From b06a99f7c76950484972e25d9dbbee8660a6a6c3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 15 May 2024 12:47:27 +0300 Subject: Post-merge spaces fix --- indra/llcommon/indra_constants.cpp | 56 +- indra/llcommon/indra_constants.h | 338 +- indra/llcommon/llstrider.h | 60 +- indra/llimage/llimage.cpp | 3410 ++--- indra/llimage/llimage.h | 408 +- indra/llinventory/llsettingssky.cpp | 146 +- indra/llmath/llcamera.h | 324 +- indra/llmath/llmatrix4a.h | 218 +- indra/llmath/llvolume.cpp | 12538 ++++++++-------- indra/llmath/llvolume.h | 1688 +-- indra/llmath/llvolumeoctree.cpp | 366 +- indra/llmath/llvolumeoctree.h | 132 +- indra/llplugin/llpluginprocessparent.cpp | 1728 +-- indra/llprimitive/llprimitive.cpp | 2892 ++-- indra/llprimitive/llprimitive.h | 894 +- indra/llprimitive/lltextureentry.cpp | 714 +- indra/llrender/llglslshader.cpp | 62 +- indra/llrender/llglslshader.h | 10 +- indra/llrender/llgltexture.cpp | 328 +- indra/llrender/llgltexture.h | 254 +- indra/llrender/llrender.cpp | 2618 ++-- indra/llrender/llrendertarget.h | 176 +- indra/llrender/llshadermgr.cpp | 1856 +-- indra/llrender/llshadermgr.h | 50 +- indra/llrender/llvertexbuffer.cpp | 634 +- indra/llrender/llvertexbuffer.h | 276 +- .../shaders/class1/deferred/avatarEyesV.glsl | 24 +- .../shaders/class1/deferred/avatarF.glsl | 34 +- .../shaders/class1/deferred/avatarV.glsl | 52 +- .../shaders/class1/deferred/bumpF.glsl | 50 +- .../shaders/class1/deferred/bumpV.glsl | 42 +- .../shaders/class1/deferred/deferredUtil.glsl | 172 +- .../shaders/class1/deferred/diffuseAlphaMaskF.glsl | 34 +- .../class1/deferred/diffuseAlphaMaskIndexedF.glsl | 34 +- .../class1/deferred/diffuseAlphaMaskNoColorF.glsl | 36 +- .../shaders/class1/deferred/diffuseF.glsl | 26 +- .../shaders/class1/deferred/diffuseIndexedF.glsl | 26 +- .../shaders/class1/deferred/diffuseV.glsl | 22 +- .../shaders/class1/deferred/impostorF.glsl | 32 +- .../shaders/class1/deferred/materialV.glsl | 54 +- .../shaders/class1/deferred/pbropaqueV.glsl | 42 +- .../shaders/class1/deferred/pbrterrainV.glsl | 18 +- .../class1/deferred/postDeferredGammaCorrect.glsl | 66 +- .../shaders/class1/deferred/treeF.glsl | 30 +- .../shaders/class1/deferred/treeV.glsl | 22 +- .../shaders/class1/interface/normaldebugF.glsl | 14 +- .../shaders/class1/interface/normaldebugV.glsl | 16 +- .../shaders/class1/interface/radianceGenF.glsl | 146 +- .../app_settings/shaders/class1/objects/bumpF.glsl | 18 +- .../app_settings/shaders/class1/objects/bumpV.glsl | 18 +- .../shaders/class2/deferred/alphaF.glsl | 70 +- .../shaders/class3/deferred/fullbrightShinyF.glsl | 28 +- .../shaders/class3/deferred/materialF.glsl | 24 +- .../shaders/class3/environment/underWaterF.glsl | 36 +- .../shaders/class3/environment/waterF.glsl | 38 +- indra/newview/gltf/asset.h | 18 +- indra/newview/gltfscenemanager.cpp | 20 +- indra/newview/gltfscenemanager.h | 4 +- indra/newview/llagentbenefits.cpp | 224 +- indra/newview/llagentbenefits.h | 74 +- indra/newview/llagentcamera.cpp | 4606 +++--- indra/newview/llappviewer.cpp | 7020 ++++----- indra/newview/lldrawable.h | 502 +- indra/newview/lldrawpool.cpp | 424 +- indra/newview/lldrawpool.h | 370 +- indra/newview/lldrawpoolalpha.cpp | 172 +- indra/newview/lldrawpoolbump.cpp | 1380 +- indra/newview/lldrawpoolterrain.cpp | 1288 +- indra/newview/lldrawpoolterrain.h | 76 +- indra/newview/lldrawpooltree.cpp | 60 +- indra/newview/lldrawpoolwlsky.cpp | 160 +- indra/newview/lldynamictexture.cpp | 286 +- indra/newview/llenvironment.cpp | 90 +- indra/newview/llface.cpp | 3362 ++--- indra/newview/llfeaturemanager.cpp | 976 +- indra/newview/llfilepicker.cpp | 2080 +-- indra/newview/llfilepicker.h | 206 +- indra/newview/llfloaterimagepreview.cpp | 1276 +- indra/newview/llfloaterimagepreview.h | 142 +- indra/newview/llfloaternamedesc.h | 50 +- indra/newview/llfloaterregioninfo.cpp | 5044 +++---- indra/newview/llfloaterregioninfo.h | 596 +- indra/newview/llgltfmaterialpreviewmgr.cpp | 38 +- indra/newview/llheroprobemanager.cpp | 78 +- indra/newview/llmanip.cpp | 864 +- indra/newview/llmaniprotate.cpp | 3292 ++--- indra/newview/llmaniptranslate.cpp | 4082 ++--- indra/newview/llmaterialeditor.cpp | 82 +- indra/newview/llpanelface.cpp | 3930 ++--- indra/newview/llpanelface.h | 808 +- indra/newview/llpanelmaininventory.cpp | 2194 +-- indra/newview/llpanelvolume.cpp | 1520 +- indra/newview/llselectmgr.cpp | 11874 +++++++-------- indra/newview/llselectmgr.h | 1514 +- indra/newview/llsettingsvo.cpp | 82 +- indra/newview/llspatialpartition.cpp | 6024 ++++---- indra/newview/llsurface.cpp | 2018 +-- indra/newview/llsurface.h | 270 +- indra/newview/llsurfacepatch.cpp | 1846 +-- indra/newview/llsurfacepatch.h | 220 +- indra/newview/lltexturectrl.cpp | 2236 +-- indra/newview/lltexturectrl.h | 500 +- indra/newview/lltooldraganddrop.cpp | 4868 +++--- indra/newview/lltoolselect.cpp | 390 +- indra/newview/llviewerassetupload.cpp | 168 +- indra/newview/llviewercamera.cpp | 1364 +- indra/newview/llviewercontrol.cpp | 476 +- indra/newview/llviewerdisplay.cpp | 2442 +-- indra/newview/llviewermenu.cpp | 12128 +++++++-------- indra/newview/llviewermenufile.cpp | 1400 +- indra/newview/llviewerobject.cpp | 10118 ++++++------- indra/newview/llviewerobject.h | 1414 +- indra/newview/llviewerregion.cpp | 4342 +++--- indra/newview/llviewerregion.h | 934 +- indra/newview/llviewershadermgr.cpp | 2694 ++-- indra/newview/llviewershadermgr.h | 356 +- indra/newview/llviewertexture.cpp | 5440 +++---- indra/newview/llviewertexture.h | 1128 +- indra/newview/llviewerwindow.cpp | 8920 +++++------ indra/newview/llviewerwindow.h | 890 +- indra/newview/llvlcomposition.cpp | 596 +- indra/newview/llvlcomposition.h | 100 +- indra/newview/llvoavatar.cpp | 14770 +++++++++---------- indra/newview/llvoavatarself.cpp | 4108 +++--- indra/newview/llvocache.cpp | 2362 +-- indra/newview/llvocache.h | 420 +- indra/newview/llvosurfacepatch.cpp | 1584 +- indra/newview/llvosurfacepatch.h | 168 +- indra/newview/llvovolume.cpp | 8366 +++++------ indra/newview/llvovolume.h | 596 +- indra/newview/llxmlrpclistener.cpp | 68 +- indra/newview/pipeline.cpp | 13108 ++++++++-------- indra/newview/pipeline.h | 1518 +- 133 files changed, 107307 insertions(+), 107307 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 39e232e480..329dfcbe37 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -1,25 +1,25 @@ -/** +/** * @file indra_constants.cpp * @brief some useful short term constants for Indra * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,39 +38,39 @@ const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); // Maintenance's group id. const LLUUID MAINTENANCE_GROUP_ID("dc7b21cd-3c89-fcaa-31c8-25f9ffd224cd"); // Grass Images -const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER +const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER -const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER +const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER -const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver -const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver -const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver -const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver -const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver +const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver +const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver +const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver +const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver +const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver -const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver +const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver const LLUUID IMG_WHITE ("5748decc-f629-461c-9a36-a35a221fe21f"); // dataserver -const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver -const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver -const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver -const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver -const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver +const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver +const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver +const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver +const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver +const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver -const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver -const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver +const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver +const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver -const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEWER -const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER -const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // VIEWER +const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEWER +const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER +const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // VIEWER -const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER -const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER -const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER -const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER +const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER +const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER +const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER +const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER -const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER +const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER const LLUUID DEFAULT_OBJECT_TEXTURE ("89556747-24cb-43ed-920b-47caed15465f"); // On dataserver const LLUUID DEFAULT_OBJECT_SPECULAR ("87e0e8f7-8729-1ea8-cfc9-8915773009db"); // On dataserver diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index a4b2efef98..d2de88ff0a 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -1,25 +1,25 @@ -/** +/** * @file indra_constants.h * @brief some useful short term constants for Indra * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,21 +37,21 @@ static const U32 REGION_WIDTH_U32 = 256; const F32 REGION_HEIGHT_METERS = 4096.f; -const F32 DEFAULT_AGENT_DEPTH = 0.45f; -const F32 DEFAULT_AGENT_WIDTH = 0.60f; -const F32 DEFAULT_AGENT_HEIGHT = 1.9f; +const F32 DEFAULT_AGENT_DEPTH = 0.45f; +const F32 DEFAULT_AGENT_WIDTH = 0.60f; +const F32 DEFAULT_AGENT_HEIGHT = 1.9f; enum ETerrainBrushType { - // the valid brush numbers cannot be reordered, because they - // are used in the binary LSL format as arguments to llModifyLand() - E_LANDBRUSH_LEVEL = 0, - E_LANDBRUSH_RAISE = 1, - E_LANDBRUSH_LOWER = 2, - E_LANDBRUSH_SMOOTH = 3, - E_LANDBRUSH_NOISE = 4, - E_LANDBRUSH_REVERT = 5, - E_LANDBRUSH_INVALID = 6 + // the valid brush numbers cannot be reordered, because they + // are used in the binary LSL format as arguments to llModifyLand() + E_LANDBRUSH_LEVEL = 0, + E_LANDBRUSH_RAISE = 1, + E_LANDBRUSH_LOWER = 2, + E_LANDBRUSH_SMOOTH = 3, + E_LANDBRUSH_NOISE = 4, + E_LANDBRUSH_REVERT = 5, + E_LANDBRUSH_INVALID = 6 }; enum EMouseClickType{ @@ -67,101 +67,101 @@ enum EMouseClickType{ // keys // Bit masks for various keyboard modifier keys. -const MASK MASK_NONE = 0x0000; -const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs -const MASK MASK_ALT = 0x0002; -const MASK MASK_SHIFT = 0x0004; +const MASK MASK_NONE = 0x0000; +const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs +const MASK MASK_ALT = 0x0002; +const MASK MASK_SHIFT = 0x0004; const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys -const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows -const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL; +const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows +const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL; // Special keys go into >128 -const KEY KEY_SPECIAL = 0x80; // special keys start here -const KEY KEY_RETURN = 0x81; -const KEY KEY_LEFT = 0x82; -const KEY KEY_RIGHT = 0x83; -const KEY KEY_UP = 0x84; -const KEY KEY_DOWN = 0x85; -const KEY KEY_ESCAPE = 0x86; +const KEY KEY_SPECIAL = 0x80; // special keys start here +const KEY KEY_RETURN = 0x81; +const KEY KEY_LEFT = 0x82; +const KEY KEY_RIGHT = 0x83; +const KEY KEY_UP = 0x84; +const KEY KEY_DOWN = 0x85; +const KEY KEY_ESCAPE = 0x86; const KEY KEY_BACKSPACE =0x87; -const KEY KEY_DELETE = 0x88; -const KEY KEY_SHIFT = 0x89; -const KEY KEY_CONTROL = 0x8A; -const KEY KEY_ALT = 0x8B; -const KEY KEY_HOME = 0x8C; -const KEY KEY_END = 0x8D; +const KEY KEY_DELETE = 0x88; +const KEY KEY_SHIFT = 0x89; +const KEY KEY_CONTROL = 0x8A; +const KEY KEY_ALT = 0x8B; +const KEY KEY_HOME = 0x8C; +const KEY KEY_END = 0x8D; const KEY KEY_PAGE_UP = 0x8E; const KEY KEY_PAGE_DOWN = 0x8F; const KEY KEY_HYPHEN = 0x90; const KEY KEY_EQUALS = 0x91; const KEY KEY_INSERT = 0x92; const KEY KEY_CAPSLOCK = 0x93; -const KEY KEY_TAB = 0x94; -const KEY KEY_ADD = 0x95; +const KEY KEY_TAB = 0x94; +const KEY KEY_ADD = 0x95; const KEY KEY_SUBTRACT =0x96; const KEY KEY_MULTIPLY =0x97; -const KEY KEY_DIVIDE = 0x98; -const KEY KEY_F1 = 0xA1; -const KEY KEY_F2 = 0xA2; -const KEY KEY_F3 = 0xA3; -const KEY KEY_F4 = 0xA4; -const KEY KEY_F5 = 0xA5; -const KEY KEY_F6 = 0xA6; -const KEY KEY_F7 = 0xA7; -const KEY KEY_F8 = 0xA8; -const KEY KEY_F9 = 0xA9; -const KEY KEY_F10 = 0xAA; -const KEY KEY_F11 = 0xAB; -const KEY KEY_F12 = 0xAC; - -const KEY KEY_PAD_UP = 0xC0; -const KEY KEY_PAD_DOWN = 0xC1; -const KEY KEY_PAD_LEFT = 0xC2; -const KEY KEY_PAD_RIGHT = 0xC3; -const KEY KEY_PAD_HOME = 0xC4; -const KEY KEY_PAD_END = 0xC5; -const KEY KEY_PAD_PGUP = 0xC6; -const KEY KEY_PAD_PGDN = 0xC7; -const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle -const KEY KEY_PAD_INS = 0xC9; -const KEY KEY_PAD_DEL = 0xCA; -const KEY KEY_PAD_RETURN = 0xCB; -const KEY KEY_PAD_ADD = 0xCC; // not used -const KEY KEY_PAD_SUBTRACT = 0xCD; // not used +const KEY KEY_DIVIDE = 0x98; +const KEY KEY_F1 = 0xA1; +const KEY KEY_F2 = 0xA2; +const KEY KEY_F3 = 0xA3; +const KEY KEY_F4 = 0xA4; +const KEY KEY_F5 = 0xA5; +const KEY KEY_F6 = 0xA6; +const KEY KEY_F7 = 0xA7; +const KEY KEY_F8 = 0xA8; +const KEY KEY_F9 = 0xA9; +const KEY KEY_F10 = 0xAA; +const KEY KEY_F11 = 0xAB; +const KEY KEY_F12 = 0xAC; + +const KEY KEY_PAD_UP = 0xC0; +const KEY KEY_PAD_DOWN = 0xC1; +const KEY KEY_PAD_LEFT = 0xC2; +const KEY KEY_PAD_RIGHT = 0xC3; +const KEY KEY_PAD_HOME = 0xC4; +const KEY KEY_PAD_END = 0xC5; +const KEY KEY_PAD_PGUP = 0xC6; +const KEY KEY_PAD_PGDN = 0xC7; +const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle +const KEY KEY_PAD_INS = 0xC9; +const KEY KEY_PAD_DEL = 0xCA; +const KEY KEY_PAD_RETURN = 0xCB; +const KEY KEY_PAD_ADD = 0xCC; // not used +const KEY KEY_PAD_SUBTRACT = 0xCD; // not used const KEY KEY_PAD_MULTIPLY = 0xCE; // not used -const KEY KEY_PAD_DIVIDE = 0xCF; // not used - -const KEY KEY_BUTTON0 = 0xD0; -const KEY KEY_BUTTON1 = 0xD1; -const KEY KEY_BUTTON2 = 0xD2; -const KEY KEY_BUTTON3 = 0xD3; -const KEY KEY_BUTTON4 = 0xD4; -const KEY KEY_BUTTON5 = 0xD5; -const KEY KEY_BUTTON6 = 0xD6; -const KEY KEY_BUTTON7 = 0xD7; -const KEY KEY_BUTTON8 = 0xD8; -const KEY KEY_BUTTON9 = 0xD9; -const KEY KEY_BUTTON10 = 0xDA; -const KEY KEY_BUTTON11 = 0xDB; -const KEY KEY_BUTTON12 = 0xDC; -const KEY KEY_BUTTON13 = 0xDD; -const KEY KEY_BUTTON14 = 0xDE; -const KEY KEY_BUTTON15 = 0xDF; - -const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only. +const KEY KEY_PAD_DIVIDE = 0xCF; // not used + +const KEY KEY_BUTTON0 = 0xD0; +const KEY KEY_BUTTON1 = 0xD1; +const KEY KEY_BUTTON2 = 0xD2; +const KEY KEY_BUTTON3 = 0xD3; +const KEY KEY_BUTTON4 = 0xD4; +const KEY KEY_BUTTON5 = 0xD5; +const KEY KEY_BUTTON6 = 0xD6; +const KEY KEY_BUTTON7 = 0xD7; +const KEY KEY_BUTTON8 = 0xD8; +const KEY KEY_BUTTON9 = 0xD9; +const KEY KEY_BUTTON10 = 0xDA; +const KEY KEY_BUTTON11 = 0xDB; +const KEY KEY_BUTTON12 = 0xDC; +const KEY KEY_BUTTON13 = 0xDD; +const KEY KEY_BUTTON14 = 0xDE; +const KEY KEY_BUTTON15 = 0xDF; + +const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only. const S32 KEY_COUNT = 256; -const F32 DEFAULT_WATER_HEIGHT = 20.0f; +const F32 DEFAULT_WATER_HEIGHT = 20.0f; // Maturity ratings for simulators -const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG -const U8 SIM_ACCESS_PG = 13; -const U8 SIM_ACCESS_MATURE = 21; -const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only -const U8 SIM_ACCESS_DOWN = 254; -const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; +const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG +const U8 SIM_ACCESS_PG = 13; +const U8 SIM_ACCESS_MATURE = 21; +const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only +const U8 SIM_ACCESS_DOWN = 254; +const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; // attachment constants const U8 ATTACHMENT_ADD = 0x80; @@ -260,84 +260,84 @@ const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13; const S32 CHAT_CHANNEL_DEBUG = S32_MAX; // agent constants -const U32 CONTROL_AT_POS_INDEX = 0; -const U32 CONTROL_AT_NEG_INDEX = 1; -const U32 CONTROL_LEFT_POS_INDEX = 2; -const U32 CONTROL_LEFT_NEG_INDEX = 3; -const U32 CONTROL_UP_POS_INDEX = 4; -const U32 CONTROL_UP_NEG_INDEX = 5; -const U32 CONTROL_PITCH_POS_INDEX = 6; -const U32 CONTROL_PITCH_NEG_INDEX = 7; -const U32 CONTROL_YAW_POS_INDEX = 8; -const U32 CONTROL_YAW_NEG_INDEX = 9; -const U32 CONTROL_FAST_AT_INDEX = 10; -const U32 CONTROL_FAST_LEFT_INDEX = 11; -const U32 CONTROL_FAST_UP_INDEX = 12; -const U32 CONTROL_FLY_INDEX = 13; -const U32 CONTROL_STOP_INDEX = 14; -const U32 CONTROL_FINISH_ANIM_INDEX = 15; -const U32 CONTROL_STAND_UP_INDEX = 16; -const U32 CONTROL_SIT_ON_GROUND_INDEX = 17; -const U32 CONTROL_MOUSELOOK_INDEX = 18; -const U32 CONTROL_NUDGE_AT_POS_INDEX = 19; -const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20; -const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21; -const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22; -const U32 CONTROL_NUDGE_UP_POS_INDEX = 23; -const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24; -const U32 CONTROL_TURN_LEFT_INDEX = 25; -const U32 CONTROL_TURN_RIGHT_INDEX = 26; -const U32 CONTROL_AWAY_INDEX = 27; -const U32 CONTROL_LBUTTON_DOWN_INDEX = 28; -const U32 CONTROL_LBUTTON_UP_INDEX = 29; -const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30; -const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31; -const U32 TOTAL_CONTROLS = 32; - -const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001 -const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002 -const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004 -const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008 -const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010 -const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020 -const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040 -const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080 -const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100 -const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200 - -const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400 -const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800 -const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000 - -const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000 -const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000 -const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000 -const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000 -const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000 -const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000 - -const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000 -const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000 -const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000 -const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000 -const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000 -const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000 -const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000 -const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000 - -const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000 - -const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000 -const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000 -const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000 -const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000 - -// move these up so that we can hide them in "State" for object updates +const U32 CONTROL_AT_POS_INDEX = 0; +const U32 CONTROL_AT_NEG_INDEX = 1; +const U32 CONTROL_LEFT_POS_INDEX = 2; +const U32 CONTROL_LEFT_NEG_INDEX = 3; +const U32 CONTROL_UP_POS_INDEX = 4; +const U32 CONTROL_UP_NEG_INDEX = 5; +const U32 CONTROL_PITCH_POS_INDEX = 6; +const U32 CONTROL_PITCH_NEG_INDEX = 7; +const U32 CONTROL_YAW_POS_INDEX = 8; +const U32 CONTROL_YAW_NEG_INDEX = 9; +const U32 CONTROL_FAST_AT_INDEX = 10; +const U32 CONTROL_FAST_LEFT_INDEX = 11; +const U32 CONTROL_FAST_UP_INDEX = 12; +const U32 CONTROL_FLY_INDEX = 13; +const U32 CONTROL_STOP_INDEX = 14; +const U32 CONTROL_FINISH_ANIM_INDEX = 15; +const U32 CONTROL_STAND_UP_INDEX = 16; +const U32 CONTROL_SIT_ON_GROUND_INDEX = 17; +const U32 CONTROL_MOUSELOOK_INDEX = 18; +const U32 CONTROL_NUDGE_AT_POS_INDEX = 19; +const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20; +const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21; +const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22; +const U32 CONTROL_NUDGE_UP_POS_INDEX = 23; +const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24; +const U32 CONTROL_TURN_LEFT_INDEX = 25; +const U32 CONTROL_TURN_RIGHT_INDEX = 26; +const U32 CONTROL_AWAY_INDEX = 27; +const U32 CONTROL_LBUTTON_DOWN_INDEX = 28; +const U32 CONTROL_LBUTTON_UP_INDEX = 29; +const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30; +const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31; +const U32 TOTAL_CONTROLS = 32; + +const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001 +const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002 +const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004 +const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008 +const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010 +const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020 +const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040 +const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080 +const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100 +const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200 + +const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400 +const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800 +const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000 + +const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000 +const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000 +const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000 +const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000 +const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000 +const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000 + +const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000 +const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000 +const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000 +const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000 +const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000 +const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000 +const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000 +const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000 + +const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000 + +const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000 +const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000 +const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000 +const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000 + +// move these up so that we can hide them in "State" for object updates // (for now) -const U32 AGENT_ATTACH_OFFSET = 4; -const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET; +const U32 AGENT_ATTACH_OFFSET = 4; +const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET; -// RN: this method swaps the upper and lower nibbles to maintain backward +// RN: this method swaps the upper and lower nibbles to maintain backward // compatibility with old objects that only used the upper nibble #define ATTACHMENT_ID_FROM_STATE(state) ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4))) diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index e7522484e6..06cf8d3480 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -1,24 +1,24 @@ -/** +/** * @file llstrider.h * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,38 +30,38 @@ template class LLStrider { - union - { - Object* mObjectp; - U8* mBytep; - }; - U32 mSkip; + union + { + Object* mObjectp; + U8* mBytep; + }; + U32 mSkip; public: - LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); } + LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); } LLStrider(Object* first) { mObjectp = first; mSkip = sizeof(Object); } - ~LLStrider() { } + ~LLStrider() { } - const LLStrider& operator = (Object *first) { mObjectp = first; return *this;} - void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} + const LLStrider& operator = (Object *first) { mObjectp = first; return *this;} + void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} - LLStrider operator+(const S32& index) - { - LLStrider ret; - ret.mBytep = mBytep + mSkip*index; - ret.mSkip = mSkip; + LLStrider operator+(const S32& index) + { + LLStrider ret; + ret.mBytep = mBytep + mSkip*index; + ret.mSkip = mSkip; - return ret; - } + return ret; + } - void skip(const U32 index) { mBytep += mSkip*index;} - U32 getSkip() const { return mSkip; } - Object* get() { return mObjectp; } - Object* operator->() { return mObjectp; } - Object& operator *() { return *mObjectp; } - Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } - Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } + void skip(const U32 index) { mBytep += mSkip*index;} + U32 getSkip() const { return mSkip; } + Object* get() { return mObjectp; } + Object* operator->() { return mObjectp; } + Object& operator *() { return *mObjectp; } + Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } + Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } - Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } + Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } }; #endif // LL_LLSTRIDER_H diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index ed8f36286f..864315d0ff 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llimage.cpp * @brief Base class for images. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,40 +54,40 @@ #define _UNROL_GEN_TPL_comma_1 BOOST_PP_COMMA() //.................................................................................. #define _UNROL_GEN_TPL_ARGS_macro(z,n,seq) \ - BOOST_PP_CAT(_UNROL_GEN_TPL_arg_, BOOST_PP_MOD(n, 2))(BOOST_PP_SEQ_ELEM(n, seq)) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) + BOOST_PP_CAT(_UNROL_GEN_TPL_arg_, BOOST_PP_MOD(n, 2))(BOOST_PP_SEQ_ELEM(n, seq)) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) #define _UNROL_GEN_TPL_ARGS(seq) \ - BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_ARGS_macro, seq) + BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_ARGS_macro, seq) //.................................................................................. #define _UNROL_GEN_TPL_TYPE_ARGS_macro(z,n,seq) \ - BOOST_PP_SEQ_ELEM(n, seq) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) + BOOST_PP_SEQ_ELEM(n, seq) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) #define _UNROL_GEN_TPL_TYPE_ARGS(seq) \ - BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_TYPE_ARGS_macro, seq) + BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_TYPE_ARGS_macro, seq) //.................................................................................. #define _UNROLL_GEN_TPL_foreach_ee(z, n, seq) \ - executor(_UNROL_GEN_TPL_ARGS(seq)); + executor(_UNROL_GEN_TPL_ARGS(seq)); #define _UNROLL_GEN_TPL(name, args_seq, operation, spec) \ - template<> struct name { \ - private: \ - template inline void executor(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ - BOOST_PP_SEQ_ENUM(operation) ; \ - } \ - public: \ - inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ - BOOST_PP_REPEAT(spec, _UNROLL_GEN_TPL_foreach_ee, args_seq) \ - } \ + template<> struct name { \ + private: \ + template inline void executor(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ + BOOST_PP_SEQ_ENUM(operation) ; \ + } \ + public: \ + inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ + BOOST_PP_REPEAT(spec, _UNROLL_GEN_TPL_foreach_ee, args_seq) \ + } \ }; //.................................................................................. #define _UNROLL_GEN_TPL_foreach_seq_macro(r, data, elem) \ - _UNROLL_GEN_TPL(BOOST_PP_SEQ_ELEM(0, data), BOOST_PP_SEQ_ELEM(1, data), BOOST_PP_SEQ_ELEM(2, data), elem) + _UNROLL_GEN_TPL(BOOST_PP_SEQ_ELEM(0, data), BOOST_PP_SEQ_ELEM(1, data), BOOST_PP_SEQ_ELEM(2, data), elem) #define UNROLL_GEN_TPL(name, args_seq, operation, spec_seq) \ - /*general specialization - should not be implemented!*/ \ - template struct name { inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { /*static_assert(!"Should not be instantiated.");*/ } }; \ - BOOST_PP_SEQ_FOR_EACH(_UNROLL_GEN_TPL_foreach_seq_macro, (name)(args_seq)(operation), spec_seq) + /*general specialization - should not be implemented!*/ \ + template struct name { inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { /*static_assert(!"Should not be instantiated.");*/ } }; \ + BOOST_PP_SEQ_FOR_EACH(_UNROLL_GEN_TPL_foreach_seq_macro, (name)(args_seq)(operation), spec_seq) //.................................................................................. //.................................................................................. @@ -123,460 +123,460 @@ UNROLL_GEN_TPL(uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff, (U8 *&)(dptr)(S3 template -struct scale_info +struct scale_info { public: - std::vector xpoints; - std::vector ystrides; - std::vector xapoints, yapoints; - S32 xup_yup; + std::vector xpoints; + std::vector ystrides; + std::vector xapoints, yapoints; + S32 xup_yup; public: - //unrolling loop types declaration - typedef uroll_zeroze_cx_comp uroll_zeroze_cx_comp_t; - typedef uroll_comp_rshftasgn_constval uroll_comp_rshftasgn_constval_t; - typedef uroll_comp_asgn_cx_rshft_cval_all_mul_val uroll_comp_asgn_cx_rshft_cval_all_mul_val_t; - typedef uroll_comp_plusasgn_cx_rshft_cval_all_mul_val uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t; - typedef uroll_inp_plusasgn_pix_mul_val uroll_inp_plusasgn_pix_mul_val_t; - typedef uroll_inp_asgn_pix_mul_val uroll_inp_asgn_pix_mul_val_t; - typedef uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t; - typedef uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t; - typedef uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t; - typedef uroll_uref_dptr_inc_asgn_comp_and_ff uroll_uref_dptr_inc_asgn_comp_and_ff_t; - typedef uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t; - typedef uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t; + //unrolling loop types declaration + typedef uroll_zeroze_cx_comp uroll_zeroze_cx_comp_t; + typedef uroll_comp_rshftasgn_constval uroll_comp_rshftasgn_constval_t; + typedef uroll_comp_asgn_cx_rshft_cval_all_mul_val uroll_comp_asgn_cx_rshft_cval_all_mul_val_t; + typedef uroll_comp_plusasgn_cx_rshft_cval_all_mul_val uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t; + typedef uroll_inp_plusasgn_pix_mul_val uroll_inp_plusasgn_pix_mul_val_t; + typedef uroll_inp_asgn_pix_mul_val uroll_inp_asgn_pix_mul_val_t; + typedef uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t; + typedef uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t; + typedef uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t; + typedef uroll_uref_dptr_inc_asgn_comp_and_ff uroll_uref_dptr_inc_asgn_comp_and_ff_t; + typedef uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t; + typedef uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t; public: - scale_info(const U8 *src, U32 srcW, U32 srcH, U32 dstW, U32 dstH, U32 srcStride) - : xup_yup((dstW >= srcW) + ((dstH >= srcH) << 1)) - { - calc_x_points(srcW, dstW); - calc_y_strides(src, srcStride, srcH, dstH); - calc_aa_points(srcW, dstW, xup_yup&1, xapoints); - calc_aa_points(srcH, dstH, xup_yup&2, yapoints); - } + scale_info(const U8 *src, U32 srcW, U32 srcH, U32 dstW, U32 dstH, U32 srcStride) + : xup_yup((dstW >= srcW) + ((dstH >= srcH) << 1)) + { + calc_x_points(srcW, dstW); + calc_y_strides(src, srcStride, srcH, dstH); + calc_aa_points(srcW, dstW, xup_yup&1, xapoints); + calc_aa_points(srcH, dstH, xup_yup&2, yapoints); + } private: - //........................................................................................... - void calc_x_points(U32 srcW, U32 dstW) - { - xpoints.resize(dstW+1); - - S32 val = dstW >= srcW ? 0x8000 * srcW / dstW - 0x8000 : 0; - S32 inc = (srcW << 16) / dstW; - - for(U32 i = 0, j = 0; i < dstW; ++i, ++j, val += inc) - { - xpoints[j] = llmax(0, val >> 16); - } - } - //........................................................................................... - void calc_y_strides(const U8 *src, U32 srcStride, U32 srcH, U32 dstH) - { - ystrides.resize(dstH+1); - - S32 val = dstH >= srcH ? 0x8000 * srcH / dstH - 0x8000 : 0; - S32 inc = (srcH << 16) / dstH; - - for(U32 i = 0, j = 0; i < dstH; ++i, ++j, val += inc) - { - ystrides[j] = src + llmax(0, val >> 16) * srcStride; - } - } - //........................................................................................... - void calc_aa_points(U32 srcSz, U32 dstSz, bool scale_up, std::vector &vp) - { - vp.resize(dstSz); - - if(scale_up) - { - S32 val = 0x8000 * srcSz / dstSz - 0x8000; - S32 inc = (srcSz << 16) / dstSz; - U32 pos; - - for(U32 i = 0, j = 0; i < dstSz; ++i, ++j, val += inc) - { - pos = val >> 16; - - if (pos >= (srcSz - 1)) - vp[j] = 0; - else - vp[j] = (val >> 8) - ((val >> 8) & 0xffffff00); - } - } - else - { - S32 inc = (srcSz << 16) / dstSz; - S32 Cp = ((dstSz << 14) / srcSz) + 1; - S32 ap; - - for(U32 i = 0, j = 0, val = 0; i < dstSz; ++i, ++j, val += inc) - { - ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; - vp[j] = ap | (Cp << 16); - } - } - } + //........................................................................................... + void calc_x_points(U32 srcW, U32 dstW) + { + xpoints.resize(dstW+1); + + S32 val = dstW >= srcW ? 0x8000 * srcW / dstW - 0x8000 : 0; + S32 inc = (srcW << 16) / dstW; + + for(U32 i = 0, j = 0; i < dstW; ++i, ++j, val += inc) + { + xpoints[j] = llmax(0, val >> 16); + } + } + //........................................................................................... + void calc_y_strides(const U8 *src, U32 srcStride, U32 srcH, U32 dstH) + { + ystrides.resize(dstH+1); + + S32 val = dstH >= srcH ? 0x8000 * srcH / dstH - 0x8000 : 0; + S32 inc = (srcH << 16) / dstH; + + for(U32 i = 0, j = 0; i < dstH; ++i, ++j, val += inc) + { + ystrides[j] = src + llmax(0, val >> 16) * srcStride; + } + } + //........................................................................................... + void calc_aa_points(U32 srcSz, U32 dstSz, bool scale_up, std::vector &vp) + { + vp.resize(dstSz); + + if(scale_up) + { + S32 val = 0x8000 * srcSz / dstSz - 0x8000; + S32 inc = (srcSz << 16) / dstSz; + U32 pos; + + for(U32 i = 0, j = 0; i < dstSz; ++i, ++j, val += inc) + { + pos = val >> 16; + + if (pos >= (srcSz - 1)) + vp[j] = 0; + else + vp[j] = (val >> 8) - ((val >> 8) & 0xffffff00); + } + } + else + { + S32 inc = (srcSz << 16) / dstSz; + S32 Cp = ((dstSz << 14) / srcSz) + 1; + S32 ap; + + for(U32 i = 0, j = 0, val = 0; i < dstSz; ++i, ++j, val += inc) + { + ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; + vp[j] = ap | (Cp << 16); + } + } + } }; template inline void bilinear_scale( - const U8 *src, U32 srcW, U32 srcH, U32 srcStride - , U8 *dst, U32 dstW, U32 dstH, U32 dstStride - ) -{ - typedef scale_info scale_info_t; - - scale_info_t info(src, srcW, srcH, dstW, dstH, srcStride); - - const U8 *sptr; - U8 *dptr; - U32 x, y; - const U8 *pix; - - S32 cx[ch], comp[ch]; - - - if(3 == info.xup_yup) - { //scale x/y - up - for(y = 0; y < dstH; ++y) - { - dptr = dst + (y * dstStride); - sptr = info.ystrides[y]; - - if(0 < info.yapoints[y]) - { - for(x = 0; x < dstW; ++x) - { - //for(c = 0; c < ch; ++c) cx[c] = comp[c] = 0; - typename scale_info_t::uroll_zeroze_cx_comp_t()(cx, comp); - - if(0 < info.xapoints[x]) - { - pix = info.ystrides[y] + info.xpoints[x] * ch; - - //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.xapoints[x]); - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); - - pix += ch; - - //for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x]; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, info.xapoints[x]); - - pix += srcStride; - - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x]; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, info.xapoints[x]); - - pix -= ch; - - //for(c = 0; c < ch; ++c) { - // cx[c] += pix[c] * (256 - info.xapoints[x]); - // comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16; - // *dptr++ = comp[c]&0xff; - //} - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, 256 - info.xapoints[x]); - typename scale_info_t::uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t()(comp, cx, info.yapoints[y]); - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); - } - else - { - pix = info.ystrides[y] + info.xpoints[x] * ch; - - //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.yapoints[y]); - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256-info.yapoints[y]); - - pix += srcStride; - - //for(c = 0; c < ch; ++c) { - // comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8; - // *dptr++ = comp[c]&0xff; - //} - typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.yapoints[y]); - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); - } - } - } - else - { - for(x = 0; x < dstW; ++x) - { - if(0 < info.xapoints[x]) - { - pix = info.ystrides[y] + info.xpoints[x] * ch; - - //for(c = 0; c < ch; ++c) { - // comp[c] = pix[c] * (256 - info.xapoints[x]); - // comp[c] = (comp[c] + pix[c] * info.xapoints[x]) >> 8; - // *dptr++ = comp[c]&0xff; - //} - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); - typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.xapoints[x]); - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); - } - else - { - //for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff; - typename scale_info_t::uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t()(dptr, sptr, info.xpoints[x]*ch); - } - } - } - } - } - else if(info.xup_yup == 1) - { //scaling down vertically - S32 Cy, j; - S32 yap; - - for(y = 0; y < dstH; y++) - { - Cy = info.yapoints[y] >> 16; - yap = info.yapoints[y] & 0xffff; - - dptr = dst + (y * dstStride); - - for(x = 0; x < dstW; x++) - { - pix = info.ystrides[y] + info.xpoints[x] * ch; - - //for(c = 0; c < ch; ++c) comp[c] = pix[c] * yap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, yap); - - pix += srcStride; - - for(j = (1 << 14) - yap; j > Cy; j -= Cy, pix += srcStride) - { - //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cy; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cy); - } - - if(j > 0) - { - //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); - } - - if(info.xapoints[x] > 0) - { - pix = info.ystrides[y] + info.xpoints[x]*ch + ch; - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * yap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, yap); - - pix += srcStride; - for(j = (1 << 14) - yap; j > Cy; j -= Cy) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cy; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cy); - pix += srcStride; - } - - if(j > 0) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); - } - - //for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12; - typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.xapoints[x], cx); - } - else - { - //for(c = 0; c < ch; ++c) comp[c] >>= 4; - typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); - } - - //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); - } - } - } - else if(info.xup_yup == 2) - { // scaling down horizontally - S32 Cx, j; - S32 xap; - - for(y = 0; y < dstH; y++) - { - dptr = dst + (y * dstStride); - - for(x = 0; x < dstW; x++) - { - Cx = info.xapoints[x] >> 16; - xap = info.xapoints[x] & 0xffff; - - pix = info.ystrides[y] + info.xpoints[x] * ch; - - //for(c = 0; c < ch; ++c) comp[c] = pix[c] * xap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, xap); - - pix+=ch; - for(j = (1 << 14) - xap; j > Cx; j -= Cx) - { - //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cx; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cx); - pix+=ch; - } - - if(j > 0) - { - //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); - } - - if(info.yapoints[y] > 0) - { - pix = info.ystrides[y] + info.xpoints[x]*ch + srcStride; - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); - - pix+=ch; - for(j = (1 << 14) - xap; j > Cx; j -= Cx) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); - pix+=ch; - } - - if(j > 0) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); - } - - //for(c = 0; c < ch; ++c) comp[c] = ((comp[c] * (256 - info.yapoints[y])) + ((cx[c] * info.yapoints[y]))) >> 12; - typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.yapoints[y], cx); - } - else - { - //for(c = 0; c < ch; ++c) comp[c] >>= 4; - typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); - } - - //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); - } - } - } - else - { //scale x/y - down - S32 Cx, Cy, i, j; - S32 xap, yap; - - for(y = 0; y < dstH; y++) - { - Cy = info.yapoints[y] >> 16; - yap = info.yapoints[y] & 0xffff; - - dptr = dst + (y * dstStride); - for(x = 0; x < dstW; x++) - { - Cx = info.xapoints[x] >> 16; - xap = info.xapoints[x] & 0xffff; - - sptr = info.ystrides[y] + info.xpoints[x] * ch; - pix = sptr; - sptr += srcStride; - - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); - - pix+=ch; - for(i = (1 << 14) - xap; i > Cx; i -= Cx) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); - pix+=ch; - } - - if(i > 0) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); - } - - //for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap; - typename scale_info_t::uroll_comp_asgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, yap); - - for(j = (1 << 14) - yap; j > Cy; j -= Cy) - { - pix = sptr; - sptr += srcStride; - - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); - - pix+=ch; - for(i = (1 << 14) - xap; i > Cx; i -= Cx) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); - pix+=ch; - } - - if(i > 0) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); - } - - //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy; - typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, Cy); - } - - if(j > 0) - { - pix = sptr; - sptr += srcStride; - - //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; - typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); - - pix+=ch; - for(i = (1 << 14) - xap; i > Cx; i -= Cx) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); - pix+=ch; - } - - if(i > 0) - { - //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; - typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); - } - - //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * j; - typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, j); - } - - //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>23)&0xff; - typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 23); - } - } - } //else + const U8 *src, U32 srcW, U32 srcH, U32 srcStride + , U8 *dst, U32 dstW, U32 dstH, U32 dstStride + ) +{ + typedef scale_info scale_info_t; + + scale_info_t info(src, srcW, srcH, dstW, dstH, srcStride); + + const U8 *sptr; + U8 *dptr; + U32 x, y; + const U8 *pix; + + S32 cx[ch], comp[ch]; + + + if(3 == info.xup_yup) + { //scale x/y - up + for(y = 0; y < dstH; ++y) + { + dptr = dst + (y * dstStride); + sptr = info.ystrides[y]; + + if(0 < info.yapoints[y]) + { + for(x = 0; x < dstW; ++x) + { + //for(c = 0; c < ch; ++c) cx[c] = comp[c] = 0; + typename scale_info_t::uroll_zeroze_cx_comp_t()(cx, comp); + + if(0 < info.xapoints[x]) + { + pix = info.ystrides[y] + info.xpoints[x] * ch; + + //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.xapoints[x]); + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); + + pix += ch; + + //for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x]; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, info.xapoints[x]); + + pix += srcStride; + + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x]; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, info.xapoints[x]); + + pix -= ch; + + //for(c = 0; c < ch; ++c) { + // cx[c] += pix[c] * (256 - info.xapoints[x]); + // comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16; + // *dptr++ = comp[c]&0xff; + //} + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, 256 - info.xapoints[x]); + typename scale_info_t::uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t()(comp, cx, info.yapoints[y]); + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); + } + else + { + pix = info.ystrides[y] + info.xpoints[x] * ch; + + //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.yapoints[y]); + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256-info.yapoints[y]); + + pix += srcStride; + + //for(c = 0; c < ch; ++c) { + // comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8; + // *dptr++ = comp[c]&0xff; + //} + typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.yapoints[y]); + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); + } + } + } + else + { + for(x = 0; x < dstW; ++x) + { + if(0 < info.xapoints[x]) + { + pix = info.ystrides[y] + info.xpoints[x] * ch; + + //for(c = 0; c < ch; ++c) { + // comp[c] = pix[c] * (256 - info.xapoints[x]); + // comp[c] = (comp[c] + pix[c] * info.xapoints[x]) >> 8; + // *dptr++ = comp[c]&0xff; + //} + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); + typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.xapoints[x]); + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); + } + else + { + //for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff; + typename scale_info_t::uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t()(dptr, sptr, info.xpoints[x]*ch); + } + } + } + } + } + else if(info.xup_yup == 1) + { //scaling down vertically + S32 Cy, j; + S32 yap; + + for(y = 0; y < dstH; y++) + { + Cy = info.yapoints[y] >> 16; + yap = info.yapoints[y] & 0xffff; + + dptr = dst + (y * dstStride); + + for(x = 0; x < dstW; x++) + { + pix = info.ystrides[y] + info.xpoints[x] * ch; + + //for(c = 0; c < ch; ++c) comp[c] = pix[c] * yap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, yap); + + pix += srcStride; + + for(j = (1 << 14) - yap; j > Cy; j -= Cy, pix += srcStride) + { + //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cy; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cy); + } + + if(j > 0) + { + //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); + } + + if(info.xapoints[x] > 0) + { + pix = info.ystrides[y] + info.xpoints[x]*ch + ch; + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * yap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, yap); + + pix += srcStride; + for(j = (1 << 14) - yap; j > Cy; j -= Cy) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cy; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cy); + pix += srcStride; + } + + if(j > 0) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); + } + + //for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12; + typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.xapoints[x], cx); + } + else + { + //for(c = 0; c < ch; ++c) comp[c] >>= 4; + typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); + } + + //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); + } + } + } + else if(info.xup_yup == 2) + { // scaling down horizontally + S32 Cx, j; + S32 xap; + + for(y = 0; y < dstH; y++) + { + dptr = dst + (y * dstStride); + + for(x = 0; x < dstW; x++) + { + Cx = info.xapoints[x] >> 16; + xap = info.xapoints[x] & 0xffff; + + pix = info.ystrides[y] + info.xpoints[x] * ch; + + //for(c = 0; c < ch; ++c) comp[c] = pix[c] * xap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, xap); + + pix+=ch; + for(j = (1 << 14) - xap; j > Cx; j -= Cx) + { + //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cx; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cx); + pix+=ch; + } + + if(j > 0) + { + //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); + } + + if(info.yapoints[y] > 0) + { + pix = info.ystrides[y] + info.xpoints[x]*ch + srcStride; + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + + pix+=ch; + for(j = (1 << 14) - xap; j > Cx; j -= Cx) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); + pix+=ch; + } + + if(j > 0) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); + } + + //for(c = 0; c < ch; ++c) comp[c] = ((comp[c] * (256 - info.yapoints[y])) + ((cx[c] * info.yapoints[y]))) >> 12; + typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.yapoints[y], cx); + } + else + { + //for(c = 0; c < ch; ++c) comp[c] >>= 4; + typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); + } + + //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); + } + } + } + else + { //scale x/y - down + S32 Cx, Cy, i, j; + S32 xap, yap; + + for(y = 0; y < dstH; y++) + { + Cy = info.yapoints[y] >> 16; + yap = info.yapoints[y] & 0xffff; + + dptr = dst + (y * dstStride); + for(x = 0; x < dstW; x++) + { + Cx = info.xapoints[x] >> 16; + xap = info.xapoints[x] & 0xffff; + + sptr = info.ystrides[y] + info.xpoints[x] * ch; + pix = sptr; + sptr += srcStride; + + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + + pix+=ch; + for(i = (1 << 14) - xap; i > Cx; i -= Cx) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); + pix+=ch; + } + + if(i > 0) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); + } + + //for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap; + typename scale_info_t::uroll_comp_asgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, yap); + + for(j = (1 << 14) - yap; j > Cy; j -= Cy) + { + pix = sptr; + sptr += srcStride; + + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + + pix+=ch; + for(i = (1 << 14) - xap; i > Cx; i -= Cx) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); + pix+=ch; + } + + if(i > 0) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); + } + + //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy; + typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, Cy); + } + + if(j > 0) + { + pix = sptr; + sptr += srcStride; + + //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; + typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + + pix+=ch; + for(i = (1 << 14) - xap; i > Cx; i -= Cx) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); + pix+=ch; + } + + if(i > 0) + { + //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; + typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); + } + + //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * j; + typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, j); + } + + //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>23)&0xff; + typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 23); + } + } + } //else } //wrapper static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 srcStride, U8 *dst, U32 dstW, U32 dstH, U32 dstCh, U32 dstStride) { - llassert(srcCh == dstCh); + llassert(srcCh == dstCh); - switch(srcCh) - { - case 1: - bilinear_scale<1>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); - break; - case 3: - bilinear_scale<3>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); - break; - case 4: - bilinear_scale<4>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); - break; - default: - llassert(!"Implement if need"); - break; - } + switch(srcCh) + { + case 1: + bilinear_scale<1>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); + break; + case 3: + bilinear_scale<3>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); + break; + case 4: + bilinear_scale<4>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); + break; + default: + llassert(!"Implement if need"); + break; + } } @@ -593,30 +593,30 @@ S32 LLImage::sMinimalReverseByteRangePercent = 75; //static void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) { - sUseNewByteRange = use_new_byte_range; + sUseNewByteRange = use_new_byte_range; sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent; - sMutex = new LLMutex(); + sMutex = new LLMutex(); } //static void LLImage::cleanupClass() { - delete sMutex; - sMutex = NULL; + delete sMutex; + sMutex = NULL; } //static const std::string& LLImage::getLastError() { - static const std::string noerr("No Error"); - return sLastErrorMessage.empty() ? noerr : sLastErrorMessage; + static const std::string noerr("No Error"); + return sLastErrorMessage.empty() ? noerr : sLastErrorMessage; } //static void LLImage::setLastError(const std::string& message) { - LLMutexLock m(sMutex); - sLastErrorMessage = message; + LLMutexLock m(sMutex); + sLastErrorMessage = message; } //--------------------------------------------------------------------------- @@ -624,175 +624,175 @@ void LLImage::setLastError(const std::string& message) //--------------------------------------------------------------------------- LLImageBase::LLImageBase() -: mData(NULL), - mDataSize(0), - mWidth(0), - mHeight(0), - mComponents(0), - mBadBufferAllocation(false), - mAllowOverSize(false) +: mData(NULL), + mDataSize(0), + mWidth(0), + mHeight(0), + mComponents(0), + mBadBufferAllocation(false), + mAllowOverSize(false) {} // virtual LLImageBase::~LLImageBase() { - deleteData(); // virtual + deleteData(); // virtual } // virtual void LLImageBase::dump() { - LL_INFOS() << "LLImageBase mComponents " << mComponents - << " mData " << mData - << " mDataSize " << mDataSize - << " mWidth " << mWidth - << " mHeight " << mHeight - << LL_ENDL; + LL_INFOS() << "LLImageBase mComponents " << mComponents + << " mData " << mData + << " mDataSize " << mDataSize + << " mWidth " << mWidth + << " mHeight " << mHeight + << LL_ENDL; } // virtual void LLImageBase::sanityCheck() { - if (mWidth > MAX_IMAGE_SIZE - || mHeight > MAX_IMAGE_SIZE - || mDataSize > (S32)MAX_IMAGE_DATA_SIZE - || mComponents > (S8)MAX_IMAGE_COMPONENTS - ) - { - LL_ERRS() << "Failed LLImageBase::sanityCheck " - << "width " << mWidth - << "height " << mHeight - << "datasize " << mDataSize - << "components " << mComponents - << "data " << mData - << LL_ENDL; - } + if (mWidth > MAX_IMAGE_SIZE + || mHeight > MAX_IMAGE_SIZE + || mDataSize > (S32)MAX_IMAGE_DATA_SIZE + || mComponents > (S8)MAX_IMAGE_COMPONENTS + ) + { + LL_ERRS() << "Failed LLImageBase::sanityCheck " + << "width " << mWidth + << "height " << mHeight + << "datasize " << mDataSize + << "components " << mComponents + << "data " << mData + << LL_ENDL; + } } // virtual void LLImageBase::deleteData() { - ll_aligned_free_16(mData); - mDataSize = 0; - mData = NULL; + ll_aligned_free_16(mData); + mDataSize = 0; + mData = NULL; } // virtual U8* LLImageBase::allocateData(S32 size) { - //make this function thread-safe. - static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16; //256 MB - mBadBufferAllocation = false; - - if (size < 0) - { - size = mWidth * mHeight * mComponents; - if (size <= 0) - { - LL_WARNS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL; - mBadBufferAllocation = true; - } - } - - if (!mBadBufferAllocation && (size < 1 || size > MAX_BUFFER_SIZE)) - { - LL_INFOS() << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << LL_ENDL ; - if(mAllowOverSize) - { - LL_INFOS() << "Oversize: " << size << LL_ENDL ; - } - else - { - LL_WARNS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL; - mBadBufferAllocation = true; - } - } - - if (!mBadBufferAllocation && (!mData || size != mDataSize)) - { - deleteData(); // virtual - mData = (U8*)ll_aligned_malloc_16(size); - if (!mData) - { - LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL; - mBadBufferAllocation = true; - } - } - - if (mBadBufferAllocation) - { - size = 0; - mWidth = mHeight = 0; - if (mData) - { - deleteData(); // virtual - mData = NULL; - } - } - mDataSize = size; - - return mData; + //make this function thread-safe. + static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16; //256 MB + mBadBufferAllocation = false; + + if (size < 0) + { + size = mWidth * mHeight * mComponents; + if (size <= 0) + { + LL_WARNS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL; + mBadBufferAllocation = true; + } + } + + if (!mBadBufferAllocation && (size < 1 || size > MAX_BUFFER_SIZE)) + { + LL_INFOS() << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << LL_ENDL ; + if(mAllowOverSize) + { + LL_INFOS() << "Oversize: " << size << LL_ENDL ; + } + else + { + LL_WARNS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL; + mBadBufferAllocation = true; + } + } + + if (!mBadBufferAllocation && (!mData || size != mDataSize)) + { + deleteData(); // virtual + mData = (U8*)ll_aligned_malloc_16(size); + if (!mData) + { + LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL; + mBadBufferAllocation = true; + } + } + + if (mBadBufferAllocation) + { + size = 0; + mWidth = mHeight = 0; + if (mData) + { + deleteData(); // virtual + mData = NULL; + } + } + mDataSize = size; + + return mData; } // virtual U8* LLImageBase::reallocateData(S32 size) { - U8 *new_datap = (U8*)ll_aligned_malloc_16(size); - if (!new_datap) - { - LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL; - return 0; - } - if (mData) - { - S32 bytes = llmin(mDataSize, size); - memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */ - ll_aligned_free_16(mData) ; - } - mData = new_datap; - mDataSize = size; - mBadBufferAllocation = false; - return mData; -} - -const U8* LLImageBase::getData() const -{ - if(mBadBufferAllocation) - { - LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ; - return NULL; - } - - return mData; + U8 *new_datap = (U8*)ll_aligned_malloc_16(size); + if (!new_datap) + { + LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL; + return 0; + } + if (mData) + { + S32 bytes = llmin(mDataSize, size); + memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */ + ll_aligned_free_16(mData) ; + } + mData = new_datap; + mDataSize = size; + mBadBufferAllocation = false; + return mData; +} + +const U8* LLImageBase::getData() const +{ + if(mBadBufferAllocation) + { + LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ; + return NULL; + } + + return mData; } // read only -U8* LLImageBase::getData() -{ - if(mBadBufferAllocation) - { - LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL; - return NULL; - } +U8* LLImageBase::getData() +{ + if(mBadBufferAllocation) + { + LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL; + return NULL; + } - return mData; + return mData; } bool LLImageBase::isBufferInvalid() const { - return mBadBufferAllocation || mData == NULL ; + return mBadBufferAllocation || mData == NULL ; } void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents) { - mWidth = width; - mHeight = height; - mComponents = ncomponents; + mWidth = width; + mHeight = height; + mComponents = ncomponents; } U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size) { - setSize(width, height, ncomponents); - return allocateData(size); // virtual + setSize(width, height, ncomponents); + return allocateData(size); // virtual } //--------------------------------------------------------------------------- @@ -802,17 +802,17 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si S32 LLImageRaw::sRawImageCount = 0; LLImageRaw::LLImageRaw() - : LLImageBase() + : LLImageBase() { - ++sRawImageCount; + ++sRawImageCount; } LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components) - : LLImageBase() + : LLImageBase() { - //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE ); - allocateDataSize(width, height, components); - ++sRawImageCount; + //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE ); + allocateDataSize(width, height, components); + ++sRawImageCount; } LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components) @@ -825,45 +825,45 @@ LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components) } LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy) - : LLImageBase() + : LLImageBase() { - if(no_copy) - { - setDataAndSize(data, width, height, components); - } - else if(allocateDataSize(width, height, components)) - { - memcpy(getData(), data, width*height*components); - } - ++sRawImageCount; + if(no_copy) + { + setDataAndSize(data, width, height, components); + } + else if(allocateDataSize(width, height, components)) + { + memcpy(getData(), data, width*height*components); + } + ++sRawImageCount; } //LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) -// : LLImageBase() +// : LLImageBase() //{ -// createFromFile(filename, j2c_lowest_mip_only); +// createFromFile(filename, j2c_lowest_mip_only); //} LLImageRaw::~LLImageRaw() { - // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData() - // NOT LLImageRaw::deleteData() - deleteData(); - --sRawImageCount; + // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData() + // NOT LLImageRaw::deleteData() + deleteData(); + --sRawImageCount; } // virtual U8* LLImageRaw::allocateData(S32 size) { - U8* res = LLImageBase::allocateData(size); - return res; + U8* res = LLImageBase::allocateData(size); + return res; } // virtual U8* LLImageRaw::reallocateData(S32 size) { - U8* res = LLImageBase::reallocateData(size); - return res; + U8* res = LLImageBase::reallocateData(size); + return res; } void LLImageRaw::releaseData() @@ -875,118 +875,118 @@ void LLImageRaw::releaseData() // virtual void LLImageRaw::deleteData() { - LLImageBase::deleteData(); + LLImageBase::deleteData(); } -void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) -{ - if(data == getData()) - { - return ; - } +void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) +{ + if(data == getData()) + { + return ; + } - deleteData(); + deleteData(); - LLImageBase::setSize(width, height, components) ; - LLImageBase::setDataAndSize(data, width * height * components) ; + LLImageBase::setSize(width, height, components) ; + LLImageBase::setDataAndSize(data, width * height * components) ; } bool LLImageRaw::resize(U16 width, U16 height, S8 components) { - if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid()) - { - return true; - } - // Reallocate the data buffer. - deleteData(); + if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid()) + { + return true; + } + // Reallocate the data buffer. + deleteData(); - allocateDataSize(width,height,components); + allocateDataSize(width,height,components); - return !isBufferInvalid(); + return !isBufferInvalid(); } bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, - const U8 *data, U32 stride, bool reverse_y) + const U8 *data, U32 stride, bool reverse_y) { - if (!getData()) - { - return false; - } - if (!data) - { - return false; - } + if (!getData()) + { + return false; + } + if (!data) + { + return false; + } - // Should do some simple bounds checking + // Should do some simple bounds checking - U32 i; - for (i = 0; i < height; i++) - { - const U32 row = reverse_y ? height - 1 - i : i; - const U32 from_offset = row * ((stride == 0) ? width*getComponents() : stride); - const U32 to_offset = (y_pos + i)*getWidth() + x_pos; - memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */ - data + from_offset, getComponents()*width); - } + U32 i; + for (i = 0; i < height; i++) + { + const U32 row = reverse_y ? height - 1 - i : i; + const U32 from_offset = row * ((stride == 0) ? width*getComponents() : stride); + const U32 to_offset = (y_pos + i)*getWidth() + x_pos; + memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */ + data + from_offset, getComponents()*width); + } - return true; + return true; } void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a) { - llassert( getComponents() <= 4 ); - // This is fairly bogus, but it'll do for now. - if (isBufferInvalid()) - { - LL_WARNS() << "Invalid image buffer" << LL_ENDL; - return; - } - - U8 *pos = getData(); - U32 x, y; - for (x = 0; x < getWidth(); x++) - { - for (y = 0; y < getHeight(); y++) - { - *pos = r; - pos++; - if (getComponents() == 1) - { - continue; - } - *pos = g; - pos++; - if (getComponents() == 2) - { - continue; - } - *pos = b; - pos++; - if (getComponents() == 3) - { - continue; - } - *pos = a; - pos++; - } - } + llassert( getComponents() <= 4 ); + // This is fairly bogus, but it'll do for now. + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + + U8 *pos = getData(); + U32 x, y; + for (x = 0; x < getWidth(); x++) + { + for (y = 0; y < getHeight(); y++) + { + *pos = r; + pos++; + if (getComponents() == 1) + { + continue; + } + *pos = g; + pos++; + if (getComponents() == 2) + { + continue; + } + *pos = b; + pos++; + if (getComponents() == 3) + { + continue; + } + *pos = a; + pos++; + } + } } // Reverses the order of the rows in the image void LLImageRaw::verticalFlip() { - S32 row_bytes = getWidth() * getComponents(); - llassert(row_bytes > 0); - std::vector line_buffer(row_bytes); - S32 mid_row = getHeight() / 2; - for( S32 row = 0; row < mid_row; row++ ) - { - U8* row_a_data = getData() + row * row_bytes; - U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes; - memcpy( &line_buffer[0], row_a_data, row_bytes ); - memcpy( row_a_data, row_b_data, row_bytes ); - memcpy( row_b_data, &line_buffer[0], row_bytes ); - } + S32 row_bytes = getWidth() * getComponents(); + llassert(row_bytes > 0); + std::vector line_buffer(row_bytes); + S32 mid_row = getHeight() / 2; + for( S32 row = 0; row < mid_row; row++ ) + { + U8* row_a_data = getData() + row * row_bytes; + U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes; + memcpy( &line_buffer[0], row_a_data, row_bytes ); + memcpy( row_a_data, row_b_data, row_bytes ); + memcpy( row_b_data, &line_buffer[0], row_bytes ); + } } @@ -1079,256 +1079,256 @@ bool LLImageRaw::makeAlpha() void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) { - // Find new sizes - S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim); - S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim); + // Find new sizes + S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim); + S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim); - scale( new_width, new_height, scale_image ); + scale( new_width, new_height, scale_image ); } void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image) { - // Find new sizes - S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE); - S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE); + // Find new sizes + S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE); + S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE); - scale( new_width, new_height, scale_image ); + scale( new_width, new_height, scale_image ); } // static S32 LLImageRaw::biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim) { - // Strong bias towards rounding down (to save bandwidth) - // No bias would mean THRESHOLD == 1.5f; - const F32 THRESHOLD = 1.75f; - - // Find new sizes - S32 larger_dim = max_dim; // 2^n >= curr_dim - S32 smaller_dim = max_dim; // 2^(n-1) <= curr_dim - while( (smaller_dim > curr_dim) && (smaller_dim > MIN_IMAGE_SIZE) ) - { - larger_dim = smaller_dim; - smaller_dim >>= 1; - } - return ( ((F32)curr_dim / (F32)smaller_dim) > THRESHOLD ) ? larger_dim : smaller_dim; + // Strong bias towards rounding down (to save bandwidth) + // No bias would mean THRESHOLD == 1.5f; + const F32 THRESHOLD = 1.75f; + + // Find new sizes + S32 larger_dim = max_dim; // 2^n >= curr_dim + S32 smaller_dim = max_dim; // 2^(n-1) <= curr_dim + while( (smaller_dim > curr_dim) && (smaller_dim > MIN_IMAGE_SIZE) ) + { + larger_dim = smaller_dim; + smaller_dim >>= 1; + } + return ( ((F32)curr_dim / (F32)smaller_dim) > THRESHOLD ) ? larger_dim : smaller_dim; } // static S32 LLImageRaw::expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim) { - S32 new_dim = MIN_IMAGE_SIZE; - while( (new_dim < curr_dim) && (new_dim < max_dim) ) - { - new_dim <<= 1; - } + S32 new_dim = MIN_IMAGE_SIZE; + while( (new_dim < curr_dim) && (new_dim < max_dim) ) + { + new_dim <<= 1; + } return new_dim; } // static S32 LLImageRaw::contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim) { - S32 new_dim = MAX_IMAGE_SIZE; - while( (new_dim > curr_dim) && (new_dim > min_dim) ) - { - new_dim >>= 1; - } + S32 new_dim = MAX_IMAGE_SIZE; + while( (new_dim > curr_dim) && (new_dim > min_dim) ) + { + new_dim >>= 1; + } return new_dim; } void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim) { - // Find new sizes - S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim); - S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim); + // Find new sizes + S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim); + S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim); - scale( new_width, new_height ); + scale( new_width, new_height ); } // Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f). Thanks, Jim Blinn! inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b ) { - U32 i = a * b + 128; - return U8((i + (i>>8)) >> 8); + U32 i = a * b + 128; + return U8((i + (i>>8)) >> 8); } void LLImageRaw::composite( LLImageRaw* src ) { - LLImageRaw* dst = this; // Just for clarity. - - if (!validateSrcAndDst("LLImageRaw::composite", src, dst)) - { - return; - } - - llassert((3 == src->getComponents()) || (4 == src->getComponents())); - llassert(3 == dst->getComponents()); - - if( 3 == dst->getComponents() ) - { - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) - { - // No scaling needed - if( 3 == src->getComponents() ) - { - copyUnscaled( src ); // alpha is one so just copy the data. - } - else - { - compositeUnscaled4onto3( src ); - } - } - else - { - if( 3 == src->getComponents() ) - { - copyScaled( src ); // alpha is one so just copy the data. - } - else - { - compositeScaled4onto3( src ); - } - } - } + LLImageRaw* dst = this; // Just for clarity. + + if (!validateSrcAndDst("LLImageRaw::composite", src, dst)) + { + return; + } + + llassert((3 == src->getComponents()) || (4 == src->getComponents())); + llassert(3 == dst->getComponents()); + + if( 3 == dst->getComponents() ) + { + if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) + { + // No scaling needed + if( 3 == src->getComponents() ) + { + copyUnscaled( src ); // alpha is one so just copy the data. + } + else + { + compositeUnscaled4onto3( src ); + } + } + else + { + if( 3 == src->getComponents() ) + { + copyScaled( src ); // alpha is one so just copy the data. + } + else + { + compositeScaled4onto3( src ); + } + } + } } // Src and dst can be any size. Src has 4 components. Dst has 3 components. void LLImageRaw::compositeScaled4onto3(LLImageRaw* src) { - LL_INFOS() << "compositeScaled4onto3" << LL_ENDL; + LL_INFOS() << "compositeScaled4onto3" << LL_ENDL; - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); + llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); - S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); - llassert_always(temp_data_size > 0); - std::vector temp_buffer(temp_data_size); + S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); + llassert_always(temp_data_size > 0); + std::vector temp_buffer(temp_data_size); - // Vertical: scale but no composite - for( S32 col = 0; col < src->getWidth(); col++ ) - { - copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); - } + // Vertical: scale but no composite + for( S32 col = 0; col < src->getWidth(); col++ ) + { + copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); + } - // Horizontal: scale and composite - for( S32 row = 0; row < dst->getHeight(); row++ ) - { - compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() ); - } + // Horizontal: scale and composite + for( S32 row = 0; row < dst->getHeight(); row++ ) + { + compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() ); + } } // Src and dst are same size. Src has 4 components. Dst has 3 components. void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) { - LLImageRaw* dst = this; // Just for clarity. - - llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - - U8* src_data = src->getData(); - U8* dst_data = dst->getData(); - S32 pixels = getWidth() * getHeight(); - while( pixels-- ) - { - U8 alpha = src_data[3]; - if( alpha ) - { - if( 255 == alpha ) - { - dst_data[0] = src_data[0]; - dst_data[1] = src_data[1]; - dst_data[2] = src_data[2]; - } - else - { - - U8 transparency = 255 - alpha; - dst_data[0] = fastFractionalMult( dst_data[0], transparency ) + fastFractionalMult( src_data[0], alpha ); - dst_data[1] = fastFractionalMult( dst_data[1], transparency ) + fastFractionalMult( src_data[1], alpha ); - dst_data[2] = fastFractionalMult( dst_data[2], transparency ) + fastFractionalMult( src_data[2], alpha ); - } - } - - src_data += 4; - dst_data += 3; - } + LLImageRaw* dst = this; // Just for clarity. + + llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + + U8* src_data = src->getData(); + U8* dst_data = dst->getData(); + S32 pixels = getWidth() * getHeight(); + while( pixels-- ) + { + U8 alpha = src_data[3]; + if( alpha ) + { + if( 255 == alpha ) + { + dst_data[0] = src_data[0]; + dst_data[1] = src_data[1]; + dst_data[2] = src_data[2]; + } + else + { + + U8 transparency = 255 - alpha; + dst_data[0] = fastFractionalMult( dst_data[0], transparency ) + fastFractionalMult( src_data[0], alpha ); + dst_data[1] = fastFractionalMult( dst_data[1], transparency ) + fastFractionalMult( src_data[1], alpha ); + dst_data[2] = fastFractionalMult( dst_data[2], transparency ) + fastFractionalMult( src_data[2], alpha ); + } + } + + src_data += 4; + dst_data += 3; + } } void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) - { - return; - } + if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) + { + return; + } - llassert( 1 == src->getComponents() ); - llassert( 4 == dst->getComponents() ); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + llassert( 1 == src->getComponents() ); + llassert( 4 == dst->getComponents() ); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); - U8* dst_data = dst->getData(); - for ( S32 i = 0; i < pixels; i++ ) - { - dst_data[0] = fill.mV[0]; - dst_data[1] = fill.mV[1]; - dst_data[2] = fill.mV[2]; - dst_data[3] = src_data[0]; - src_data += 1; - dst_data += 4; - } + S32 pixels = getWidth() * getHeight(); + U8* src_data = src->getData(); + U8* dst_data = dst->getData(); + for ( S32 i = 0; i < pixels; i++ ) + { + dst_data[0] = fill.mV[0]; + dst_data[1] = fill.mV[1]; + dst_data[2] = fill.mV[2]; + dst_data[3] = src_data[0]; + src_data += 1; + dst_data += 4; + } } // Fill the buffer with a constant color void LLImageRaw::fill( const LLColor4U& color ) { - if (isBufferInvalid()) - { - LL_WARNS() << "Invalid image buffer" << LL_ENDL; - return; - } - - S32 pixels = getWidth() * getHeight(); - if( 4 == getComponents() ) - { - U32* data = (U32*) getData(); - U32 rgbaColor = color.asRGBA(); - for( S32 i = 0; i < pixels; i++ ) - { - data[ i ] = rgbaColor; - } - } - else - if( 3 == getComponents() ) - { - U8* data = getData(); - for( S32 i = 0; i < pixels; i++ ) - { - data[0] = color.mV[0]; - data[1] = color.mV[1]; - data[2] = color.mV[2]; - data += 3; - } - } -} + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + + S32 pixels = getWidth() * getHeight(); + if( 4 == getComponents() ) + { + U32* data = (U32*) getData(); + U32 rgbaColor = color.asRGBA(); + for( S32 i = 0; i < pixels; i++ ) + { + data[ i ] = rgbaColor; + } + } + else + if( 3 == getComponents() ) + { + U8* data = getData(); + for( S32 i = 0; i < pixels; i++ ) + { + data[0] = color.mV[0]; + data[1] = color.mV[1]; + data[2] = color.mV[2]; + data += 3; + } + } +} void LLImageRaw::tint( const LLColor3& color ) { - llassert( (3 == getComponents()) || (4 == getComponents()) ); - if (isBufferInvalid()) - { - LL_WARNS() << "Invalid image buffer" << LL_ENDL; - return; - } + llassert( (3 == getComponents()) || (4 == getComponents()) ); + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } - S32 pixels = getWidth() * getHeight(); + S32 pixels = getWidth() * getHeight(); const S32 components = getComponents(); U8* data = getData(); for( S32 i = 0; i < pixels; i++ ) @@ -1345,188 +1345,188 @@ void LLImageRaw::tint( const LLColor3& color ) LLPointer LLImageRaw::duplicate() { - if(getNumRefs() < 2) - { - return this; //nobody else refences to this image, no need to duplicate. - } + if(getNumRefs() < 2) + { + return this; //nobody else refences to this image, no need to duplicate. + } - //make a duplicate - LLPointer dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents()); - return dup; + //make a duplicate + LLPointer dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents()); + return dup; } // Src and dst can be any size. Src and dst can each have 3 or 4 components. void LLImageRaw::copy(LLImageRaw* src) { - LLImageRaw* dst = this; // Just for clarity. - - if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) - { - return; - } - - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) - { - // No scaling needed - if( src->getComponents() == dst->getComponents() ) - { - copyUnscaled( src ); - } - else - if( 3 == src->getComponents() ) - { - copyUnscaled3onto4( src ); - } - else - { - // 4 == src->getComponents() - copyUnscaled4onto3( src ); - } - } - else - { - // Scaling needed - // No scaling needed - if( src->getComponents() == dst->getComponents() ) - { - copyScaled( src ); - } - else - if( 3 == src->getComponents() ) - { - copyScaled3onto4( src ); - } - else - { - // 4 == src->getComponents() - copyScaled4onto3( src ); - } - } + LLImageRaw* dst = this; // Just for clarity. + + if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) + { + return; + } + + if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) + { + // No scaling needed + if( src->getComponents() == dst->getComponents() ) + { + copyUnscaled( src ); + } + else + if( 3 == src->getComponents() ) + { + copyUnscaled3onto4( src ); + } + else + { + // 4 == src->getComponents() + copyUnscaled4onto3( src ); + } + } + else + { + // Scaling needed + // No scaling needed + if( src->getComponents() == dst->getComponents() ) + { + copyScaled( src ); + } + else + if( 3 == src->getComponents() ) + { + copyScaled3onto4( src ); + } + else + { + // 4 == src->getComponents() + copyScaled4onto3( src ); + } + } } // Src and dst are same size. Src and dst have same number of components. void LLImageRaw::copyUnscaled(LLImageRaw* src) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); - llassert( src->getComponents() == dst->getComponents() ); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); + llassert( src->getComponents() == dst->getComponents() ); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */ + memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */ } // Src and dst can be any size. Src has 3 components. Dst has 4 components. void LLImageRaw::copyScaled3onto4(LLImageRaw* src) { - llassert( (3 == src->getComponents()) && (4 == getComponents()) ); + llassert( (3 == src->getComponents()) && (4 == getComponents()) ); - // Slow, but simple. Optimize later if needed. - LLImageRaw temp( src->getWidth(), src->getHeight(), 4); - temp.copyUnscaled3onto4( src ); - copyScaled( &temp ); + // Slow, but simple. Optimize later if needed. + LLImageRaw temp( src->getWidth(), src->getHeight(), 4); + temp.copyUnscaled3onto4( src ); + copyScaled( &temp ); } // Src and dst can be any size. Src has 4 components. Dst has 3 components. void LLImageRaw::copyScaled4onto3(LLImageRaw* src) { - llassert( (4 == src->getComponents()) && (3 == getComponents()) ); + llassert( (4 == src->getComponents()) && (3 == getComponents()) ); - // Slow, but simple. Optimize later if needed. - LLImageRaw temp( src->getWidth(), src->getHeight(), 3); - temp.copyUnscaled4onto3( src ); - copyScaled( &temp ); + // Slow, but simple. Optimize later if needed. + LLImageRaw temp( src->getWidth(), src->getHeight(), 3); + temp.copyUnscaled4onto3( src ); + copyScaled( &temp ); } // Src and dst are same size. Src has 4 components. Dst has 3 components. void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src ) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) ); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) ); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); - U8* dst_data = dst->getData(); - for( S32 i=0; igetData(); + U8* dst_data = dst->getData(); + for( S32 i=0; igetComponents() ); - llassert( 4 == dst->getComponents() ); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + LLImageRaw* dst = this; // Just for clarity. + llassert( 3 == src->getComponents() ); + llassert( 4 == dst->getComponents() ); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); - U8* dst_data = dst->getData(); - for( S32 i=0; igetData(); + U8* dst_data = dst->getData(); + for( S32 i=0; igetComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); - llassert_always( src->getComponents() == dst->getComponents() ); + llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); + llassert_always( src->getComponents() == dst->getComponents() ); - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) - { - memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */ - return; - } + if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) + { + memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */ + return; + } - bilinear_scale( - src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), src->getWidth()*src->getComponents() - , dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents(), dst->getWidth()*dst->getComponents() - ); + bilinear_scale( + src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), src->getWidth()*src->getComponents() + , dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents(), dst->getWidth()*dst->getComponents() + ); - /* - S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents(); - llassert_always(temp_data_size > 0); - std::vector temp_buffer(temp_data_size); + /* + S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents(); + llassert_always(temp_data_size > 0); + std::vector temp_buffer(temp_data_size); - // Vertical - for( S32 col = 0; col < src->getWidth(); col++ ) - { - copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); - } + // Vertical + for( S32 col = 0; col < src->getWidth(); col++ ) + { + copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); + } - // Horizontal - for( S32 row = 0; row < dst->getHeight(); row++ ) - { - copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 ); - } - */ + // Horizontal + for( S32 row = 0; row < dst->getHeight(); row++ ) + { + copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 ); + } + */ } @@ -1539,79 +1539,79 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) return false; } - if (isBufferInvalid()) - { - LL_WARNS() << "Invalid image buffer" << LL_ENDL; - return false; - } + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return false; + } - S32 old_width = getWidth(); - S32 old_height = getHeight(); - - if( (old_width == new_width) && (old_height == new_height) ) - { - return true; // Nothing to do. - } + S32 old_width = getWidth(); + S32 old_height = getHeight(); + + if( (old_width == new_width) && (old_height == new_height) ) + { + return true; // Nothing to do. + } - // Reallocate the data buffer. + // Reallocate the data buffer. - if (scale_image_data) - { - S32 new_data_size = new_width * new_height * components; + if (scale_image_data) + { + S32 new_data_size = new_width * new_height * components; - if (new_data_size > 0) + if (new_data_size > 0) { - U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size); - if(NULL == new_data) + U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size); + if(NULL == new_data) { - return false; + return false; } bilinear_scale(getData(), old_width, old_height, components, old_width*components, new_data, new_width, new_height, components, new_width*components); - setDataAndSize(new_data, new_width, new_height, components); - } - } - else try - { - // copy out existing image data - S32 temp_data_size = old_width * old_height * components; - std::vector temp_buffer(temp_data_size); - memcpy(&temp_buffer[0], getData(), temp_data_size); - - // allocate new image data, will delete old data - U8* new_buffer = allocateDataSize(new_width, new_height, components); + setDataAndSize(new_data, new_width, new_height, components); + } + } + else try + { + // copy out existing image data + S32 temp_data_size = old_width * old_height * components; + std::vector temp_buffer(temp_data_size); + memcpy(&temp_buffer[0], getData(), temp_data_size); + + // allocate new image data, will delete old data + U8* new_buffer = allocateDataSize(new_width, new_height, components); if (!new_buffer) { LL_WARNS() << "Failed to allocate new image data buffer" << LL_ENDL; return false; } - - for( S32 row = 0; row < new_height; row++ ) + + for( S32 row = 0; row < new_height; row++ ) { - if (row < old_height) + if (row < old_height) { - memcpy(new_buffer + (new_width * row * components), &temp_buffer[0] + (old_width * row * components), components * llmin(old_width, new_width)); - if (old_width < new_width) + memcpy(new_buffer + (new_width * row * components), &temp_buffer[0] + (old_width * row * components), components * llmin(old_width, new_width)); + if (old_width < new_width) { - // pad out rest of row with black - memset(new_buffer + (components * ((new_width * row) + old_width)), 0, components * (new_width - old_width)); + // pad out rest of row with black + memset(new_buffer + (components * ((new_width * row) + old_width)), 0, components * (new_width - old_width)); } } else { // pad remaining rows with black - memset(new_buffer + (new_width * row * components), 0, new_width * components); + memset(new_buffer + (new_width * row * components), 0, new_width * components); } } - } + } catch (std::bad_alloc&) // for temp_buffer { LL_WARNS() << "Failed to allocate temporary image buffer" << LL_ENDL; return false; } - return true ; + return true ; } LLPointer LLImageRaw::scaled(S32 new_width, S32 new_height) @@ -1665,253 +1665,253 @@ LLPointer LLImageRaw::scaled(S32 new_width, S32 new_height) void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) { - const S32 components = getComponents(); - llassert( components >= 1 && components <= 4 ); - - const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new - const F32 norm_factor = 1.f / ratio; - - S32 goff = components >= 2 ? 1 : 0; - S32 boff = components >= 3 ? 2 : 0; - for( S32 x = 0; x < out_pixel_len; x++ ) - { - // Sample input pixels in range from sample0 to sample1. - // Avoid floating point accumulation error... don't just add ratio each time. JC - const F32 sample0 = x * ratio; - const F32 sample1 = (x+1) * ratio; - const S32 index0 = llfloor(sample0); // left integer (floor) - const S32 index1 = llfloor(sample1); // right integer (floor) - const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left - const F32 fract1 = sample1 - F32(index1); // spill-over on right - - if( index0 == index1 ) - { - // Interval is embedded in one input pixel - S32 t0 = x * out_pixel_step * components; - S32 t1 = index0 * in_pixel_step * components; - U8* outp = out + t0; - U8* inp = in + t1; - for (S32 i = 0; i < components; ++i) - { - *outp = *inp; - ++outp; - ++inp; - } - } - else - { - // Left straddle - S32 t1 = index0 * in_pixel_step * components; - F32 r = in[t1 + 0] * fract0; - F32 g = in[t1 + goff] * fract0; - F32 b = in[t1 + boff] * fract0; - F32 a = 0; - if( components == 4) - { - a = in[t1 + 3] * fract0; - } - - // Central interval - if (components < 4) - { - for( S32 u = index0 + 1; u < index1; u++ ) - { - S32 t2 = u * in_pixel_step * components; - r += in[t2 + 0]; - g += in[t2 + goff]; - b += in[t2 + boff]; - } - } - else - { - for( S32 u = index0 + 1; u < index1; u++ ) - { - S32 t2 = u * in_pixel_step * components; - r += in[t2 + 0]; - g += in[t2 + 1]; - b += in[t2 + 2]; - a += in[t2 + 3]; - } - } - - // right straddle - // Watch out for reading off of end of input array. - if( fract1 && index1 < in_pixel_len ) - { - S32 t3 = index1 * in_pixel_step * components; - if (components < 4) - { - U8 in0 = in[t3 + 0]; - U8 in1 = in[t3 + goff]; - U8 in2 = in[t3 + boff]; - r += in0 * fract1; - g += in1 * fract1; - b += in2 * fract1; - } - else - { - U8 in0 = in[t3 + 0]; - U8 in1 = in[t3 + 1]; - U8 in2 = in[t3 + 2]; - U8 in3 = in[t3 + 3]; - r += in0 * fract1; - g += in1 * fract1; - b += in2 * fract1; - a += in3 * fract1; - } - } - - r *= norm_factor; - g *= norm_factor; - b *= norm_factor; - a *= norm_factor; // skip conditional - - S32 t4 = x * out_pixel_step * components; - out[t4 + 0] = U8(ll_round(r)); - if (components >= 2) - out[t4 + 1] = U8(ll_round(g)); - if (components >= 3) - out[t4 + 2] = U8(ll_round(b)); - if( components == 4) - out[t4 + 3] = U8(ll_round(a)); - } - } + const S32 components = getComponents(); + llassert( components >= 1 && components <= 4 ); + + const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new + const F32 norm_factor = 1.f / ratio; + + S32 goff = components >= 2 ? 1 : 0; + S32 boff = components >= 3 ? 2 : 0; + for( S32 x = 0; x < out_pixel_len; x++ ) + { + // Sample input pixels in range from sample0 to sample1. + // Avoid floating point accumulation error... don't just add ratio each time. JC + const F32 sample0 = x * ratio; + const F32 sample1 = (x+1) * ratio; + const S32 index0 = llfloor(sample0); // left integer (floor) + const S32 index1 = llfloor(sample1); // right integer (floor) + const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left + const F32 fract1 = sample1 - F32(index1); // spill-over on right + + if( index0 == index1 ) + { + // Interval is embedded in one input pixel + S32 t0 = x * out_pixel_step * components; + S32 t1 = index0 * in_pixel_step * components; + U8* outp = out + t0; + U8* inp = in + t1; + for (S32 i = 0; i < components; ++i) + { + *outp = *inp; + ++outp; + ++inp; + } + } + else + { + // Left straddle + S32 t1 = index0 * in_pixel_step * components; + F32 r = in[t1 + 0] * fract0; + F32 g = in[t1 + goff] * fract0; + F32 b = in[t1 + boff] * fract0; + F32 a = 0; + if( components == 4) + { + a = in[t1 + 3] * fract0; + } + + // Central interval + if (components < 4) + { + for( S32 u = index0 + 1; u < index1; u++ ) + { + S32 t2 = u * in_pixel_step * components; + r += in[t2 + 0]; + g += in[t2 + goff]; + b += in[t2 + boff]; + } + } + else + { + for( S32 u = index0 + 1; u < index1; u++ ) + { + S32 t2 = u * in_pixel_step * components; + r += in[t2 + 0]; + g += in[t2 + 1]; + b += in[t2 + 2]; + a += in[t2 + 3]; + } + } + + // right straddle + // Watch out for reading off of end of input array. + if( fract1 && index1 < in_pixel_len ) + { + S32 t3 = index1 * in_pixel_step * components; + if (components < 4) + { + U8 in0 = in[t3 + 0]; + U8 in1 = in[t3 + goff]; + U8 in2 = in[t3 + boff]; + r += in0 * fract1; + g += in1 * fract1; + b += in2 * fract1; + } + else + { + U8 in0 = in[t3 + 0]; + U8 in1 = in[t3 + 1]; + U8 in2 = in[t3 + 2]; + U8 in3 = in[t3 + 3]; + r += in0 * fract1; + g += in1 * fract1; + b += in2 * fract1; + a += in3 * fract1; + } + } + + r *= norm_factor; + g *= norm_factor; + b *= norm_factor; + a *= norm_factor; // skip conditional + + S32 t4 = x * out_pixel_step * components; + out[t4 + 0] = U8(ll_round(r)); + if (components >= 2) + out[t4 + 1] = U8(ll_round(g)); + if (components >= 3) + out[t4 + 2] = U8(ll_round(b)); + if( components == 4) + out[t4 + 3] = U8(ll_round(a)); + } + } } void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ) { - llassert( getComponents() == 3 ); - - const S32 IN_COMPONENTS = 4; - const S32 OUT_COMPONENTS = 3; - - const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new - const F32 norm_factor = 1.f / ratio; - - for( S32 x = 0; x < out_pixel_len; x++ ) - { - // Sample input pixels in range from sample0 to sample1. - // Avoid floating point accumulation error... don't just add ratio each time. JC - const F32 sample0 = x * ratio; - const F32 sample1 = (x+1) * ratio; - const S32 index0 = S32(sample0); // left integer (floor) - const S32 index1 = S32(sample1); // right integer (floor) - const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left - const F32 fract1 = sample1 - F32(index1); // spill-over on right - - U8 in_scaled_r; - U8 in_scaled_g; - U8 in_scaled_b; - U8 in_scaled_a; - - if( index0 == index1 ) - { - // Interval is embedded in one input pixel - S32 t1 = index0 * IN_COMPONENTS; - in_scaled_r = in[t1 + 0]; - in_scaled_g = in[t1 + 0]; - in_scaled_b = in[t1 + 0]; - in_scaled_a = in[t1 + 0]; - } - else - { - // Left straddle - S32 t1 = index0 * IN_COMPONENTS; - F32 r = in[t1 + 0] * fract0; - F32 g = in[t1 + 1] * fract0; - F32 b = in[t1 + 2] * fract0; - F32 a = in[t1 + 3] * fract0; - - // Central interval - for( S32 u = index0 + 1; u < index1; u++ ) - { - S32 t2 = u * IN_COMPONENTS; - r += in[t2 + 0]; - g += in[t2 + 1]; - b += in[t2 + 2]; - a += in[t2 + 3]; - } - - // right straddle - // Watch out for reading off of end of input array. - if( fract1 && index1 < in_pixel_len ) - { - S32 t3 = index1 * IN_COMPONENTS; - r += in[t3 + 0] * fract1; - g += in[t3 + 1] * fract1; - b += in[t3 + 2] * fract1; - a += in[t3 + 3] * fract1; - } - - r *= norm_factor; - g *= norm_factor; - b *= norm_factor; - a *= norm_factor; - - in_scaled_r = U8(ll_round(r)); - in_scaled_g = U8(ll_round(g)); - in_scaled_b = U8(ll_round(b)); - in_scaled_a = U8(ll_round(a)); - } - - if( in_scaled_a ) - { - if( 255 == in_scaled_a ) - { - out[0] = in_scaled_r; - out[1] = in_scaled_g; - out[2] = in_scaled_b; - } - else - { - U8 transparency = 255 - in_scaled_a; - out[0] = fastFractionalMult( out[0], transparency ) + fastFractionalMult( in_scaled_r, in_scaled_a ); - out[1] = fastFractionalMult( out[1], transparency ) + fastFractionalMult( in_scaled_g, in_scaled_a ); - out[2] = fastFractionalMult( out[2], transparency ) + fastFractionalMult( in_scaled_b, in_scaled_a ); - } - } - out += OUT_COMPONENTS; - } + llassert( getComponents() == 3 ); + + const S32 IN_COMPONENTS = 4; + const S32 OUT_COMPONENTS = 3; + + const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new + const F32 norm_factor = 1.f / ratio; + + for( S32 x = 0; x < out_pixel_len; x++ ) + { + // Sample input pixels in range from sample0 to sample1. + // Avoid floating point accumulation error... don't just add ratio each time. JC + const F32 sample0 = x * ratio; + const F32 sample1 = (x+1) * ratio; + const S32 index0 = S32(sample0); // left integer (floor) + const S32 index1 = S32(sample1); // right integer (floor) + const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left + const F32 fract1 = sample1 - F32(index1); // spill-over on right + + U8 in_scaled_r; + U8 in_scaled_g; + U8 in_scaled_b; + U8 in_scaled_a; + + if( index0 == index1 ) + { + // Interval is embedded in one input pixel + S32 t1 = index0 * IN_COMPONENTS; + in_scaled_r = in[t1 + 0]; + in_scaled_g = in[t1 + 0]; + in_scaled_b = in[t1 + 0]; + in_scaled_a = in[t1 + 0]; + } + else + { + // Left straddle + S32 t1 = index0 * IN_COMPONENTS; + F32 r = in[t1 + 0] * fract0; + F32 g = in[t1 + 1] * fract0; + F32 b = in[t1 + 2] * fract0; + F32 a = in[t1 + 3] * fract0; + + // Central interval + for( S32 u = index0 + 1; u < index1; u++ ) + { + S32 t2 = u * IN_COMPONENTS; + r += in[t2 + 0]; + g += in[t2 + 1]; + b += in[t2 + 2]; + a += in[t2 + 3]; + } + + // right straddle + // Watch out for reading off of end of input array. + if( fract1 && index1 < in_pixel_len ) + { + S32 t3 = index1 * IN_COMPONENTS; + r += in[t3 + 0] * fract1; + g += in[t3 + 1] * fract1; + b += in[t3 + 2] * fract1; + a += in[t3 + 3] * fract1; + } + + r *= norm_factor; + g *= norm_factor; + b *= norm_factor; + a *= norm_factor; + + in_scaled_r = U8(ll_round(r)); + in_scaled_g = U8(ll_round(g)); + in_scaled_b = U8(ll_round(b)); + in_scaled_a = U8(ll_round(a)); + } + + if( in_scaled_a ) + { + if( 255 == in_scaled_a ) + { + out[0] = in_scaled_r; + out[1] = in_scaled_g; + out[2] = in_scaled_b; + } + else + { + U8 transparency = 255 - in_scaled_a; + out[0] = fastFractionalMult( out[0], transparency ) + fastFractionalMult( in_scaled_r, in_scaled_a ); + out[1] = fastFractionalMult( out[1], transparency ) + fastFractionalMult( in_scaled_g, in_scaled_a ); + out[2] = fastFractionalMult( out[2], transparency ) + fastFractionalMult( in_scaled_b, in_scaled_a ); + } + } + out += OUT_COMPONENTS; + } } void LLImageRaw::addEmissive(LLImageRaw* src) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - if (!validateSrcAndDst(__FUNCTION__, src, dst)) - { - return; - } + if (!validateSrcAndDst(__FUNCTION__, src, dst)) + { + return; + } - llassert((3 == src->getComponents()) || (4 == src->getComponents())); - llassert(3 == dst->getComponents()); + llassert((3 == src->getComponents()) || (4 == src->getComponents())); + llassert(3 == dst->getComponents()); - if( 3 == dst->getComponents() ) - { - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) - { + if( 3 == dst->getComponents() ) + { + if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) + { addEmissiveUnscaled(src); - } - else - { + } + else + { addEmissiveScaled(src); - } - } + } + } } void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - llassert((3 == src->getComponents()) || (4 == src->getComponents())); - llassert((3 == dst->getComponents()) || (4 == dst->getComponents())); - llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + llassert((3 == src->getComponents()) || (4 == src->getComponents())); + llassert((3 == dst->getComponents()) || (4 == dst->getComponents())); + llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); U8* const src_data = src->getData(); U8* const dst_data = dst->getData(); - for(S32 y = 0; y < dst->getHeight(); ++y) - { + for(S32 y = 0; y < dst->getHeight(); ++y) + { const S32 src_row_offset = src->getComponents() * src->getWidth() * y; const S32 dst_row_offset = dst->getComponents() * dst->getWidth() * y; for (S32 x = 0; x < dst->getWidth(); ++x) @@ -1924,17 +1924,17 @@ void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src) dst_pixel[1] = llmin(255, dst_pixel[1] + src_pixel[1]); dst_pixel[2] = llmin(255, dst_pixel[2] + src_pixel[2]); } - } + } } void LLImageRaw::addEmissiveScaled(LLImageRaw* src) { - LLImageRaw* dst = this; // Just for clarity. + LLImageRaw* dst = this; // Just for clarity. - llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); + llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); LLImageRaw temp(dst->getWidth(), dst->getHeight(), dst->getComponents()); - llassert_always(temp.getDataSize() > 0); + llassert_always(temp.getDataSize() > 0); temp.copyScaled(src); dst->addEmissiveUnscaled(&temp); @@ -1943,161 +1943,161 @@ void LLImageRaw::addEmissiveScaled(LLImageRaw* src) bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst) { - if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid()) - { - LL_WARNS() << func << ": Source: "; - if (!src) LL_CONT << "Null pointer"; - else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer"; - else LL_CONT << "OK"; + if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid()) + { + LL_WARNS() << func << ": Source: "; + if (!src) LL_CONT << "Null pointer"; + else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; - LL_CONT << "; Destination: "; - if (!dst) LL_CONT << "Null pointer"; - else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer"; - else LL_CONT << "OK"; - LL_CONT << "." << LL_ENDL; + LL_CONT << "; Destination: "; + if (!dst) LL_CONT << "Null pointer"; + else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; + LL_CONT << "." << LL_ENDL; - return false; - } - return true; + return false; + } + return true; } //---------------------------------------------------------------------------- static struct { - const char* exten; - EImageCodec codec; + const char* exten; + EImageCodec codec; } file_extensions[] = { - { "bmp", IMG_CODEC_BMP }, - { "tga", IMG_CODEC_TGA }, - { "j2c", IMG_CODEC_J2C }, - { "jp2", IMG_CODEC_J2C }, - { "texture", IMG_CODEC_J2C }, - { "jpg", IMG_CODEC_JPEG }, - { "jpeg", IMG_CODEC_JPEG }, - { "mip", IMG_CODEC_DXT }, - { "dxt", IMG_CODEC_DXT }, - { "png", IMG_CODEC_PNG } + { "bmp", IMG_CODEC_BMP }, + { "tga", IMG_CODEC_TGA }, + { "j2c", IMG_CODEC_J2C }, + { "jp2", IMG_CODEC_J2C }, + { "texture", IMG_CODEC_J2C }, + { "jpg", IMG_CODEC_JPEG }, + { "jpeg", IMG_CODEC_JPEG }, + { "mip", IMG_CODEC_DXT }, + { "dxt", IMG_CODEC_DXT }, + { "png", IMG_CODEC_PNG } }; #define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions) #if 0 static std::string find_file(std::string &name, S8 *codec) { - std::string tname; - for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++) - { - tname = name + "." + std::string(file_extensions[i].exten); - llifstream ifs(tname.c_str(), llifstream::binary); - if (ifs.is_open()) - { - ifs.close(); - if (codec) - *codec = file_extensions[i].codec; - return std::string(file_extensions[i].exten); - } - } - return std::string(""); + std::string tname; + for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++) + { + tname = name + "." + std::string(file_extensions[i].exten); + llifstream ifs(tname.c_str(), llifstream::binary); + if (ifs.is_open()) + { + ifs.close(); + if (codec) + *codec = file_extensions[i].codec; + return std::string(file_extensions[i].exten); + } + } + return std::string(""); } #endif EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten) { - if (!exten.empty()) - { - for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++) - { - if (exten == file_extensions[i].exten) - return file_extensions[i].codec; - } - } - return IMG_CODEC_INVALID; + if (!exten.empty()) + { + for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++) + { + if (exten == file_extensions[i].exten) + return file_extensions[i].codec; + } + } + return IMG_CODEC_INVALID; } #if 0 bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only) { - std::string name = filename; - size_t dotidx = name.rfind('.'); - S8 codec = IMG_CODEC_INVALID; - std::string exten; - - deleteData(); // delete any existing data - - if (dotidx != std::string::npos) - { - exten = name.substr(dotidx+1); - LLStringUtil::toLower(exten); - codec = getCodecFromExtension(exten); - } - else - { - exten = find_file(name, &codec); - name = name + "." + exten; - } - if (codec == IMG_CODEC_INVALID) - { - return false; // format not recognized - } - - llifstream ifs(name.c_str(), llifstream::binary); - if (!ifs.is_open()) - { - // SJB: changed from LL_INFOS() to LL_DEBUGS() to reduce spam - LL_DEBUGS() << "Unable to open image file: " << name << LL_ENDL; - return false; - } - - ifs.seekg (0, std::ios::end); - int length = ifs.tellg(); - if (j2c_lowest_mip_only && length > 2048) - { - length = 2048; - } - ifs.seekg (0, std::ios::beg); - - if (!length) - { - LL_INFOS() << "Zero length file file: " << name << LL_ENDL; - return false; - } - - LLPointer image = LLImageFormatted::createFromType(codec); - llassert(image.notNull()); - - U8 *buffer = image->allocateData(length); - ifs.read ((char*)buffer, length); - ifs.close(); - - bool success; - - success = image->updateData(); - if (success) - { - if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C) - { - S32 width = image->getWidth(); - S32 height = image->getHeight(); - S32 discard_level = 0; - while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL) - { - width >>= 1; - height >>= 1; - discard_level++; - } - ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level); - } - success = image->decode(this, 100000.0f); - } - - image = NULL; // deletes image - if (!success) - { - deleteData(); - LL_WARNS() << "Unable to decode image" << name << LL_ENDL; - return false; - } - - return true; + std::string name = filename; + size_t dotidx = name.rfind('.'); + S8 codec = IMG_CODEC_INVALID; + std::string exten; + + deleteData(); // delete any existing data + + if (dotidx != std::string::npos) + { + exten = name.substr(dotidx+1); + LLStringUtil::toLower(exten); + codec = getCodecFromExtension(exten); + } + else + { + exten = find_file(name, &codec); + name = name + "." + exten; + } + if (codec == IMG_CODEC_INVALID) + { + return false; // format not recognized + } + + llifstream ifs(name.c_str(), llifstream::binary); + if (!ifs.is_open()) + { + // SJB: changed from LL_INFOS() to LL_DEBUGS() to reduce spam + LL_DEBUGS() << "Unable to open image file: " << name << LL_ENDL; + return false; + } + + ifs.seekg (0, std::ios::end); + int length = ifs.tellg(); + if (j2c_lowest_mip_only && length > 2048) + { + length = 2048; + } + ifs.seekg (0, std::ios::beg); + + if (!length) + { + LL_INFOS() << "Zero length file file: " << name << LL_ENDL; + return false; + } + + LLPointer image = LLImageFormatted::createFromType(codec); + llassert(image.notNull()); + + U8 *buffer = image->allocateData(length); + ifs.read ((char*)buffer, length); + ifs.close(); + + bool success; + + success = image->updateData(); + if (success) + { + if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C) + { + S32 width = image->getWidth(); + S32 height = image->getHeight(); + S32 discard_level = 0; + while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL) + { + width >>= 1; + height >>= 1; + discard_level++; + } + ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level); + } + success = image->decode(this, 100000.0f); + } + + image = NULL; // deletes image + if (!success) + { + deleteData(); + LL_WARNS() << "Unable to decode image" << name << LL_ENDL; + return false; + } + + return true; } #endif //--------------------------------------------------------------------------- @@ -2108,21 +2108,21 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip S32 LLImageFormatted::sGlobalFormattedMemory = 0; LLImageFormatted::LLImageFormatted(S8 codec) - : LLImageBase(), - mCodec(codec), - mDecoding(0), - mDecoded(0), - mDiscardLevel(-1), - mLevels(0) + : LLImageBase(), + mCodec(codec), + mDecoding(0), + mDecoded(0), + mDiscardLevel(-1), + mLevels(0) { } // virtual LLImageFormatted::~LLImageFormatted() { - // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData() - // NOT LLImageFormatted::deleteData() - deleteData(); + // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData() + // NOT LLImageFormatted::deleteData() + deleteData(); } //---------------------------------------------------------------------------- @@ -2130,16 +2130,16 @@ LLImageFormatted::~LLImageFormatted() //virtual void LLImageFormatted::resetLastError() { - LLImage::setLastError(""); + LLImage::setLastError(""); } //virtual void LLImageFormatted::setLastError(const std::string& message, const std::string& filename) { - std::string error = message; - if (!filename.empty()) - error += std::string(" FILE: ") + filename; - LLImage::setLastError(error); + std::string error = message; + if (!filename.empty()) + error += std::string(" FILE: ") + filename; + LLImage::setLastError(error); } //---------------------------------------------------------------------------- @@ -2147,97 +2147,97 @@ void LLImageFormatted::setLastError(const std::string& message, const std::strin // static LLImageFormatted* LLImageFormatted::createFromType(S8 codec) { - LLImageFormatted* image; - switch(codec) - { - case IMG_CODEC_BMP: - image = new LLImageBMP(); - break; - case IMG_CODEC_TGA: - image = new LLImageTGA(); - break; - case IMG_CODEC_JPEG: - image = new LLImageJPEG(); - break; - case IMG_CODEC_PNG: - image = new LLImagePNG(); - break; - case IMG_CODEC_J2C: - image = new LLImageJ2C(); - break; - case IMG_CODEC_DXT: - image = new LLImageDXT(); - break; - default: - image = NULL; - break; - } - return image; + LLImageFormatted* image; + switch(codec) + { + case IMG_CODEC_BMP: + image = new LLImageBMP(); + break; + case IMG_CODEC_TGA: + image = new LLImageTGA(); + break; + case IMG_CODEC_JPEG: + image = new LLImageJPEG(); + break; + case IMG_CODEC_PNG: + image = new LLImagePNG(); + break; + case IMG_CODEC_J2C: + image = new LLImageJ2C(); + break; + case IMG_CODEC_DXT: + image = new LLImageDXT(); + break; + default: + image = NULL; + break; + } + return image; } // static LLImageFormatted* LLImageFormatted::createFromExtension(const std::string& instring) { - std::string exten; - size_t dotidx = instring.rfind('.'); - if (dotidx != std::string::npos) - { - exten = instring.substr(dotidx+1); - } - else - { - exten = instring; - } - S8 codec = getCodecFromExtension(exten); - return createFromType(codec); + std::string exten; + size_t dotidx = instring.rfind('.'); + if (dotidx != std::string::npos) + { + exten = instring.substr(dotidx+1); + } + else + { + exten = instring; + } + S8 codec = getCodecFromExtension(exten); + return createFromType(codec); } //---------------------------------------------------------------------------- // virtual void LLImageFormatted::dump() { - LLImageBase::dump(); + LLImageBase::dump(); - LL_INFOS() << "LLImageFormatted" - << " mDecoding " << mDecoding - << " mCodec " << S32(mCodec) - << " mDecoded " << mDecoded - << LL_ENDL; + LL_INFOS() << "LLImageFormatted" + << " mDecoding " << mDecoding + << " mCodec " << S32(mCodec) + << " mDecoded " << mDecoded + << LL_ENDL; } //---------------------------------------------------------------------------- S32 LLImageFormatted::calcDataSize(S32 discard_level) { - if (discard_level < 0) - { - discard_level = mDiscardLevel; - } - S32 w = getWidth() >> discard_level; - S32 h = getHeight() >> discard_level; - w = llmax(w, 1); - h = llmax(h, 1); - return w * h * getComponents(); + if (discard_level < 0) + { + discard_level = mDiscardLevel; + } + S32 w = getWidth() >> discard_level; + S32 h = getHeight() >> discard_level; + w = llmax(w, 1); + h = llmax(h, 1); + return w * h * getComponents(); } S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes) { - llassert(bytes >= 0); - S32 discard_level = 0; - while (1) - { - S32 bytes_needed = calcDataSize(discard_level); // virtual - if (bytes_needed <= bytes) - { - break; - } - discard_level++; - if (discard_level > MAX_IMAGE_MIP) - { - return -1; - } - } - return discard_level; + llassert(bytes >= 0); + S32 discard_level = 0; + while (1) + { + S32 bytes_needed = calcDataSize(discard_level); // virtual + if (bytes_needed <= bytes) + { + break; + } + discard_level++; + if (discard_level > MAX_IMAGE_MIP) + { + return -1; + } + } + return discard_level; } @@ -2246,34 +2246,34 @@ S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes) // Subclasses that can handle more than 4 channels should override this function. bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32 decode_time, S32 first_channel, S32 max_channel) { - llassert( (first_channel == 0) && (max_channel == 4) ); - return decode( raw_image, decode_time ); // Loads first 4 channels by default. -} + llassert( (first_channel == 0) && (max_channel == 4) ); + return decode( raw_image, decode_time ); // Loads first 4 channels by default. +} //---------------------------------------------------------------------------- // virtual U8* LLImageFormatted::allocateData(S32 size) { - U8* res = LLImageBase::allocateData(size); // calls deleteData() - sGlobalFormattedMemory += getDataSize(); - return res; + U8* res = LLImageBase::allocateData(size); // calls deleteData() + sGlobalFormattedMemory += getDataSize(); + return res; } // virtual U8* LLImageFormatted::reallocateData(S32 size) { - sGlobalFormattedMemory -= getDataSize(); - U8* res = LLImageBase::reallocateData(size); - sGlobalFormattedMemory += getDataSize(); - return res; + sGlobalFormattedMemory -= getDataSize(); + U8* res = LLImageBase::reallocateData(size); + sGlobalFormattedMemory += getDataSize(); + return res; } // virtual void LLImageFormatted::deleteData() { - sGlobalFormattedMemory -= getDataSize(); - LLImageBase::deleteData(); + sGlobalFormattedMemory -= getDataSize(); + LLImageBase::deleteData(); } //---------------------------------------------------------------------------- @@ -2281,196 +2281,196 @@ void LLImageFormatted::deleteData() // virtual void LLImageFormatted::sanityCheck() { - LLImageBase::sanityCheck(); + LLImageBase::sanityCheck(); - if (mCodec >= IMG_CODEC_EOF) - { - LL_ERRS() << "Failed LLImageFormatted::sanityCheck " - << "decoding " << S32(mDecoding) - << "decoded " << S32(mDecoded) - << "codec " << S32(mCodec) - << LL_ENDL; - } + if (mCodec >= IMG_CODEC_EOF) + { + LL_ERRS() << "Failed LLImageFormatted::sanityCheck " + << "decoding " << S32(mDecoding) + << "decoded " << S32(mDecoded) + << "codec " << S32(mCodec) + << LL_ENDL; + } } //---------------------------------------------------------------------------- bool LLImageFormatted::copyData(U8 *data, S32 size) { - if ( data && ((data != getData()) || (size != getDataSize())) ) - { - deleteData(); - allocateData(size); - memcpy(getData(), data, size); /* Flawfinder: ignore */ - } - return true; + if ( data && ((data != getData()) || (size != getDataSize())) ) + { + deleteData(); + allocateData(size); + memcpy(getData(), data, size); /* Flawfinder: ignore */ + } + return true; } // LLImageFormatted becomes the owner of data void LLImageFormatted::setData(U8 *data, S32 size) { - if (data && data != getData()) - { - deleteData(); - setDataAndSize(data, size); // Access private LLImageBase members + if (data && data != getData()) + { + deleteData(); + setDataAndSize(data, size); // Access private LLImageBase members - sGlobalFormattedMemory += getDataSize(); - } + sGlobalFormattedMemory += getDataSize(); + } } void LLImageFormatted::appendData(U8 *data, S32 size) { - if (data) - { - if (!getData()) - { - setData(data, size); - } - else - { - S32 cursize = getDataSize(); - S32 newsize = cursize + size; - reallocateData(newsize); - memcpy(getData() + cursize, data, size); - ll_aligned_free_16(data); - } - } + if (data) + { + if (!getData()) + { + setData(data, size); + } + else + { + S32 cursize = getDataSize(); + S32 newsize = cursize + size; + reallocateData(newsize); + memcpy(getData() + cursize, data, size); + ll_aligned_free_16(data); + } + } } //---------------------------------------------------------------------------- bool LLImageFormatted::load(const std::string &filename, int load_size) { - resetLastError(); - - S32 file_size = 0; - LLAPRFile infile ; - infile.open(filename, LL_APR_RB, NULL, &file_size); - apr_file_t* apr_file = infile.getFileHandle(); - if (!apr_file) - { - setLastError("Unable to open file for reading", filename); - return false; - } - if (file_size == 0) - { - setLastError("File is empty",filename); - return false; - } - - // Constrain the load size to acceptable values - if ((load_size == 0) || (load_size > file_size)) - { - load_size = file_size; - } - bool res; - U8 *data = allocateData(load_size); - if (data) - { - apr_size_t bytes_read = load_size; - apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read - if (s != APR_SUCCESS || (S32) bytes_read != load_size) - { - deleteData(); - setLastError("Unable to read file",filename); - res = false; - } - else - { - res = updateData(); - } - } - else - { - setLastError("Allocation failure", filename); - res = false; - } - - return res; + resetLastError(); + + S32 file_size = 0; + LLAPRFile infile ; + infile.open(filename, LL_APR_RB, NULL, &file_size); + apr_file_t* apr_file = infile.getFileHandle(); + if (!apr_file) + { + setLastError("Unable to open file for reading", filename); + return false; + } + if (file_size == 0) + { + setLastError("File is empty",filename); + return false; + } + + // Constrain the load size to acceptable values + if ((load_size == 0) || (load_size > file_size)) + { + load_size = file_size; + } + bool res; + U8 *data = allocateData(load_size); + if (data) + { + apr_size_t bytes_read = load_size; + apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read + if (s != APR_SUCCESS || (S32) bytes_read != load_size) + { + deleteData(); + setLastError("Unable to read file",filename); + res = false; + } + else + { + res = updateData(); + } + } + else + { + setLastError("Allocation failure", filename); + res = false; + } + + return res; } bool LLImageFormatted::save(const std::string &filename) { - resetLastError(); - - LLAPRFile outfile ; - outfile.open(filename, LL_APR_WB); - if (!outfile.getFileHandle()) - { - setLastError("Unable to open file for writing", filename); - return false; - } - - S32 result = outfile.write(getData(), getDataSize()); - outfile.close() ; + resetLastError(); + + LLAPRFile outfile ; + outfile.open(filename, LL_APR_WB); + if (!outfile.getFileHandle()) + { + setLastError("Unable to open file for writing", filename); + return false; + } + + S32 result = outfile.write(getData(), getDataSize()); + outfile.close() ; return (result != 0); } S8 LLImageFormatted::getCodec() const { - return mCodec; + return mCodec; } static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst) { - dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); - dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); - dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2); - dst[3] = (U8)(((U32)(a[3]) + b[3] + c[3] + d[3])>>2); + dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); + dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); + dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2); + dst[3] = (U8)(((U32)(a[3]) + b[3] + c[3] + d[3])>>2); } static void avg4_colors3(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst) { - dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); - dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); - dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2); + dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); + dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); + dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2); } static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst) { - dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); - dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); + dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); + dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); } void LLImageBase::setDataAndSize(U8 *data, S32 size) -{ - ll_assert_aligned(data, 16); - mData = data; - mDataSize = size; -} +{ + ll_assert_aligned(data, 16); + mData = data; + mDataSize = size; +} //static void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels) { - llassert(width > 0 && height > 0); - U8* data = mipdata; - S32 in_width = width*2; - for (S32 h=0; h>2); - break; - default: - LL_ERRS() << "generateMmip called with bad num channels" << LL_ENDL; - } - indata += nchannels*2; - data += nchannels; - } - indata += nchannels*in_width; // skip odd lines - } + llassert(width > 0 && height > 0); + U8* data = mipdata; + S32 in_width = width*2; + for (S32 h=0; h>2); + break; + default: + LL_ERRS() << "generateMmip called with bad num channels" << LL_ENDL; + } + indata += nchannels*2; + data += nchannels; + } + indata += nchannels*in_width; // skip odd lines + } } @@ -2479,69 +2479,69 @@ void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 heig //static F32 LLImageBase::calc_download_priority(F32 virtual_size, F32 visible_pixels, S32 bytes_sent) { - F32 w_priority; - - F32 bytes_weight = 1.f; - if (!bytes_sent) - { - bytes_weight = 20.f; - } - else if (bytes_sent < 1000) - { - bytes_weight = 1.f; - } - else if (bytes_sent < 2000) - { - bytes_weight = 1.f/1.5f; - } - else if (bytes_sent < 4000) - { - bytes_weight = 1.f/3.f; - } - else if (bytes_sent < 8000) - { - bytes_weight = 1.f/6.f; - } - else if (bytes_sent < 16000) - { - bytes_weight = 1.f/12.f; - } - else if (bytes_sent < 32000) - { - bytes_weight = 1.f/20.f; - } - else if (bytes_sent < 64000) - { - bytes_weight = 1.f/32.f; - } - else - { - bytes_weight = 1.f/64.f; - } - bytes_weight *= bytes_weight; - - - //LL_INFOS() << "VS: " << virtual_size << LL_ENDL; - F32 virtual_size_factor = virtual_size / (10.f*10.f); - - // The goal is for weighted priority to be <= 0 when we've reached a point where - // we've sent enough data. - //LL_INFOS() << "BytesSent: " << bytes_sent << LL_ENDL; - //LL_INFOS() << "BytesWeight: " << bytes_weight << LL_ENDL; - //LL_INFOS() << "PreLog: " << bytes_weight * virtual_size_factor << LL_ENDL; - w_priority = (F32)log10(bytes_weight * virtual_size_factor); - - //LL_INFOS() << "PreScale: " << w_priority << LL_ENDL; - - // We don't want to affect how MANY bytes we send based on the visible pixels, but the order - // in which they're sent. We post-multiply so we don't change the zero point. - if (w_priority > 0.f) - { - F32 pixel_weight = (F32)log10(visible_pixels + 1)*3.0f; - w_priority *= pixel_weight; - } - - return w_priority; + F32 w_priority; + + F32 bytes_weight = 1.f; + if (!bytes_sent) + { + bytes_weight = 20.f; + } + else if (bytes_sent < 1000) + { + bytes_weight = 1.f; + } + else if (bytes_sent < 2000) + { + bytes_weight = 1.f/1.5f; + } + else if (bytes_sent < 4000) + { + bytes_weight = 1.f/3.f; + } + else if (bytes_sent < 8000) + { + bytes_weight = 1.f/6.f; + } + else if (bytes_sent < 16000) + { + bytes_weight = 1.f/12.f; + } + else if (bytes_sent < 32000) + { + bytes_weight = 1.f/20.f; + } + else if (bytes_sent < 64000) + { + bytes_weight = 1.f/32.f; + } + else + { + bytes_weight = 1.f/64.f; + } + bytes_weight *= bytes_weight; + + + //LL_INFOS() << "VS: " << virtual_size << LL_ENDL; + F32 virtual_size_factor = virtual_size / (10.f*10.f); + + // The goal is for weighted priority to be <= 0 when we've reached a point where + // we've sent enough data. + //LL_INFOS() << "BytesSent: " << bytes_sent << LL_ENDL; + //LL_INFOS() << "BytesWeight: " << bytes_weight << LL_ENDL; + //LL_INFOS() << "PreLog: " << bytes_weight * virtual_size_factor << LL_ENDL; + w_priority = (F32)log10(bytes_weight * virtual_size_factor); + + //LL_INFOS() << "PreScale: " << w_priority << LL_ENDL; + + // We don't want to affect how MANY bytes we send based on the visible pixels, but the order + // in which they're sent. We post-multiply so we don't change the zero point. + if (w_priority > 0.f) + { + F32 pixel_weight = (F32)log10(visible_pixels + 1)*3.0f; + w_priority *= pixel_weight; + } + + return w_priority; } //============================================================================ diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index c49184e338..a5f05d4380 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -1,25 +1,25 @@ -/** +/** * @file llimage.h * @brief Object for managing images and their textures. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,21 +35,21 @@ const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2 const S32 MAX_IMAGE_MIP = 12; // 4096x4096 -// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number +// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number // of levels is read from the header's file, not inferred from its size. const S32 MAX_DISCARD_LEVEL = 5; // JPEG2000 size constraints // Those are declared here as they are germane to other image constraints used in the viewer // and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL. -const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec -const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) -const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE -const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE -const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks -const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec -const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!! -const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit) +const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec +const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) +const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE +const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE +const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks +const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec +const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!! +const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit) const S32 MIN_IMAGE_SIZE = (1< scaled(S32 new_width, S32 new_height); - - // Fill the buffer with a constant color - void fill( const LLColor4U& color ); + + // Fill the buffer with a constant color + void fill( const LLColor4U& color ); // Multiply this raw image by the given color void tint( const LLColor3& color ); - // Copy operations - - //duplicate this raw image if refCount > 1. - LLPointer duplicate(); + // Copy operations + + //duplicate this raw image if refCount > 1. + LLPointer duplicate(); - // Src and dst can be any size. Src and dst can each have 3 or 4 components. - void copy( LLImageRaw* src ); + // Src and dst can be any size. Src and dst can each have 3 or 4 components. + void copy( LLImageRaw* src ); - // Src and dst are same size. Src and dst have same number of components. - void copyUnscaled( LLImageRaw* src ); - - // Src and dst are same size. Src has 4 components. Dst has 3 components. - void copyUnscaled4onto3( LLImageRaw* src ); + // Src and dst are same size. Src and dst have same number of components. + void copyUnscaled( LLImageRaw* src ); - // Src and dst are same size. Src has 3 components. Dst has 4 components. - void copyUnscaled3onto4( LLImageRaw* src ); + // Src and dst are same size. Src has 4 components. Dst has 3 components. + void copyUnscaled4onto3( LLImageRaw* src ); - // Src and dst are same size. Src has 1 component. Dst has 4 components. - // Alpha component is set to source alpha mask component. - // RGB components are set to fill color. - void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill); + // Src and dst are same size. Src has 3 components. Dst has 4 components. + void copyUnscaled3onto4( LLImageRaw* src ); - // Src and dst can be any size. Src and dst have same number of components. - void copyScaled( LLImageRaw* src ); + // Src and dst are same size. Src has 1 component. Dst has 4 components. + // Alpha component is set to source alpha mask component. + // RGB components are set to fill color. + void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill); - // Src and dst can be any size. Src has 3 components. Dst has 4 components. - void copyScaled3onto4( LLImageRaw* src ); + // Src and dst can be any size. Src and dst have same number of components. + void copyScaled( LLImageRaw* src ); - // Src and dst can be any size. Src has 4 components. Dst has 3 components. - void copyScaled4onto3( LLImageRaw* src ); + // Src and dst can be any size. Src has 3 components. Dst has 4 components. + void copyScaled3onto4( LLImageRaw* src ); + // Src and dst can be any size. Src has 4 components. Dst has 3 components. + void copyScaled4onto3( LLImageRaw* src ); - // Composite operations - // Src and dst can be any size. Src and dst can each have 3 or 4 components. - void composite( LLImageRaw* src ); + // Composite operations - // Src and dst can be any size. Src has 4 components. Dst has 3 components. - void compositeScaled4onto3( LLImageRaw* src ); + // Src and dst can be any size. Src and dst can each have 3 or 4 components. + void composite( LLImageRaw* src ); - // Src and dst are same size. Src has 4 components. Dst has 3 components. - void compositeUnscaled4onto3( LLImageRaw* src ); + // Src and dst can be any size. Src has 4 components. Dst has 3 components. + void compositeScaled4onto3( LLImageRaw* src ); + + // Src and dst are same size. Src has 4 components. Dst has 3 components. + void compositeUnscaled4onto3( LLImageRaw* src ); // Emissive operations used by minimap // Roughly emulates GLTF emissive texture, but is not GLTF-compliant @@ -283,21 +283,21 @@ public: void addEmissiveScaled(LLImageRaw* src); void addEmissiveUnscaled(LLImageRaw* src); protected: - // Create an image from a local file (generally used in tools) - //bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false); + // Create an image from a local file (generally used in tools) + //bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false); - void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ); - void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); + void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ); + void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); - U8 fastFractionalMult(U8 a,U8 b); + U8 fastFractionalMult(U8 a,U8 b); - void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; + void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; public: - static S32 sRawImageCount; + static S32 sRawImageCount; private: - bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); + bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); }; // Compressed representation of image. @@ -305,74 +305,74 @@ private: class LLImageFormatted : public LLImageBase { public: - static LLImageFormatted* createFromType(S8 codec); - static LLImageFormatted* createFromExtension(const std::string& instring); + static LLImageFormatted* createFromType(S8 codec); + static LLImageFormatted* createFromExtension(const std::string& instring); protected: - /*virtual*/ ~LLImageFormatted(); - + /*virtual*/ ~LLImageFormatted(); + public: - LLImageFormatted(S8 codec); - - // LLImageBase - /*virtual*/ void deleteData(); - /*virtual*/ U8* allocateData(S32 size = -1); - /*virtual*/ U8* reallocateData(S32 size); - - /*virtual*/ void dump(); - /*virtual*/ void sanityCheck(); - - // New methods - // subclasses must return a prefered file extension (lowercase without a leading dot) - virtual std::string getExtension() = 0; - // calcHeaderSize() returns the maximum size of header; - // 0 indicates we don't have a header and have to read the entire file - virtual S32 calcHeaderSize() { return 0; }; - // calcDataSize() returns how many bytes to read to load discard_level (including header) - virtual S32 calcDataSize(S32 discard_level); - // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes - virtual S32 calcDiscardLevelBytes(S32 bytes); - // getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C) - virtual S8 getRawDiscardLevel() { return mDiscardLevel; } - - bool load(const std::string& filename, int load_size = 0); - bool save(const std::string& filename); - - virtual bool updateData() = 0; // pure virtual - void setData(U8 *data, S32 size); - void appendData(U8 *data, S32 size); - - // Loads first 4 channels. - virtual bool decode(LLImageRaw* raw_image, F32 decode_time) = 0; - // Subclasses that can handle more than 4 channels should override this function. - virtual bool decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel); - - virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0; - - S8 getCodec() const; - bool isDecoding() const { return mDecoding; } - bool isDecoded() const { return mDecoded; } - void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; } - S8 getDiscardLevel() const { return mDiscardLevel; } - S8 getLevels() const { return mLevels; } - void setLevels(S8 nlevels) { mLevels = nlevels; } - - // setLastError needs to be deferred for J2C images since it may be called from a DLL - virtual void resetLastError(); - virtual void setLastError(const std::string& message, const std::string& filename = std::string()); - + LLImageFormatted(S8 codec); + + // LLImageBase + /*virtual*/ void deleteData(); + /*virtual*/ U8* allocateData(S32 size = -1); + /*virtual*/ U8* reallocateData(S32 size); + + /*virtual*/ void dump(); + /*virtual*/ void sanityCheck(); + + // New methods + // subclasses must return a prefered file extension (lowercase without a leading dot) + virtual std::string getExtension() = 0; + // calcHeaderSize() returns the maximum size of header; + // 0 indicates we don't have a header and have to read the entire file + virtual S32 calcHeaderSize() { return 0; }; + // calcDataSize() returns how many bytes to read to load discard_level (including header) + virtual S32 calcDataSize(S32 discard_level); + // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes + virtual S32 calcDiscardLevelBytes(S32 bytes); + // getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C) + virtual S8 getRawDiscardLevel() { return mDiscardLevel; } + + bool load(const std::string& filename, int load_size = 0); + bool save(const std::string& filename); + + virtual bool updateData() = 0; // pure virtual + void setData(U8 *data, S32 size); + void appendData(U8 *data, S32 size); + + // Loads first 4 channels. + virtual bool decode(LLImageRaw* raw_image, F32 decode_time) = 0; + // Subclasses that can handle more than 4 channels should override this function. + virtual bool decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel); + + virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0; + + S8 getCodec() const; + bool isDecoding() const { return mDecoding; } + bool isDecoded() const { return mDecoded; } + void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; } + S8 getDiscardLevel() const { return mDiscardLevel; } + S8 getLevels() const { return mLevels; } + void setLevels(S8 nlevels) { mLevels = nlevels; } + + // setLastError needs to be deferred for J2C images since it may be called from a DLL + virtual void resetLastError(); + virtual void setLastError(const std::string& message, const std::string& filename = std::string()); + protected: - bool copyData(U8 *data, S32 size); // calls updateData() - + bool copyData(U8 *data, S32 size); // calls updateData() + protected: - S8 mCodec; - S8 mDecoding; - S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC - S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc... - S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown. - + S8 mCodec; + S8 mDecoding; + S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC + S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc... + S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown. + public: - static S32 sGlobalFormattedMemory; + static S32 sGlobalFormattedMemory; }; #endif diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 6688dadd3a..1e332e0154 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -51,9 +51,9 @@ namespace { F32 cosPhi = cos(altitude); LLVector3 dir; - // +x right, +z up, +y at... + // +x right, +z up, +y at... dir.mV[0] = cosTheta * cosPhi; - dir.mV[1] = sinTheta * cosPhi; + dir.mV[1] = sinTheta * cosPhi; dir.mV[2] = sinPhi; LLVector3 axis = LLVector3::x_axis % dir; @@ -156,23 +156,23 @@ LLSettingsSky::validation_list_t legacyHazeValidationList() static LLSettingsBase::validation_list_t legacyHazeValidation; if (legacyHazeValidation.empty()) { - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f)))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f)))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 2.0f)))); legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 1000.0f)))); @@ -185,19 +185,19 @@ LLSettingsSky::validation_list_t rayleighValidationList() static LLSettingsBase::validation_list_t rayleighValidation; if (rayleighValidation.empty()) { - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return rayleighValidation; @@ -208,19 +208,19 @@ LLSettingsSky::validation_list_t absorptionValidationList() static LLSettingsBase::validation_list_t absorptionValidation; if (absorptionValidation.empty()) { - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return absorptionValidation; @@ -231,22 +231,22 @@ LLSettingsSky::validation_list_t mieValidationList() static LLSettingsBase::validation_list_t mieValidation; if (mieValidation.empty()) { - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return mieValidation; @@ -296,7 +296,7 @@ bool validateRayleighLayers(LLSD &value, U32 flags) } } return allGood; - } + } llassert(value.type() == LLSD::TypeMap); LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations, flags); if (result["errors"].size() > 0) @@ -317,7 +317,7 @@ bool validateAbsorptionLayers(LLSD &value, U32 flags) LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList(); if (value.isArray()) { - bool allGood = true; + bool allGood = true; for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf) { LLSD& layerConfig = (*itf); @@ -443,7 +443,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mNextHaloTextureId = pother->mNextHaloTextureId; } -void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; llassert(getSettingsType() == end->getSettingsType()); @@ -529,8 +529,8 @@ LLSettingsSky::stringset_t LLSettingsSky::getSkipInterpolateKeys() const return skipSet; } -LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const -{ +LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const +{ static stringset_t slepSet; if (slepSet.empty()) @@ -557,53 +557,53 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList() validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID)); validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 1.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 3.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 1.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.001f, 3.0f)))); - validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(-50.0f, -50.0f), llsd::array(50.0f, 50.0f)))); - validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 2000.0f)))); - validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f)))); - validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.2f, "*", -10.0f, "*"), llsd::array(40.0f, "*", 10.0f, "*")))); - - validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, + + validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 10000.0f)))); validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0))); validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 500.0f)))); - validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); @@ -612,25 +612,25 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList() boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0))); validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 0.1f)))); - validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(5.0f, 1000.0f)))); - validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal, @@ -720,7 +720,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position) sunquat = convert_azimuth_and_altitude_to_quat(altitude, azimuth); moonquat = convert_azimuth_and_altitude_to_quat(altitude + (F_PI * 0.125f), azimuth + (F_PI * 0.125f)); - // Magic constants copied form dfltsetting.xml + // Magic constants copied form dfltsetting.xml dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 0.0).getValue(); dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); @@ -733,7 +733,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position) dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f); dfltsetting[SETTING_GAMMA] = LLSD::Real(1.0); dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue(); - + dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605); dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue(); dfltsetting[SETTING_MOON_BRIGHTNESS] = LLSD::Real(0.5f); @@ -777,7 +777,7 @@ LLSD LLSettingsSky::translateLegacyHazeSettings(const LLSD& legacy) // AdvancedAtmospherics TODO // These need to be translated into density profile info in the new settings format... -// LEGACY_ATMOSPHERICS +// LEGACY_ATMOSPHERICS if (legacy.has(SETTING_AMBIENT)) { legacyhazesettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue(); @@ -867,7 +867,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy) newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal()); converted_something |= true; } - + if (legacy.has(SETTING_GAMMA)) { @@ -925,7 +925,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy) // get counter-clockwise radian angle from clockwise legacy WL east angle... F32 azimuth = -legacy[SETTING_LEGACY_EAST_ANGLE].asReal(); F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal(); - + LLQuaternion sunquat = convert_azimuth_and_altitude_to_quat(azimuth, altitude); // original WL moon dir was diametrically opposed to the sun dir LLQuaternion moonquat = convert_azimuth_and_altitude_to_quat(azimuth + F_PI, -altitude); @@ -1240,9 +1240,9 @@ LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in,const F32 &gamma) const } LLColor3 color = in * 2.0f; - color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors... - componentPow(color, gamma); - color = smear(1.f) - color; + color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors... + componentPow(color, gamma); + color = smear(1.f) - color; return color; } @@ -1352,7 +1352,7 @@ void LLSettingsSky::calculateLightSettings() const mSunAmbient = tmpAmbient; F32 haze_horizon = getHazeHorizon(); - + sunlight *= 1.0 - cloud_shadow; sunlight += tmpAmbient; @@ -1462,7 +1462,7 @@ F32 LLSettingsSky::getMieAnisotropy() const { return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal(); } - + LLSD LLSettingsSky::getRayleighConfig() const { LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray()); @@ -1480,7 +1480,7 @@ LLSD LLSettingsSky::getAbsorptionConfig() const LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray()); return copy; } - + LLSD LLSettingsSky::getRayleighConfigs() const { return mSettings[SETTING_RAYLEIGH_CONFIG]; @@ -1622,13 +1622,13 @@ void LLSettingsSky::setCloudVariance(F32 val) F32 LLSettingsSky::getDomeOffset() const { //return mSettings[SETTING_DOME_OFFSET].asReal(); - return DOME_OFFSET; + return DOME_OFFSET; } F32 LLSettingsSky::getDomeRadius() const { //return mSettings[SETTING_DOME_RADIUS].asReal(); - return DOME_RADIUS; + return DOME_RADIUS; } F32 LLSettingsSky::getGamma() const @@ -1657,7 +1657,7 @@ F32 LLSettingsSky::getMaxY() const return mSettings[SETTING_MAX_Y].asReal(); } -void LLSettingsSky::setMaxY(F32 val) +void LLSettingsSky::setMaxY(F32 val) { setValue(SETTING_MAX_Y, val); } @@ -1741,7 +1741,7 @@ LLQuaternion LLSettingsSky::getSunRotation() const return LLQuaternion(mSettings[SETTING_SUN_ROTATION]); } -void LLSettingsSky::setSunRotation(const LLQuaternion &val) +void LLSettingsSky::setSunRotation(const LLQuaternion &val) { setValue(SETTING_SUN_ROTATION, val); } @@ -1762,7 +1762,7 @@ LLUUID LLSettingsSky::getSunTextureId() const return mSettings[SETTING_SUN_TEXTUREID].asUUID(); } -void LLSettingsSky::setSunTextureId(LLUUID id) +void LLSettingsSky::setSunTextureId(LLUUID id) { setValue(SETTING_SUN_TEXTUREID, id); } @@ -1788,7 +1788,7 @@ LLUUID LLSettingsSky::getNextBloomTextureId() const } // if true, this sky is a candidate for auto-adjustment -bool LLSettingsSky::canAutoAdjust() const -{ +bool LLSettingsSky::canAutoAdjust() const +{ return !mSettings.has(SETTING_REFLECTION_PROBE_AMBIANCE); } diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index e1d3536f66..b6e0e4a2be 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -1,25 +1,25 @@ -/** +/** * @file llcamera.h * @brief Header file for the LLCamera class. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,26 +33,26 @@ #include "llplane.h" #include "llvector4a.h" -const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; -const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; -const F32 DEFAULT_NEAR_PLANE = 0.25f; -const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions +const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; +const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; +const F32 DEFAULT_NEAR_PLANE = 0.25f; +const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions -const F32 MAX_ASPECT_RATIO = 50.0f; -const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends -const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. -const F32 MAX_FAR_CLIP = 512.0f; +const F32 MAX_ASPECT_RATIO = 50.0f; +const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends +const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. +const F32 MAX_FAR_CLIP = 512.0f; -const F32 MIN_ASPECT_RATIO = 0.02f; -const F32 MIN_NEAR_PLANE = 0.1f; -const F32 MIN_FAR_PLANE = 0.2f; +const F32 MIN_ASPECT_RATIO = 0.02f; +const F32 MIN_NEAR_PLANE = 0.1f; +const F32 MIN_FAR_PLANE = 0.2f; // Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio. static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD; static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; // An LLCamera is an LLCoorFrame with a view frustum. -// This means that it has several methods for moving it around +// This means that it has several methods for moving it around // that are inherited from the LLCoordFrame() class : // // setOrigin(), setAxes() @@ -62,162 +62,162 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; LL_ALIGN_PREFIX(16) class LLCamera -: public LLCoordFrame +: public LLCoordFrame { public: - LLCamera(const LLCamera& rhs) - { - *this = rhs; - } - - enum { - PLANE_LEFT = 0, - PLANE_RIGHT = 1, - PLANE_BOTTOM = 2, - PLANE_TOP = 3, - PLANE_NUM = 4, - PLANE_MASK_NONE = 0xff // Disable this plane - }; - enum { - PLANE_LEFT_MASK = (1<size[i] + fAWdU[i]) return false; - } + for (U32 i = 0; i < 3; i++) + { + dir[i] = 0.5f * (end[i] - start[i]); + diff[i] = (0.5f * (end[i] + start[i])) - center[i]; + fAWdU[i] = fabsf(dir[i]); + if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; + } - float f; - f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false; - f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false; - f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false; - - return true; + float f; + f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false; + f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false; + f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false; + + return true; } // Finds tangent vec based on three vertices with texture coordinates. // Fills in dummy values if the triangle has degenerate texture coordinates. void calc_tangent_from_triangle( - LLVector4a& normal, - LLVector4a& tangent_out, - const LLVector4a& v1, - const LLVector2& w1, - const LLVector4a& v2, - const LLVector2& w2, - const LLVector4a& v3, - const LLVector2& w3) -{ - const F32* v1ptr = v1.getF32ptr(); - const F32* v2ptr = v2.getF32ptr(); - const F32* v3ptr = v3.getF32ptr(); + LLVector4a& normal, + LLVector4a& tangent_out, + const LLVector4a& v1, + const LLVector2& w1, + const LLVector4a& v2, + const LLVector2& w2, + const LLVector4a& v3, + const LLVector2& w3) +{ + const F32* v1ptr = v1.getF32ptr(); + const F32* v2ptr = v2.getF32ptr(); + const F32* v3ptr = v3.getF32ptr(); + + float x1 = v2ptr[0] - v1ptr[0]; + float x2 = v3ptr[0] - v1ptr[0]; + float y1 = v2ptr[1] - v1ptr[1]; + float y2 = v3ptr[1] - v1ptr[1]; + float z1 = v2ptr[2] - v1ptr[2]; + float z2 = v3ptr[2] - v1ptr[2]; + + float s1 = w2.mV[0] - w1.mV[0]; + float s2 = w3.mV[0] - w1.mV[0]; + float t1 = w2.mV[1] - w1.mV[1]; + float t2 = w3.mV[1] - w1.mV[1]; + + F32 rd = s1*t2-s2*t1; + + float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) + : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero + + llassert(llfinite(r)); + llassert(!llisnan(r)); + + LLVector4a sdir( + (t2 * x1 - t1 * x2) * r, + (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + + LLVector4a tdir( + (s1 * x2 - s2 * x1) * r, + (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + + LLVector4a n = normal; + LLVector4a t = sdir; + + LLVector4a ncrosst; + ncrosst.setCross3(n,t); + + // Gram-Schmidt orthogonalize + n.mul(n.dot3(t).getF32()); + + LLVector4a tsubn; + tsubn.setSub(t,n); + + if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) + { + tsubn.normalize3fast_checked(); - float x1 = v2ptr[0] - v1ptr[0]; - float x2 = v3ptr[0] - v1ptr[0]; - float y1 = v2ptr[1] - v1ptr[1]; - float y2 = v3ptr[1] - v1ptr[1]; - float z1 = v2ptr[2] - v1ptr[2]; - float z2 = v3ptr[2] - v1ptr[2]; + // Calculate handedness + F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; - float s1 = w2.mV[0] - w1.mV[0]; - float s2 = w3.mV[0] - w1.mV[0]; - float t1 = w2.mV[1] - w1.mV[1]; - float t2 = w3.mV[1] - w1.mV[1]; + tsubn.getF32ptr()[3] = handedness; - F32 rd = s1*t2-s2*t1; + tangent_out = tsubn; + } + else + { + // degenerate, make up a value + // + tangent_out.set(0,0,1,1); + } - float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) - : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero +} - llassert(llfinite(r)); - llassert(!llisnan(r)); - LLVector4a sdir( - (t2 * x1 - t1 * x2) * r, - (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); +// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. +// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, +// and returns the intersection point along dir in intersection_t. - LLVector4a tdir( - (s1 * x2 - s2 * x1) * r, - (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); +// Moller-Trumbore algorithm +BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, + F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ - LLVector4a n = normal; - LLVector4a t = sdir; + /* find vectors for two edges sharing vert0 */ + LLVector4a edge1; + edge1.setSub(vert1, vert0); - LLVector4a ncrosst; - ncrosst.setCross3(n,t); + LLVector4a edge2; + edge2.setSub(vert2, vert0); - // Gram-Schmidt orthogonalize - n.mul(n.dot3(t).getF32()); + /* begin calculating determinant - also used to calculate U parameter */ + LLVector4a pvec; + pvec.setCross3(dir, edge2); - LLVector4a tsubn; - tsubn.setSub(t,n); + /* if determinant is near zero, ray lies in plane of triangle */ + LLVector4a det; + det.setAllDot3(edge1, pvec); - if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) - { - tsubn.normalize3fast_checked(); + if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7) + { + /* calculate distance from vert0 to ray origin */ + LLVector4a tvec; + tvec.setSub(orig, vert0); - // Calculate handedness - F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; + /* calculate U parameter and test bounds */ + LLVector4a u; + u.setAllDot3(tvec,pvec); - tsubn.getF32ptr()[3] = handedness; + if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) && + (u.lessEqual(det).getGatheredBits() & 0x7)) + { + /* prepare to test V parameter */ + LLVector4a qvec; + qvec.setCross3(tvec, edge1); - tangent_out = tsubn; - } - else - { - // degenerate, make up a value - // - tangent_out.set(0,0,1,1); - } + /* calculate V parameter and test bounds */ + LLVector4a v; + v.setAllDot3(dir, qvec); -} + //if (!(v < 0.f || u + v > det)) -// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. -// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, -// and returns the intersection point along dir in intersection_t. + LLVector4a sum_uv; + sum_uv.setAdd(u, v); -// Moller-Trumbore algorithm -BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t) -{ - - /* find vectors for two edges sharing vert0 */ - LLVector4a edge1; - edge1.setSub(vert1, vert0); - - LLVector4a edge2; - edge2.setSub(vert2, vert0); - - /* begin calculating determinant - also used to calculate U parameter */ - LLVector4a pvec; - pvec.setCross3(dir, edge2); - - /* if determinant is near zero, ray lies in plane of triangle */ - LLVector4a det; - det.setAllDot3(edge1, pvec); - - if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7) - { - /* calculate distance from vert0 to ray origin */ - LLVector4a tvec; - tvec.setSub(orig, vert0); - - /* calculate U parameter and test bounds */ - LLVector4a u; - u.setAllDot3(tvec,pvec); - - if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) && - (u.lessEqual(det).getGatheredBits() & 0x7)) - { - /* prepare to test V parameter */ - LLVector4a qvec; - qvec.setCross3(tvec, edge1); - - /* calculate V parameter and test bounds */ - LLVector4a v; - v.setAllDot3(dir, qvec); - - - //if (!(v < 0.f || u + v > det)) - - LLVector4a sum_uv; - sum_uv.setAdd(u, v); - - S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7; - S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7; - - if (v_gequal && sum_lequal) - { - /* calculate t, scale parameters, ray intersects triangle */ - LLVector4a t; - t.setAllDot3(edge2,qvec); - - t.div(det); - u.div(det); - v.div(det); - - intersection_a = u[0]; - intersection_b = v[0]; - intersection_t = t[0]; - return TRUE; - } - } - } - - return FALSE; -} + S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7; + S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7; + + if (v_gequal && sum_lequal) + { + /* calculate t, scale parameters, ray intersects triangle */ + LLVector4a t; + t.setAllDot3(edge2,qvec); + + t.div(det); + u.div(det); + v.div(det); + + intersection_a = u[0]; + intersection_b = v[0]; + intersection_t = t[0]; + return TRUE; + } + } + } + + return FALSE; +} BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t) -{ - F32 u, v, t; - - /* find vectors for two edges sharing vert0 */ - LLVector4a edge1; - edge1.setSub(vert1, vert0); - - - LLVector4a edge2; - edge2.setSub(vert2, vert0); - - /* begin calculating determinant - also used to calculate U parameter */ - LLVector4a pvec; - pvec.setCross3(dir, edge2); - - /* if determinant is near zero, ray lies in plane of triangle */ - F32 det = edge1.dot3(pvec).getF32(); - - - if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) - { - return FALSE; - } - - F32 inv_det = 1.f / det; - - /* calculate distance from vert0 to ray origin */ - LLVector4a tvec; - tvec.setSub(orig, vert0); - - /* calculate U parameter and test bounds */ - u = (tvec.dot3(pvec).getF32()) * inv_det; - if (u < 0.f || u > 1.f) - { - return FALSE; - } - - /* prepare to test V parameter */ - tvec.sub(edge1); - - /* calculate V parameter and test bounds */ - v = (dir.dot3(tvec).getF32()) * inv_det; - - if (v < 0.f || u + v > 1.f) - { - return FALSE; - } - - /* calculate t, ray intersects triangle */ - t = (edge2.dot3(tvec).getF32()) * inv_det; - - intersection_a = u; - intersection_b = v; - intersection_t = t; - - - return TRUE; -} + F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ + F32 u, v, t; + + /* find vectors for two edges sharing vert0 */ + LLVector4a edge1; + edge1.setSub(vert1, vert0); + + + LLVector4a edge2; + edge2.setSub(vert2, vert0); + + /* begin calculating determinant - also used to calculate U parameter */ + LLVector4a pvec; + pvec.setCross3(dir, edge2); + + /* if determinant is near zero, ray lies in plane of triangle */ + F32 det = edge1.dot3(pvec).getF32(); + + + if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) + { + return FALSE; + } + + F32 inv_det = 1.f / det; + + /* calculate distance from vert0 to ray origin */ + LLVector4a tvec; + tvec.setSub(orig, vert0); + + /* calculate U parameter and test bounds */ + u = (tvec.dot3(pvec).getF32()) * inv_det; + if (u < 0.f || u > 1.f) + { + return FALSE; + } + + /* prepare to test V parameter */ + tvec.sub(edge1); + + /* calculate V parameter and test bounds */ + v = (dir.dot3(tvec).getF32()) * inv_det; + + if (v < 0.f || u + v > 1.f) + { + return FALSE; + } + + /* calculate t, ray intersects triangle */ + t = (edge2.dot3(tvec).getF32()) * inv_det; + + intersection_a = u; + intersection_b = v; + intersection_t = t; + + + return TRUE; +} //helper for non-aligned vectors BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) -{ - LLVector4a vert0a, vert1a, vert2a, origa, dira; - vert0a.load3(vert0.mV); - vert1a.load3(vert1.mV); - vert2a.load3(vert2.mV); - origa.load3(orig.mV); - dira.load3(dir.mV); - - if (two_sided) - { - return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira, - intersection_a, intersection_b, intersection_t); - } - else - { - return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, - intersection_a, intersection_b, intersection_t); - } + F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) +{ + LLVector4a vert0a, vert1a, vert2a, origa, dira; + vert0a.load3(vert0.mV); + vert1a.load3(vert1.mV); + vert2a.load3(vert2.mV); + origa.load3(orig.mV); + dira.load3(dir.mV); + + if (two_sided) + { + return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } + else + { + return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } } //------------------------------------------------------------------- @@ -385,5141 +385,5141 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons LLProfile::Face* LLProfile::addCap(S16 faceID) { - Face *face = vector_append(mFaces, 1); - - face->mIndex = 0; - face->mCount = mTotal; - face->mScaleU= 1.0f; - face->mCap = TRUE; - face->mFaceID = faceID; - return face; + Face *face = vector_append(mFaces, 1); + + face->mIndex = 0; + face->mCount = mTotal; + face->mScaleU= 1.0f; + face->mCap = TRUE; + face->mFaceID = faceID; + return face; } LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat) { - Face *face = vector_append(mFaces, 1); - - face->mIndex = i; - face->mCount = count; - face->mScaleU= scaleU; + Face *face = vector_append(mFaces, 1); - face->mFlat = flat; - face->mCap = FALSE; - face->mFaceID = faceID; - return face; + face->mIndex = i; + face->mCount = count; + face->mScaleU= scaleU; + + face->mFlat = flat; + face->mCap = FALSE; + face->mFaceID = faceID; + return face; } //static S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split) { // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points - S32 np = 0; - - // Generate an n-sided "circular" path. - // 0 is (1,0), and we go counter-clockwise along a circular path from there. - F32 t, t_step, t_first, t_fraction; - - F32 begin = params.getBegin(); - F32 end = params.getEnd(); - - t_step = 1.0f / sides; - - t_first = floor(begin * sides) / (F32)sides; - - // pt1 is the first point on the fractional face. - // Starting t and ang values for the first face - t = t_first; - - // Increment to the next point. - // pt2 is the end point on the fractional face - t += t_step; - - t_fraction = (begin - t_first)*sides; - - // Only use if it's not almost exactly on an edge. - if (t_fraction < 0.9999f) - { - np++; - } - - // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 - while (t < end) - { - // Iterate through all the integer steps of t. - np++; - - t += t_step; - } - - t_fraction = (end - (t - t_step))*sides; - - // Find the fraction that we need to add to the end point. - t_fraction = (end - (t - t_step))*sides; - if (t_fraction > 0.0001f) - { - np++; - } - - // If we're sliced, the profile is open. - if ((end - begin)*ang_scale < 0.99f) - { - if (params.getHollow() <= 0) - { - // put center point if not hollow. - np++; - } - } - - return np; -} - -// What is the bevel parameter used for? - DJS 04/05/02 -// Bevel parameter is currently unused but presumedly would support -// filleted and chamfered corners -void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split) -{ - // Generate an n-sided "circular" path. - // 0 is (1,0), and we go counter-clockwise along a circular path from there. - static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; - F32 scale = 0.5f; - F32 t, t_step, t_first, t_fraction, ang, ang_step; - LLVector4a pt1,pt2; - - F32 begin = params.getBegin(); - F32 end = params.getEnd(); - - t_step = 1.0f / sides; - ang_step = 2.0f*F_PI*t_step*ang_scale; - - // Scale to have size "match" scale. Compensates to get object to generally fill bounding box. - - S32 total_sides = ll_round(sides / ang_scale); // Total number of sides all around - - if (total_sides < 8) - { - scale = tableScale[total_sides]; - } - - t_first = floor(begin * sides) / (F32)sides; - - // pt1 is the first point on the fractional face. - // Starting t and ang values for the first face - t = t_first; - ang = 2.0f*F_PI*(t*ang_scale + offset); - pt1.set(cos(ang)*scale,sin(ang)*scale, t); - - // Increment to the next point. - // pt2 is the end point on the fractional face - t += t_step; - ang += ang_step; - pt2.set(cos(ang)*scale,sin(ang)*scale,t); - - t_fraction = (begin - t_first)*sides; - - // Only use if it's not almost exactly on an edge. - if (t_fraction < 0.9999f) - { - LLVector4a new_pt; - new_pt.setLerp(pt1, pt2, t_fraction); - mProfile.push_back(new_pt); - } - - // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 - while (t < end) - { - // Iterate through all the integer steps of t. - pt1.set(cos(ang)*scale,sin(ang)*scale,t); - - if (mProfile.size() > 0) { - LLVector4a p = mProfile[mProfile.size()-1]; - for (S32 i = 0; i < split && mProfile.size() > 0; i++) { - //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); - LLVector4a new_pt; - new_pt.setSub(pt1, p); - new_pt.mul(1.0f/(float)(split+1) * (float)(i+1)); - new_pt.add(p); - mProfile.push_back(new_pt); - } - } - mProfile.push_back(pt1); - - t += t_step; - ang += ang_step; - } - - t_fraction = (end - (t - t_step))*sides; - - // pt1 is the first point on the fractional face - // pt2 is the end point on the fractional face - pt2.set(cos(ang)*scale,sin(ang)*scale,t); - - // Find the fraction that we need to add to the end point. - t_fraction = (end - (t - t_step))*sides; - if (t_fraction > 0.0001f) - { - LLVector4a new_pt; - new_pt.setLerp(pt1, pt2, t_fraction); - - if (mProfile.size() > 0) { - LLVector4a p = mProfile[mProfile.size()-1]; - for (S32 i = 0; i < split && mProfile.size() > 0; i++) { - //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); - - LLVector4a pt1; - pt1.setSub(new_pt, p); - pt1.mul(1.0f/(float)(split+1) * (float)(i+1)); - pt1.add(p); - mProfile.push_back(pt1); - } - } - mProfile.push_back(new_pt); - } - - // If we're sliced, the profile is open. - if ((end - begin)*ang_scale < 0.99f) - { - if ((end - begin)*ang_scale > 0.5f) - { - mConcave = TRUE; - } - else - { - mConcave = FALSE; - } - mOpen = TRUE; - if (params.getHollow() <= 0) - { - // put center point if not hollow. - mProfile.push_back(LLVector4a(0,0,0)); - } - } - else - { - // The profile isn't open. - mOpen = FALSE; - mConcave = FALSE; - } - - mTotal = mProfile.size(); -} - -// Hollow is percent of the original bounding box, not of this particular -// profile's geometry. Thus, a swept triangle needs lower hollow values than -// a swept square. -LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split) -{ - // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them. + S32 np = 0; - // Total add has number of vertices on outside. - mTotalOut = mTotal; + // Generate an n-sided "circular" path. + // 0 is (1,0), and we go counter-clockwise along a circular path from there. + F32 t, t_step, t_first, t_fraction; - // Why is the "bevel" parameter -1? DJS 04/05/02 - genNGon(params, llfloor(sides),offset,-1, ang_scale, split); + F32 begin = params.getBegin(); + F32 end = params.getEnd(); - Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); + t_step = 1.0f / sides; - static thread_local LLAlignedArray pt; - pt.resize(mTotal) ; + t_first = floor(begin * sides) / (F32)sides; - for (S32 i=mTotalOut;i end - 0.01f) - { - LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL; - return FALSE; - } - - S32 face_num = 0; - - switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) - { - case LL_PCODE_PROFILE_SQUARE: - { - genNGon(params, 4,-0.375, 0, 1, split); - if (path_open) - { - addCap (LL_FACE_PATH_BEGIN); - } - - for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++) - { - addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); - } - - LLVector4a scale(1,1,4,1); - - for (i = 0; i <(S32) mProfile.size(); i++) - { - // Scale by 4 to generate proper tex coords. - mProfile[i].mul(scale); - llassert(mProfile[i].isFinite3()); - } - - if (hollow) - { - switch (params.getCurveType() & LL_PCODE_HOLE_MASK) - { - case LL_PCODE_HOLE_TRIANGLE: - // This offset is not correct, but we can't change it now... DK 11/17/04 - addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split); - break; - case LL_PCODE_HOLE_CIRCLE: - // TODO: Compute actual detail levels for cubes - addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f); - break; - case LL_PCODE_HOLE_SAME: - case LL_PCODE_HOLE_SQUARE: - default: - addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split); - break; - } - } - - if (path_open) { - mFaces[0].mCount = mTotal; - } - } - break; - case LL_PCODE_PROFILE_ISOTRI: - case LL_PCODE_PROFILE_RIGHTTRI: - case LL_PCODE_PROFILE_EQUALTRI: - { - genNGon(params, 3,0, 0, 1, split); - LLVector4a scale(1,1,3,1); - for (i = 0; i <(S32) mProfile.size(); i++) - { - // Scale by 3 to generate proper tex coords. - mProfile[i].mul(scale); - llassert(mProfile[i].isFinite3()); - } - - if (path_open) - { - addCap(LL_FACE_PATH_BEGIN); - } - - for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++) - { - addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); - } - if (hollow) - { - // Swept triangles need smaller hollowness values, - // because the triangle doesn't fill the bounding box. - F32 triangle_hollow = hollow / 2.f; - - switch (params.getCurveType() & LL_PCODE_HOLE_MASK) - { - case LL_PCODE_HOLE_CIRCLE: - // TODO: Actually generate level of detail for triangles - addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f); - break; - case LL_PCODE_HOLE_SQUARE: - addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split); - break; - case LL_PCODE_HOLE_SAME: - case LL_PCODE_HOLE_TRIANGLE: - default: - addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split); - break; - } - } - } - break; - case LL_PCODE_PROFILE_CIRCLE: - { - // If this has a square hollow, we should adjust the - // number of faces a bit so that the geometry lines up. - U8 hole_type=0; - F32 circle_detail = MIN_DETAIL_FACES * detail; - if (hollow) - { - hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; - if (hole_type == LL_PCODE_HOLE_SQUARE) - { - // Snap to the next multiple of four sides, - // so that corners line up. - circle_detail = llceil(circle_detail / 4.0f) * 4.0f; - } - } - - S32 sides = (S32)circle_detail; - - if (is_sculpted) - sides = sculpt_size; - - genNGon(params, sides); - - if (path_open) - { - addCap (LL_FACE_PATH_BEGIN); - } - - if (mOpen && !hollow) - { - addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); - } - else - { - addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); - } - - if (hollow) - { - switch (hole_type) - { - case LL_PCODE_HOLE_SQUARE: - addHole(params, TRUE, 4, 0, hollow, 1.f, split); - break; - case LL_PCODE_HOLE_TRIANGLE: - addHole(params, TRUE, 3, 0, hollow, 1.f, split); - break; - case LL_PCODE_HOLE_CIRCLE: - case LL_PCODE_HOLE_SAME: - default: - addHole(params, FALSE, circle_detail, 0, hollow, 1.f); - break; - } - } - } - break; - case LL_PCODE_PROFILE_CIRCLE_HALF: - { - // If this has a square hollow, we should adjust the - // number of faces a bit so that the geometry lines up. - U8 hole_type=0; - // Number of faces is cut in half because it's only a half-circle. - F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; - if (hollow) - { - hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; - if (hole_type == LL_PCODE_HOLE_SQUARE) - { - // Snap to the next multiple of four sides (div 2), - // so that corners line up. - circle_detail = llceil(circle_detail / 2.0f) * 2.0f; - } - } - genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); - if (path_open) - { - addCap(LL_FACE_PATH_BEGIN); - } - if (mOpen && !params.getHollow()) - { - addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); - } - else - { - addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); - } - - if (hollow) - { - switch (hole_type) - { - case LL_PCODE_HOLE_SQUARE: - addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split); - break; - case LL_PCODE_HOLE_TRIANGLE: - addHole(params, TRUE, 3, 0.5f, hollow, 0.5f, split); - break; - case LL_PCODE_HOLE_CIRCLE: - case LL_PCODE_HOLE_SAME: - default: - addHole(params, FALSE, circle_detail, 0.5f, hollow, 0.5f); - break; - } - } - - // Special case for openness of sphere - if ((params.getEnd() - params.getBegin()) < 1.f) - { - mOpen = TRUE; - } - else if (!hollow) - { - mOpen = FALSE; - mProfile.push_back(mProfile[0]); - mTotal++; - } - } - break; - default: - LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL; - break; - }; - - if (path_open) - { - addCap(LL_FACE_PATH_END); // bottom - } - - if ( mOpen) // interior edge caps - { - addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE); - - if (hollow) - { - addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE); - } - else - { - addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE); - } - } - - return TRUE; -} + t_fraction = (end - (t - t_step))*sides; + // Find the fraction that we need to add to the end point. + t_fraction = (end - (t - t_step))*sides; + if (t_fraction > 0.0001f) + { + np++; + } + // If we're sliced, the profile is open. + if ((end - begin)*ang_scale < 0.99f) + { + if (params.getHollow() <= 0) + { + // put center point if not hollow. + np++; + } + } -BOOL LLProfileParams::importFile(LLFILE *fp) -{ - const S32 BUFSIZE = 16384; - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - // *NOTE: changing the size or type of these buffers will require - // changing the sscanf below. - char keyword[256]; /* Flawfinder: ignore */ - char valuestr[256]; /* Flawfinder: ignore */ - keyword[0] = 0; - valuestr[0] = 0; - F32 tempF32; - U32 tempU32; - - while (!feof(fp)) - { - if (fgets(buffer, BUFSIZE, fp) == NULL) - { - buffer[0] = '\0'; - } - - sscanf( /* Flawfinder: ignore */ - buffer, - " %255s %255s", - keyword, valuestr); - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("curve", keyword)) - { - sscanf(valuestr,"%d",&tempU32); - setCurveType((U8) tempU32); - } - else if (!strcmp("begin",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setBegin(tempF32); - } - else if (!strcmp("end",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setEnd(tempF32); - } - else if (!strcmp("hollow",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setHollow(tempF32); - } - else - { - LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; - } - } - - return TRUE; + return np; } - -BOOL LLProfileParams::exportFile(LLFILE *fp) const +// What is the bevel parameter used for? - DJS 04/05/02 +// Bevel parameter is currently unused but presumedly would support +// filleted and chamfered corners +void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split) { - fprintf(fp,"\t\tprofile 0\n"); - fprintf(fp,"\t\t{\n"); - fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType()); - fprintf(fp,"\t\t\tbegin\t%g\n", getBegin()); - fprintf(fp,"\t\t\tend\t%g\n", getEnd()); - fprintf(fp,"\t\t\thollow\t%g\n", getHollow()); - fprintf(fp, "\t\t}\n"); - return TRUE; -} + // Generate an n-sided "circular" path. + // 0 is (1,0), and we go counter-clockwise along a circular path from there. + static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; + F32 scale = 0.5f; + F32 t, t_step, t_first, t_fraction, ang, ang_step; + LLVector4a pt1,pt2; + F32 begin = params.getBegin(); + F32 end = params.getEnd(); -BOOL LLProfileParams::importLegacyStream(std::istream& input_stream) -{ - const S32 BUFSIZE = 16384; - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - // *NOTE: changing the size or type of these buffers will require - // changing the sscanf below. - char keyword[256]; /* Flawfinder: ignore */ - char valuestr[256]; /* Flawfinder: ignore */ - keyword[0] = 0; - valuestr[0] = 0; - F32 tempF32; - U32 tempU32; - - while (input_stream.good()) - { - input_stream.getline(buffer, BUFSIZE); - sscanf( /* Flawfinder: ignore */ - buffer, - " %255s %255s", - keyword, - valuestr); - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("curve", keyword)) - { - sscanf(valuestr,"%d",&tempU32); - setCurveType((U8) tempU32); - } - else if (!strcmp("begin",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setBegin(tempF32); - } - else if (!strcmp("end",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setEnd(tempF32); - } - else if (!strcmp("hollow",keyword)) - { - sscanf(valuestr,"%g",&tempF32); - setHollow(tempF32); - } - else - { - LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; - } - } - - return TRUE; -} + t_step = 1.0f / sides; + ang_step = 2.0f*F_PI*t_step*ang_scale; + // Scale to have size "match" scale. Compensates to get object to generally fill bounding box. -BOOL LLProfileParams::exportLegacyStream(std::ostream& output_stream) const -{ - output_stream <<"\t\tprofile 0\n"; - output_stream <<"\t\t{\n"; - output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n"; - output_stream <<"\t\t\tbegin\t" << getBegin() << "\n"; - output_stream <<"\t\t\tend\t" << getEnd() << "\n"; - output_stream <<"\t\t\thollow\t" << getHollow() << "\n"; - output_stream << "\t\t}\n"; - return TRUE; -} + S32 total_sides = ll_round(sides / ang_scale); // Total number of sides all around -LLSD LLProfileParams::asLLSD() const -{ - LLSD sd; + if (total_sides < 8) + { + scale = tableScale[total_sides]; + } - sd["curve"] = getCurveType(); - sd["begin"] = getBegin(); - sd["end"] = getEnd(); - sd["hollow"] = getHollow(); - return sd; -} + t_first = floor(begin * sides) / (F32)sides; -bool LLProfileParams::fromLLSD(LLSD& sd) -{ - setCurveType(sd["curve"].asInteger()); - setBegin((F32)sd["begin"].asReal()); - setEnd((F32)sd["end"].asReal()); - setHollow((F32)sd["hollow"].asReal()); - return true; -} + // pt1 is the first point on the fractional face. + // Starting t and ang values for the first face + t = t_first; + ang = 2.0f*F_PI*(t*ang_scale + offset); + pt1.set(cos(ang)*scale,sin(ang)*scale, t); -void LLProfileParams::copyParams(const LLProfileParams ¶ms) -{ - setCurveType(params.getCurveType()); - setBegin(params.getBegin()); - setEnd(params.getEnd()); - setHollow(params.getHollow()); -} + // Increment to the next point. + // pt2 is the end point on the fractional face + t += t_step; + ang += ang_step; + pt2.set(cos(ang)*scale,sin(ang)*scale,t); + t_fraction = (begin - t_first)*sides; -LLPath::~LLPath() -{ -} + // Only use if it's not almost exactly on an edge. + if (t_fraction < 0.9999f) + { + LLVector4a new_pt; + new_pt.setLerp(pt1, pt2, t_fraction); + mProfile.push_back(new_pt); + } -S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) -{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added - S32 ret = 0; + // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 + while (t < end) + { + // Iterate through all the integer steps of t. + pt1.set(cos(ang)*scale,sin(ang)*scale,t); + + if (mProfile.size() > 0) { + LLVector4a p = mProfile[mProfile.size()-1]; + for (S32 i = 0; i < split && mProfile.size() > 0; i++) { + //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); + LLVector4a new_pt; + new_pt.setSub(pt1, p); + new_pt.mul(1.0f/(float)(split+1) * (float)(i+1)); + new_pt.add(p); + mProfile.push_back(new_pt); + } + } + mProfile.push_back(pt1); - F32 step= 1.0f / sides; - F32 t = params.getBegin(); - ret = 1; - - t+=step; + t += t_step; + ang += ang_step; + } - // Snap to a quantized parameter, so that cut does not - // affect most sample points. - t = ((S32)(t * sides)) / (F32)sides; + t_fraction = (end - (t - t_step))*sides; - // Run through the non-cut dependent points. - while (t < params.getEnd()) - { - ret++; - t+=step; - } + // pt1 is the first point on the fractional face + // pt2 is the end point on the fractional face + pt2.set(cos(ang)*scale,sin(ang)*scale,t); - ret++; + // Find the fraction that we need to add to the end point. + t_fraction = (end - (t - t_step))*sides; + if (t_fraction > 0.0001f) + { + LLVector4a new_pt; + new_pt.setLerp(pt1, pt2, t_fraction); + + if (mProfile.size() > 0) { + LLVector4a p = mProfile[mProfile.size()-1]; + for (S32 i = 0; i < split && mProfile.size() > 0; i++) { + //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); + + LLVector4a pt1; + pt1.setSub(new_pt, p); + pt1.mul(1.0f/(float)(split+1) * (float)(i+1)); + pt1.add(p); + mProfile.push_back(pt1); + } + } + mProfile.push_back(new_pt); + } - return ret; -} + // If we're sliced, the profile is open. + if ((end - begin)*ang_scale < 0.99f) + { + if ((end - begin)*ang_scale > 0.5f) + { + mConcave = TRUE; + } + else + { + mConcave = FALSE; + } + mOpen = TRUE; + if (params.getHollow() <= 0) + { + // put center point if not hollow. + mProfile.push_back(LLVector4a(0,0,0)); + } + } + else + { + // The profile isn't open. + mOpen = FALSE; + mConcave = FALSE; + } -void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - - // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. - static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; - - F32 revolutions = params.getRevolutions(); - F32 skew = params.getSkew(); - F32 skew_mag = fabs(skew); - F32 hole_x = params.getScaleX() * (1.0f - skew_mag); - F32 hole_y = params.getScaleY(); - - // Calculate taper begin/end for x,y (Negative means taper the beginning) - F32 taper_x_begin = 1.0f; - F32 taper_x_end = 1.0f - params.getTaperX(); - F32 taper_y_begin = 1.0f; - F32 taper_y_end = 1.0f - params.getTaperY(); - - if ( taper_x_end > 1.0f ) - { - // Flip tapering. - taper_x_begin = 2.0f - taper_x_end; - taper_x_end = 1.0f; - } - if ( taper_y_end > 1.0f ) - { - // Flip tapering. - taper_y_begin = 2.0f - taper_y_end; - taper_y_end = 1.0f; - } - - // For spheres, the radius is usually zero. - F32 radius_start = 0.5f; - if (sides < 8) - { - radius_start = tableScale[sides]; - } - - // Scale the radius to take the hole size into account. - radius_start *= 1.0f - hole_y; - - // Now check the radius offset to calculate the start,end radius. (Negative means - // decrease the start radius instead). - F32 radius_end = radius_start; - F32 radius_offset = params.getRadiusOffset(); - if (radius_offset < 0.f) - { - radius_start *= 1.f + radius_offset; - } - else - { - radius_end *= 1.f - radius_offset; - } - - // Is the path NOT a closed loop? - mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) || - (skew_mag > 0.001f) || - (fabs(taper_x_end - taper_x_begin) > 0.001f) || - (fabs(taper_y_end - taper_y_begin) > 0.001f) || - (fabs(radius_end - radius_start) > 0.001f) ); - - F32 ang, c, s; - LLQuaternion twist, qang; - PathPt *pt; - LLVector3 path_axis (1.f, 0.f, 0.f); - //LLVector3 twist_axis(0.f, 0.f, 1.f); - F32 twist_begin = params.getTwistBegin() * twist_scale; - F32 twist_end = params.getTwist() * twist_scale; - - // We run through this once before the main loop, to make sure - // the path begins at the correct cut. - F32 step= 1.0f / sides; - F32 t = params.getBegin(); - pt = mPath.append(1); - ang = 2.0f*F_PI*revolutions * t; - s = sin(ang)*lerp(radius_start, radius_end, t); - c = cos(ang)*lerp(radius_start, radius_end, t); - - - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) - + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), - s); - pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), - hole_y * lerp(taper_y_begin, taper_y_end, t), - 0,1); - pt->mTexT = t; - - // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 - twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); - // Rotate the point around the circle's center. - qang.setQuat (ang,path_axis); - - LLMatrix3 rot(twist * qang); - - pt->mRot.loadu(rot); - - t+=step; - - // Snap to a quantized parameter, so that cut does not - // affect most sample points. - t = ((S32)(t * sides)) / (F32)sides; - - // Run through the non-cut dependent points. - while (t < params.getEnd()) - { - pt = mPath.append(1); - - ang = 2.0f*F_PI*revolutions * t; - c = cos(ang)*lerp(radius_start, radius_end, t); - s = sin(ang)*lerp(radius_start, radius_end, t); - - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) - + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), - s); - - pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), - hole_y * lerp(taper_y_begin, taper_y_end, t), - 0,1); - pt->mTexT = t; - - // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 - twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); - // Rotate the point around the circle's center. - qang.setQuat (ang,path_axis); - LLMatrix3 tmp(twist*qang); - pt->mRot.loadu(tmp); - - t+=step; - } - - // Make one final pass for the end cut. - t = params.getEnd(); - pt = mPath.append(1); - ang = 2.0f*F_PI*revolutions * t; - c = cos(ang)*lerp(radius_start, radius_end, t); - s = sin(ang)*lerp(radius_start, radius_end, t); - - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) - + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), - s); - pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), - hole_y * lerp(taper_y_begin, taper_y_end, t), - 0,1); - pt->mTexT = t; - - // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 - twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); - // Rotate the point around the circle's center. - qang.setQuat (ang,path_axis); - LLMatrix3 tmp(twist*qang); - pt->mRot.loadu(tmp); - - mTotal = mPath.size(); + mTotal = mProfile.size(); } -const LLVector2 LLPathParams::getBeginScale() const +// Hollow is percent of the original bounding box, not of this particular +// profile's geometry. Thus, a swept triangle needs lower hollow values than +// a swept square. +LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split) { - LLVector2 begin_scale(1.f, 1.f); - if (getScaleX() > 1) - { - begin_scale.mV[0] = 2-getScaleX(); - } - if (getScaleY() > 1) - { - begin_scale.mV[1] = 2-getScaleY(); - } - return begin_scale; -} + // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them. -const LLVector2 LLPathParams::getEndScale() const -{ - LLVector2 end_scale(1.f, 1.f); - if (getScaleX() < 1) - { - end_scale.mV[0] = getScaleX(); - } - if (getScaleY() < 1) - { - end_scale.mV[1] = getScaleY(); - } - return end_scale; -} + // Total add has number of vertices on outside. + mTotalOut = mTotal; -S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) -{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points - if (detail < MIN_LOD) - { - detail = MIN_LOD; - } + // Why is the "bevel" parameter -1? DJS 04/05/02 + genNGon(params, llfloor(sides),offset,-1, ang_scale, split); - S32 np = 2; // hardcode for line + Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); - // Is this 0xf0 mask really necessary? DK 03/02/05 + static thread_local LLAlignedArray pt; + pt.resize(mTotal) ; - switch (params.getCurveType() & 0xf0) - { - default: - case LL_PCODE_PATH_LINE: - { - // Take the begin/end twist into account for detail. - np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; - } - break; + for (S32 i=mTotalOut;i= 0.99f && - params.getScaleX() >= .99f) - { - mOpen = FALSE; - } - - //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); - genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); - - F32 toggle = 0.5f; - for (S32 i=0;i<(S32)mPath.size();i++) - { - mPath[i].mPos.getF32ptr()[0] = toggle; - if (toggle == 0.5f) - toggle = -0.5f; - else - toggle = 0.5f; - } - } - - break; - - case LL_PCODE_PATH_TEST: - - np = 5; - mStep = 1.0f / (np-1); - - mPath.resize(np); - - for (S32 i=0;i end - 0.01f) + { + LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL; + return FALSE; + } -S32 LLVolume::sNumMeshPoints = 0; + S32 face_num = 0; -LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face, const BOOL is_unique) - : mParams(params) -{ - mUnique = is_unique; - mFaceMask = 0x0; - mDetail = detail; - mSculptLevel = -2; - mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims - mIsMeshAssetLoaded = false; - mIsMeshAssetUnavaliable = false; - mLODScaleBias.setVec(1,1,1); - mHullPoints = NULL; - mHullIndices = NULL; - mNumHullPoints = 0; - mNumHullIndices = 0; - - // set defaults - if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) - { - mPathp = new LLDynamicPath(); - } - else - { - mPathp = new LLPath(); - } - mProfilep = new LLProfile(); - - mGenerateSingleFace = generate_single_face; - - generate(); - - if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) - { - createVolumeFaces(); - } -} + switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) + { + case LL_PCODE_PROFILE_SQUARE: + { + genNGon(params, 4,-0.375, 0, 1, split); + if (path_open) + { + addCap (LL_FACE_PATH_BEGIN); + } -void LLVolume::resizePath(S32 length) -{ - mPathp->resizePath(length); - mVolumeFaces.clear(); - setDirty(); -} + for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++) + { + addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); + } -void LLVolume::regen() -{ - generate(); - createVolumeFaces(); -} + LLVector4a scale(1,1,4,1); -void LLVolume::genTangents(S32 face) -{ - // generate legacy tangents for the specified face - llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents - mVolumeFaces[face].createTangents(); -} + for (i = 0; i <(S32) mProfile.size(); i++) + { + // Scale by 4 to generate proper tex coords. + mProfile[i].mul(scale); + llassert(mProfile[i].isFinite3()); + } -LLVolume::~LLVolume() -{ - sNumMeshPoints -= mMesh.size(); - delete mPathp; + if (hollow) + { + switch (params.getCurveType() & LL_PCODE_HOLE_MASK) + { + case LL_PCODE_HOLE_TRIANGLE: + // This offset is not correct, but we can't change it now... DK 11/17/04 + addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split); + break; + case LL_PCODE_HOLE_CIRCLE: + // TODO: Compute actual detail levels for cubes + addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f); + break; + case LL_PCODE_HOLE_SAME: + case LL_PCODE_HOLE_SQUARE: + default: + addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split); + break; + } + } + + if (path_open) { + mFaces[0].mCount = mTotal; + } + } + break; + case LL_PCODE_PROFILE_ISOTRI: + case LL_PCODE_PROFILE_RIGHTTRI: + case LL_PCODE_PROFILE_EQUALTRI: + { + genNGon(params, 3,0, 0, 1, split); + LLVector4a scale(1,1,3,1); + for (i = 0; i <(S32) mProfile.size(); i++) + { + // Scale by 3 to generate proper tex coords. + mProfile[i].mul(scale); + llassert(mProfile[i].isFinite3()); + } - delete mProfilep; + if (path_open) + { + addCap(LL_FACE_PATH_BEGIN); + } - mPathp = NULL; - mProfilep = NULL; - mVolumeFaces.clear(); + for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++) + { + addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); + } + if (hollow) + { + // Swept triangles need smaller hollowness values, + // because the triangle doesn't fill the bounding box. + F32 triangle_hollow = hollow / 2.f; - ll_aligned_free_16(mHullPoints); - mHullPoints = NULL; - ll_aligned_free_16(mHullIndices); - mHullIndices = NULL; -} + switch (params.getCurveType() & LL_PCODE_HOLE_MASK) + { + case LL_PCODE_HOLE_CIRCLE: + // TODO: Actually generate level of detail for triangles + addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f); + break; + case LL_PCODE_HOLE_SQUARE: + addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split); + break; + case LL_PCODE_HOLE_SAME: + case LL_PCODE_HOLE_TRIANGLE: + default: + addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split); + break; + } + } + } + break; + case LL_PCODE_PROFILE_CIRCLE: + { + // If this has a square hollow, we should adjust the + // number of faces a bit so that the geometry lines up. + U8 hole_type=0; + F32 circle_detail = MIN_DETAIL_FACES * detail; + if (hollow) + { + hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; + if (hole_type == LL_PCODE_HOLE_SQUARE) + { + // Snap to the next multiple of four sides, + // so that corners line up. + circle_detail = llceil(circle_detail / 4.0f) * 4.0f; + } + } -BOOL LLVolume::generate() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - - LL_CHECK_MEMORY - llassert_always(mProfilep); - - //Added 10.03.05 Dave Parks - // Split is a parameter to LLProfile::generate that tesselates edges on the profile - // to prevent lighting and texture interpolation errors on triangles that are - // stretched due to twisting or scaling on the path. - S32 split = (S32) ((mDetail)*0.66f); - - if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE && - (mParams.getPathParams().getScale().mV[0] != 1.0f || - mParams.getPathParams().getScale().mV[1] != 1.0f) && - (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE || - mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI || - mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI || - mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI)) - { - split = 0; - } - - mLODScaleBias.setVec(0.5f, 0.5f, 0.5f); - - F32 profile_detail = mDetail; - F32 path_detail = mDetail; - - if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) - { - U8 path_type = mParams.getPathParams().getCurveType(); - U8 profile_type = mParams.getProfileParams().getCurveType(); - if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE) - { - //cylinders don't care about Z-Axis - mLODScaleBias.setVec(0.6f, 0.6f, 0.0f); - } - else if (path_type == LL_PCODE_PATH_CIRCLE) - { - mLODScaleBias.setVec(0.6f, 0.6f, 0.6f); - } - } - - BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split); - BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split); - - if (regenPath || regenProf ) - { - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); - - sNumMeshPoints -= mMesh.size(); - mMesh.resize(sizeT * sizeS); - sNumMeshPoints += mMesh.size(); - - //generate vertex positions - - // Run along the path. - LLVector4a* dst = mMesh.mArray; - - for (S32 s = 0; s < sizeS; ++s) - { - F32* scale = mPathp->mPath[s].mScale.getF32ptr(); - - F32 sc [] = - { scale[0], 0, 0, 0, - 0, scale[1], 0, 0, - 0, 0, scale[2], 0, - 0, 0, 0, 1 }; - - LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); - LLMatrix4 scale_mat(sc); - - scale_mat *= rot; - - LLMatrix4a rot_mat; - rot_mat.loadu(scale_mat); - - LLVector4a* profile = mProfilep->mProfile.mArray; - LLVector4a* end_profile = profile+sizeT; - LLVector4a offset = mPathp->mPath[s].mPos; + S32 sides = (S32)circle_detail; - // hack to work around MAINT-5660 for debug until we can suss out - // what is wrong with the path generated that inserts NaNs... - if (!offset.isFinite3()) + if (is_sculpted) + sides = sculpt_size; + + genNGon(params, sides); + + if (path_open) { - offset.clear(); + addCap (LL_FACE_PATH_BEGIN); + } + + if (mOpen && !hollow) + { + addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); + } + else + { + addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); + } + + if (hollow) + { + switch (hole_type) + { + case LL_PCODE_HOLE_SQUARE: + addHole(params, TRUE, 4, 0, hollow, 1.f, split); + break; + case LL_PCODE_HOLE_TRIANGLE: + addHole(params, TRUE, 3, 0, hollow, 1.f, split); + break; + case LL_PCODE_HOLE_CIRCLE: + case LL_PCODE_HOLE_SAME: + default: + addHole(params, FALSE, circle_detail, 0, hollow, 1.f); + break; + } + } + } + break; + case LL_PCODE_PROFILE_CIRCLE_HALF: + { + // If this has a square hollow, we should adjust the + // number of faces a bit so that the geometry lines up. + U8 hole_type=0; + // Number of faces is cut in half because it's only a half-circle. + F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; + if (hollow) + { + hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; + if (hole_type == LL_PCODE_HOLE_SQUARE) + { + // Snap to the next multiple of four sides (div 2), + // so that corners line up. + circle_detail = llceil(circle_detail / 2.0f) * 2.0f; + } + } + genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); + if (path_open) + { + addCap(LL_FACE_PATH_BEGIN); + } + if (mOpen && !params.getHollow()) + { + addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); + } + else + { + addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); } - LLVector4a tmp; + if (hollow) + { + switch (hole_type) + { + case LL_PCODE_HOLE_SQUARE: + addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split); + break; + case LL_PCODE_HOLE_TRIANGLE: + addHole(params, TRUE, 3, 0.5f, hollow, 0.5f, split); + break; + case LL_PCODE_HOLE_CIRCLE: + case LL_PCODE_HOLE_SAME: + default: + addHole(params, FALSE, circle_detail, 0.5f, hollow, 0.5f); + break; + } + } - // Run along the profile. - while (profile < end_profile) - { - rot_mat.rotate(*profile++, tmp); - dst->setAdd(tmp,offset); - ++dst; - } - } + // Special case for openness of sphere + if ((params.getEnd() - params.getBegin()) < 1.f) + { + mOpen = TRUE; + } + else if (!hollow) + { + mOpen = FALSE; + mProfile.push_back(mProfile[0]); + mTotal++; + } + } + break; + default: + LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL; + break; + }; - for (std::vector::iterator iter = mProfilep->mFaces.begin(); - iter != mProfilep->mFaces.end(); ++iter) - { - LLFaceID id = iter->mFaceID; - mFaceMask |= id; - } - LL_CHECK_MEMORY - return TRUE; - } + if (path_open) + { + addCap(LL_FACE_PATH_END); // bottom + } - LL_CHECK_MEMORY - return FALSE; -} + if ( mOpen) // interior edge caps + { + addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE); -void LLVolumeFace::VertexData::init() -{ - if (!mData) - { - mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2); - } -} + if (hollow) + { + addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE); + } + else + { + addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE); + } + } -LLVolumeFace::VertexData::VertexData() -{ - mData = NULL; - init(); + return TRUE; } - -LLVolumeFace::VertexData::VertexData(const VertexData& rhs) + + + +BOOL LLProfileParams::importFile(LLFILE *fp) { - mData = NULL; - *this = rhs; + const S32 BUFSIZE = 16384; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + // *NOTE: changing the size or type of these buffers will require + // changing the sscanf below. + char keyword[256]; /* Flawfinder: ignore */ + char valuestr[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + valuestr[0] = 0; + F32 tempF32; + U32 tempU32; + + while (!feof(fp)) + { + if (fgets(buffer, BUFSIZE, fp) == NULL) + { + buffer[0] = '\0'; + } + + sscanf( /* Flawfinder: ignore */ + buffer, + " %255s %255s", + keyword, valuestr); + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("curve", keyword)) + { + sscanf(valuestr,"%d",&tempU32); + setCurveType((U8) tempU32); + } + else if (!strcmp("begin",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setBegin(tempF32); + } + else if (!strcmp("end",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setEnd(tempF32); + } + else if (!strcmp("hollow",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setHollow(tempF32); + } + else + { + LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; + } + } + + return TRUE; } -const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolumeFace::VertexData& rhs) + +BOOL LLProfileParams::exportFile(LLFILE *fp) const { - if (this != &rhs) - { - init(); - LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a)); - mTexCoord = rhs.mTexCoord; - } - return *this; + fprintf(fp,"\t\tprofile 0\n"); + fprintf(fp,"\t\t{\n"); + fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType()); + fprintf(fp,"\t\t\tbegin\t%g\n", getBegin()); + fprintf(fp,"\t\t\tend\t%g\n", getEnd()); + fprintf(fp,"\t\t\thollow\t%g\n", getHollow()); + fprintf(fp, "\t\t}\n"); + return TRUE; } -LLVolumeFace::VertexData::~VertexData() + +BOOL LLProfileParams::importLegacyStream(std::istream& input_stream) { - ll_aligned_free_16(mData); - mData = NULL; + const S32 BUFSIZE = 16384; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + // *NOTE: changing the size or type of these buffers will require + // changing the sscanf below. + char keyword[256]; /* Flawfinder: ignore */ + char valuestr[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + valuestr[0] = 0; + F32 tempF32; + U32 tempU32; + + while (input_stream.good()) + { + input_stream.getline(buffer, BUFSIZE); + sscanf( /* Flawfinder: ignore */ + buffer, + " %255s %255s", + keyword, + valuestr); + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("curve", keyword)) + { + sscanf(valuestr,"%d",&tempU32); + setCurveType((U8) tempU32); + } + else if (!strcmp("begin",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setBegin(tempF32); + } + else if (!strcmp("end",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setEnd(tempF32); + } + else if (!strcmp("hollow",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setHollow(tempF32); + } + else + { + LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; + } + } + + return TRUE; } -LLVector4a& LLVolumeFace::VertexData::getPosition() + +BOOL LLProfileParams::exportLegacyStream(std::ostream& output_stream) const { - return mData[POSITION]; + output_stream <<"\t\tprofile 0\n"; + output_stream <<"\t\t{\n"; + output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n"; + output_stream <<"\t\t\tbegin\t" << getBegin() << "\n"; + output_stream <<"\t\t\tend\t" << getEnd() << "\n"; + output_stream <<"\t\t\thollow\t" << getHollow() << "\n"; + output_stream << "\t\t}\n"; + return TRUE; } -LLVector4a& LLVolumeFace::VertexData::getNormal() +LLSD LLProfileParams::asLLSD() const { - return mData[NORMAL]; + LLSD sd; + + sd["curve"] = getCurveType(); + sd["begin"] = getBegin(); + sd["end"] = getEnd(); + sd["hollow"] = getHollow(); + return sd; } -const LLVector4a& LLVolumeFace::VertexData::getPosition() const +bool LLProfileParams::fromLLSD(LLSD& sd) { - return mData[POSITION]; + setCurveType(sd["curve"].asInteger()); + setBegin((F32)sd["begin"].asReal()); + setEnd((F32)sd["end"].asReal()); + setHollow((F32)sd["hollow"].asReal()); + return true; } -const LLVector4a& LLVolumeFace::VertexData::getNormal() const +void LLProfileParams::copyParams(const LLProfileParams ¶ms) { - return mData[NORMAL]; + setCurveType(params.getCurveType()); + setBegin(params.getBegin()); + setEnd(params.getEnd()); + setHollow(params.getHollow()); } -void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos) +LLPath::~LLPath() { - mData[POSITION] = pos; } -void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) -{ - mData[NORMAL] = norm; +S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) +{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added + S32 ret = 0; + + F32 step= 1.0f / sides; + F32 t = params.getBegin(); + ret = 1; + + t+=step; + + // Snap to a quantized parameter, so that cut does not + // affect most sample points. + t = ((S32)(t * sides)) / (F32)sides; + + // Run through the non-cut dependent points. + while (t < params.getEnd()) + { + ret++; + t+=step; + } + + ret++; + + return ret; } -bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const +void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { - const F32* lp = this->getPosition().getF32ptr(); - const F32* rp = rhs.getPosition().getF32ptr(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - if (lp[0] != rp[0]) - { - return lp[0] < rp[0]; - } + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. + static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; + + F32 revolutions = params.getRevolutions(); + F32 skew = params.getSkew(); + F32 skew_mag = fabs(skew); + F32 hole_x = params.getScaleX() * (1.0f - skew_mag); + F32 hole_y = params.getScaleY(); + + // Calculate taper begin/end for x,y (Negative means taper the beginning) + F32 taper_x_begin = 1.0f; + F32 taper_x_end = 1.0f - params.getTaperX(); + F32 taper_y_begin = 1.0f; + F32 taper_y_end = 1.0f - params.getTaperY(); + + if ( taper_x_end > 1.0f ) + { + // Flip tapering. + taper_x_begin = 2.0f - taper_x_end; + taper_x_end = 1.0f; + } + if ( taper_y_end > 1.0f ) + { + // Flip tapering. + taper_y_begin = 2.0f - taper_y_end; + taper_y_end = 1.0f; + } - if (rp[1] != lp[1]) - { - return lp[1] < rp[1]; - } + // For spheres, the radius is usually zero. + F32 radius_start = 0.5f; + if (sides < 8) + { + radius_start = tableScale[sides]; + } - if (rp[2] != lp[2]) - { - return lp[2] < rp[2]; - } + // Scale the radius to take the hole size into account. + radius_start *= 1.0f - hole_y; - lp = getNormal().getF32ptr(); - rp = rhs.getNormal().getF32ptr(); + // Now check the radius offset to calculate the start,end radius. (Negative means + // decrease the start radius instead). + F32 radius_end = radius_start; + F32 radius_offset = params.getRadiusOffset(); + if (radius_offset < 0.f) + { + radius_start *= 1.f + radius_offset; + } + else + { + radius_end *= 1.f - radius_offset; + } - if (lp[0] != rp[0]) - { - return lp[0] < rp[0]; - } + // Is the path NOT a closed loop? + mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) || + (skew_mag > 0.001f) || + (fabs(taper_x_end - taper_x_begin) > 0.001f) || + (fabs(taper_y_end - taper_y_begin) > 0.001f) || + (fabs(radius_end - radius_start) > 0.001f) ); + + F32 ang, c, s; + LLQuaternion twist, qang; + PathPt *pt; + LLVector3 path_axis (1.f, 0.f, 0.f); + //LLVector3 twist_axis(0.f, 0.f, 1.f); + F32 twist_begin = params.getTwistBegin() * twist_scale; + F32 twist_end = params.getTwist() * twist_scale; + + // We run through this once before the main loop, to make sure + // the path begins at the correct cut. + F32 step= 1.0f / sides; + F32 t = params.getBegin(); + pt = mPath.append(1); + ang = 2.0f*F_PI*revolutions * t; + s = sin(ang)*lerp(radius_start, radius_end, t); + c = cos(ang)*lerp(radius_start, radius_end, t); + + + pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + + lerp(-skew ,skew, t) * 0.5f, + c + lerp(0,params.getShear().mV[1],s), + s); + pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), + hole_y * lerp(taper_y_begin, taper_y_end, t), + 0,1); + pt->mTexT = t; + + // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 + twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); + // Rotate the point around the circle's center. + qang.setQuat (ang,path_axis); + + LLMatrix3 rot(twist * qang); + + pt->mRot.loadu(rot); + + t+=step; + + // Snap to a quantized parameter, so that cut does not + // affect most sample points. + t = ((S32)(t * sides)) / (F32)sides; + + // Run through the non-cut dependent points. + while (t < params.getEnd()) + { + pt = mPath.append(1); + + ang = 2.0f*F_PI*revolutions * t; + c = cos(ang)*lerp(radius_start, radius_end, t); + s = sin(ang)*lerp(radius_start, radius_end, t); + + pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + + lerp(-skew ,skew, t) * 0.5f, + c + lerp(0,params.getShear().mV[1],s), + s); + + pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), + hole_y * lerp(taper_y_begin, taper_y_end, t), + 0,1); + pt->mTexT = t; + + // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 + twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); + // Rotate the point around the circle's center. + qang.setQuat (ang,path_axis); + LLMatrix3 tmp(twist*qang); + pt->mRot.loadu(tmp); + + t+=step; + } - if (rp[1] != lp[1]) - { - return lp[1] < rp[1]; - } + // Make one final pass for the end cut. + t = params.getEnd(); + pt = mPath.append(1); + ang = 2.0f*F_PI*revolutions * t; + c = cos(ang)*lerp(radius_start, radius_end, t); + s = sin(ang)*lerp(radius_start, radius_end, t); - if (rp[2] != lp[2]) - { - return lp[2] < rp[2]; - } + pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + + lerp(-skew ,skew, t) * 0.5f, + c + lerp(0,params.getShear().mV[1],s), + s); + pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), + hole_y * lerp(taper_y_begin, taper_y_end, t), + 0,1); + pt->mTexT = t; - if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0]) - { - return mTexCoord.mV[0] < rhs.mTexCoord.mV[0]; - } + // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 + twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); + // Rotate the point around the circle's center. + qang.setQuat (ang,path_axis); + LLMatrix3 tmp(twist*qang); + pt->mRot.loadu(tmp); - return mTexCoord.mV[1] < rhs.mTexCoord.mV[1]; + mTotal = mPath.size(); } -bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const +const LLVector2 LLPathParams::getBeginScale() const { - return mData[POSITION].equals3(rhs.getPosition()) && - mData[NORMAL].equals3(rhs.getNormal()) && - mTexCoord == rhs.mTexCoord; + LLVector2 begin_scale(1.f, 1.f); + if (getScaleX() > 1) + { + begin_scale.mV[0] = 2-getScaleX(); + } + if (getScaleY() > 1) + { + begin_scale.mV[1] = 2-getScaleY(); + } + return begin_scale; } -bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const +const LLVector2 LLPathParams::getEndScale() const { - bool retval = false; + LLVector2 end_scale(1.f, 1.f); + if (getScaleX() < 1) + { + end_scale.mV[0] = getScaleX(); + } + if (getScaleY() < 1) + { + end_scale.mV[1] = getScaleY(); + } + return end_scale; +} - const F32 epsilon = 0.00001f; +S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) +{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points + if (detail < MIN_LOD) + { + detail = MIN_LOD; + } - if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && - fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && - fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) - { - if (angle_cutoff > 1.f) - { - retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); - } - else - { - F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32(); - retval = cur_angle > angle_cutoff; - } - } + S32 np = 2; // hardcode for line - return retval; -} + // Is this 0xf0 mask really necessary? DK 03/02/05 -bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + switch (params.getCurveType() & 0xf0) + { + default: + case LL_PCODE_PATH_LINE: + { + // Take the begin/end twist into account for detail. + np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; + } + break; - //input stream is now pointing at a zlib compressed block of LLSD - //decompress block - LLSD mdl; - U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; - return false; - } - return unpackVolumeFacesInternal(mdl); -} + case LL_PCODE_PATH_CIRCLE: + { + // Increase the detail as the revolutions and twist increase. + F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); -bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) -{ - //input data is now pointing at a zlib compressed block of LLSD - //decompress block - LLSD mdl; - U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; - return false; - } - return unpackVolumeFacesInternal(mdl); + S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); + + np = sides; + } + break; + + case LL_PCODE_PATH_CIRCLE2: + { + //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); + np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail)); + } + break; + + case LL_PCODE_PATH_TEST: + + np = 5; + break; + }; + + return np; } -bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) +BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) { - { - U32 face_count = mdl.size(); - - if (face_count == 0) - { //no faces unpacked, treat as failed decode - LL_WARNS() << "found no faces!" << LL_ENDL; - return false; - } - - mVolumeFaces.resize(face_count); - - for (size_t i = 0; i < face_count; ++i) - { - LLVolumeFace& face = mVolumeFaces[i]; - - if (mdl[i].has("NoGeometry")) - { //face has no geometry, continue - face.resizeIndices(3); - face.resizeVertices(1); - face.mPositions->clear(); - face.mNormals->clear(); - face.mTexCoords->setZero(); - memset(face.mIndices, 0, sizeof(U16)*3); - continue; - } - - LLSD::Binary pos = mdl[i]["Position"]; - LLSD::Binary norm = mdl[i]["Normal"]; - LLSD::Binary tangent = mdl[i]["Tangent"]; - LLSD::Binary tc = mdl[i]["TexCoord0"]; - LLSD::Binary idx = mdl[i]["TriangleList"]; + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - //copy out indices - S32 num_indices = idx.size() / 2; - const S32 indices_to_discard = num_indices % 3; - if (indices_to_discard > 0) - { - // Invalid number of triangle indices - LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; - num_indices -= indices_to_discard; - } - face.resizeIndices(num_indices); + if ((!mDirty) && (!is_sculpted)) + { + return FALSE; + } - if (num_indices > 2 && !face.mIndices) + if (detail < MIN_LOD) + { + LL_INFOS() << "Generating path with LOD < MIN! Clamping to 1" << LL_ENDL; + detail = MIN_LOD; + } + + mDirty = FALSE; + S32 np = 2; // hardcode for line + + mPath.resize(0); + mOpen = TRUE; + + // Is this 0xf0 mask really necessary? DK 03/02/05 + switch (params.getCurveType() & 0xf0) + { + default: + case LL_PCODE_PATH_LINE: + { + // Take the begin/end twist into account for detail. + np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; + if (np < split+2) { - LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL; - continue; + np = split+2; } - - if (idx.empty() || face.mNumIndices < 3) - { //why is there an empty index list? - LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL; - continue; - } - - U16* indices = (U16*) &(idx[0]); - for (U32 j = 0; j < num_indices; ++j) - { - face.mIndices[j] = indices[j]; - } - //copy out vertices - U32 num_verts = pos.size()/(3*2); - face.resizeVertices(num_verts); + mStep = 1.0f / (np-1); - if (num_verts > 0 && !face.mPositions) + mPath.resize(np); + + LLVector2 start_scale = params.getBeginScale(); + LLVector2 end_scale = params.getEndScale(); + + for (S32 i=0;iset((F32) v[0], (F32) v[1], (F32) v[2]); - pos_out->div(65535.f); - pos_out->mul(pos_range); - pos_out->add(min_pos); - pos_out++; - v += 3; - } - - } - - { - if (!norm.empty()) - { - U16* n = (U16*) &(norm[0]); - for (U32 j = 0; j < num_verts; ++j) - { - norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); - norm_out->div(65535.f); - norm_out->mul(2.f); - norm_out->sub(1.f); - norm_out++; - n += 3; - } - } - else - { - for (U32 j = 0; j < num_verts; ++j) - { - norm_out->clear(); - norm_out++; // or just norm_out[j].clear(); - } - } - } + if (is_sculpted) + sides = llmax(sculpt_size, 1); -#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents + if (0 < sides) + genNGon(params, sides); + } + break; + + case LL_PCODE_PATH_CIRCLE2: + { + if (params.getEnd() - params.getBegin() >= 0.99f && + params.getScaleX() >= .99f) { - if (!tangent.empty()) - { - face.allocateTangents(face.mNumVertices); - U16* t = (U16*)&(tangent[0]); + mOpen = FALSE; + } - // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to - // maintain compliance with the GLTF spec - LLVector4a* t_out = face.mTangents; + //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); + genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); - for (U32 j = 0; j < num_verts; ++j) - { - t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]); - t_out->div(65535.f); - t_out->mul(2.f); - t_out->sub(1.f); + F32 toggle = 0.5f; + for (S32 i=0;i<(S32)mPath.size();i++) + { + mPath[i].mPos.getF32ptr()[0] = toggle; + if (toggle == 0.5f) + toggle = -0.5f; + else + toggle = 0.5f; + } + } - F32* tp = t_out->getF32ptr(); - tp[3] = tp[3] < 0.f ? -1.f : 1.f; + break; - t_out++; - t += 4; - } - } - } -#endif + case LL_PCODE_PATH_TEST: - { - if (!tc.empty()) - { - U16* t = (U16*) &(tc[0]); - for (U32 j = 0; j < num_verts; j+=2) - { - if (j < num_verts-1) - { - tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); - } - else - { - tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); - } - - t += 4; - - tc_out->div(65535.f); - tc_out->mul(tc_range); - tc_out->add(min_tc4); - - tc_out++; - } - } - else - { - for (U32 j = 0; j < num_verts; j += 2) - { - tc_out->clear(); - tc_out++; - } - } - } - - if (mdl[i].has("Weights")) - { - face.allocateWeights(num_verts); - if (!face.mWeights && num_verts) - { - LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL; - face.resizeIndices(0); - face.resizeVertices(0); - continue; - } + np = 5; + mStep = 1.0f / (np-1); - LLSD::Binary weights = mdl[i]["Weights"]; + mPath.resize(np); - U32 idx = 0; + for (S32 i=0;i= 4) - { - joint = END_INFLUENCES; - } - else - { - joint = weights[idx++]; - } - } - F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; - if (wsum <= 0.f) - { - wght = LLVector4(0.999f,0.f,0.f,0.f); - } - for (U32 k=0; k<4; k++) - { - F32 f_combined = (F32) joints[k] + wght[k]; - joints_with_weights[k] = f_combined; - // Any weights we added above should wind up non-zero and applied to a specific bone. - // A failure here would indicate a floating point precision error in the math. - llassert((k >= cur_influence) || (f_combined - S32(f_combined) > 0.0f)); - } - face.mWeights[cur_vertex].loadua(joints_with_weights.mV); - - cur_vertex++; - } - - if (cur_vertex != num_verts || idx != weights.size()) - { - LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL; - } - - } - - // modifier flags? - bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); - bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); - - - // translate to actions: - bool do_reflect_x = false; - bool do_reverse_triangles = false; - bool do_invert_normals = false; - - if (do_mirror) - { - do_reflect_x = true; - do_reverse_triangles = !do_reverse_triangles; - } - - if (do_invert) - { - do_invert_normals = true; - do_reverse_triangles = !do_reverse_triangles; - } - - // now do the work - - if (do_reflect_x) - { - LLVector4a* p = (LLVector4a*) face.mPositions; - LLVector4a* n = (LLVector4a*) face.mNormals; - - for (S32 i = 0; i < face.mNumVertices; i++) - { - p[i].mul(-1.0f); - n[i].mul(-1.0f); - } - } - - if (do_invert_normals) - { - LLVector4a* n = (LLVector4a*) face.mNormals; - - for (S32 i = 0; i < face.mNumVertices; i++) - { - n[i].mul(-1.0f); - } - } - - if (do_reverse_triangles) - { - for (U32 j = 0; j < face.mNumIndices; j += 3) - { - // swap the 2nd and 3rd index - S32 swap = face.mIndices[j+1]; - face.mIndices[j+1] = face.mIndices[j+2]; - face.mIndices[j+2] = swap; - } - } - - //calculate bounding box - // VFExtents change - LLVector4a& min = face.mExtents[0]; - LLVector4a& max = face.mExtents[1]; - - if (face.mNumVertices < 3) - { //empty face, use a dummy 1cm (at 1m scale) bounding box - min.splat(-0.005f); - max.splat(0.005f); - } - else - { - min = max = face.mPositions[0]; - - for (S32 i = 1; i < face.mNumVertices; ++i) - { - min.setMin(min, face.mPositions[i]); - max.setMax(max, face.mPositions[i]); - } - - if (face.mTexCoords) - { - LLVector2& min_tc = face.mTexCoordExtents[0]; - LLVector2& max_tc = face.mTexCoordExtents[1]; - - min_tc = face.mTexCoords[0]; - max_tc = face.mTexCoords[0]; - - for (U32 j = 1; j < face.mNumVertices; ++j) - { - update_min_max(min_tc, max_tc, face.mTexCoords[j]); - } - } - else - { - face.mTexCoordExtents[0].set(0,0); - face.mTexCoordExtents[1].set(1,1); - } - } - } - } - - if (!cacheOptimize(true)) - { - // Out of memory? - LL_WARNS() << "Failed to optimize!" << LL_ENDL; - mVolumeFaces.clear(); - return false; - } - - mSculptLevel = 0; // success! - - return true; -} + if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE; + //if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) { + // mOpen = TRUE; + //} -bool LLVolume::isMeshAssetLoaded() -{ - return mIsMeshAssetLoaded; + return TRUE; } -void LLVolume::setMeshAssetLoaded(bool loaded) +BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) { - mIsMeshAssetLoaded = loaded; - if (loaded) + mOpen = TRUE; // Draw end caps + if (getPathLength() == 0) { - mIsMeshAssetUnavaliable = false; + // Path hasn't been generated yet. + // Some algorithms later assume at least TWO path points. + resizePath(2); + LLQuaternion quat; + quat.setQuat(0,0,0); + LLMatrix3 tmp(quat); + + for (U32 i = 0; i < 2; i++) + { + mPath[i].mPos.set(0, 0, 0); + mPath[i].mRot.loadu(tmp); + mPath[i].mScale.set(1, 1, 0, 1); + mPath[i].mTexT = 0; + } } + + return TRUE; } -void LLVolume::setMeshAssetUnavaliable(bool unavaliable) + +BOOL LLPathParams::importFile(LLFILE *fp) { - // Don't set it if at least one lod loaded - if (!mIsMeshAssetLoaded) + const S32 BUFSIZE = 16384; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + // *NOTE: changing the size or type of these buffers will require + // changing the sscanf below. + char keyword[256]; /* Flawfinder: ignore */ + char valuestr[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + valuestr[0] = 0; + + F32 tempF32; + F32 x, y; + U32 tempU32; + + while (!feof(fp)) { - mIsMeshAssetUnavaliable = unavaliable; + if (fgets(buffer, BUFSIZE, fp) == NULL) + { + buffer[0] = '\0'; + } + + sscanf( /* Flawfinder: ignore */ + buffer, + " %255s %255s", + keyword, valuestr); + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("curve", keyword)) + { + sscanf(valuestr,"%d",&tempU32); + setCurveType((U8) tempU32); + } + else if (!strcmp("begin",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setBegin(tempF32); + } + else if (!strcmp("end",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setEnd(tempF32); + } + else if (!strcmp("scale",keyword)) + { + // Legacy for one dimensional scale per path + sscanf(valuestr,"%g",&tempF32); + setScale(tempF32, tempF32); + } + else if (!strcmp("scale_x", keyword)) + { + sscanf(valuestr, "%g", &x); + setScaleX(x); + } + else if (!strcmp("scale_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setScaleY(y); + } + else if (!strcmp("shear_x", keyword)) + { + sscanf(valuestr, "%g", &x); + setShearX(x); + } + else if (!strcmp("shear_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setShearY(y); + } + else if (!strcmp("twist",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setTwist(tempF32); + } + else if (!strcmp("twist_begin", keyword)) + { + sscanf(valuestr, "%g", &y); + setTwistBegin(y); + } + else if (!strcmp("radius_offset", keyword)) + { + sscanf(valuestr, "%g", &y); + setRadiusOffset(y); + } + else if (!strcmp("taper_x", keyword)) + { + sscanf(valuestr, "%g", &y); + setTaperX(y); + } + else if (!strcmp("taper_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setTaperY(y); + } + else if (!strcmp("revolutions", keyword)) + { + sscanf(valuestr, "%g", &y); + setRevolutions(y); + } + else if (!strcmp("skew", keyword)) + { + sscanf(valuestr, "%g", &y); + setSkew(y); + } + else + { + LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; + } } + return TRUE; } -bool LLVolume::isMeshAssetUnavaliable() + +BOOL LLPathParams::exportFile(LLFILE *fp) const { - return mIsMeshAssetUnavaliable; + fprintf(fp, "\t\tpath 0\n"); + fprintf(fp, "\t\t{\n"); + fprintf(fp, "\t\t\tcurve\t%d\n", getCurveType()); + fprintf(fp, "\t\t\tbegin\t%g\n", getBegin()); + fprintf(fp, "\t\t\tend\t%g\n", getEnd()); + fprintf(fp, "\t\t\tscale_x\t%g\n", getScaleX() ); + fprintf(fp, "\t\t\tscale_y\t%g\n", getScaleY() ); + fprintf(fp, "\t\t\tshear_x\t%g\n", getShearX() ); + fprintf(fp, "\t\t\tshear_y\t%g\n", getShearY() ); + fprintf(fp,"\t\t\ttwist\t%g\n", getTwist()); + + fprintf(fp,"\t\t\ttwist_begin\t%g\n", getTwistBegin()); + fprintf(fp,"\t\t\tradius_offset\t%g\n", getRadiusOffset()); + fprintf(fp,"\t\t\ttaper_x\t%g\n", getTaperX()); + fprintf(fp,"\t\t\ttaper_y\t%g\n", getTaperY()); + fprintf(fp,"\t\t\trevolutions\t%g\n", getRevolutions()); + fprintf(fp,"\t\t\tskew\t%g\n", getSkew()); + + fprintf(fp, "\t\t}\n"); + return TRUE; } -void LLVolume::copyFacesTo(std::vector &faces) const + +BOOL LLPathParams::importLegacyStream(std::istream& input_stream) { - faces = mVolumeFaces; + const S32 BUFSIZE = 16384; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + // *NOTE: changing the size or type of these buffers will require + // changing the sscanf below. + char keyword[256]; /* Flawfinder: ignore */ + char valuestr[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + valuestr[0] = 0; + + F32 tempF32; + F32 x, y; + U32 tempU32; + + while (input_stream.good()) + { + input_stream.getline(buffer, BUFSIZE); + sscanf( /* Flawfinder: ignore */ + buffer, + " %255s %255s", + keyword, valuestr); + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("curve", keyword)) + { + sscanf(valuestr,"%d",&tempU32); + setCurveType((U8) tempU32); + } + else if (!strcmp("begin",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setBegin(tempF32); + } + else if (!strcmp("end",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setEnd(tempF32); + } + else if (!strcmp("scale",keyword)) + { + // Legacy for one dimensional scale per path + sscanf(valuestr,"%g",&tempF32); + setScale(tempF32, tempF32); + } + else if (!strcmp("scale_x", keyword)) + { + sscanf(valuestr, "%g", &x); + setScaleX(x); + } + else if (!strcmp("scale_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setScaleY(y); + } + else if (!strcmp("shear_x", keyword)) + { + sscanf(valuestr, "%g", &x); + setShearX(x); + } + else if (!strcmp("shear_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setShearY(y); + } + else if (!strcmp("twist",keyword)) + { + sscanf(valuestr,"%g",&tempF32); + setTwist(tempF32); + } + else if (!strcmp("twist_begin", keyword)) + { + sscanf(valuestr, "%g", &y); + setTwistBegin(y); + } + else if (!strcmp("radius_offset", keyword)) + { + sscanf(valuestr, "%g", &y); + setRadiusOffset(y); + } + else if (!strcmp("taper_x", keyword)) + { + sscanf(valuestr, "%g", &y); + setTaperX(y); + } + else if (!strcmp("taper_y", keyword)) + { + sscanf(valuestr, "%g", &y); + setTaperY(y); + } + else if (!strcmp("revolutions", keyword)) + { + sscanf(valuestr, "%g", &y); + setRevolutions(y); + } + else if (!strcmp("skew", keyword)) + { + sscanf(valuestr, "%g", &y); + setSkew(y); + } + else + { + LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; + } + } + return TRUE; } -void LLVolume::copyFacesFrom(const std::vector &faces) + +BOOL LLPathParams::exportLegacyStream(std::ostream& output_stream) const { - mVolumeFaces = faces; - mSculptLevel = 0; + output_stream << "\t\tpath 0\n"; + output_stream << "\t\t{\n"; + output_stream << "\t\t\tcurve\t" << (S32) getCurveType() << "\n"; + output_stream << "\t\t\tbegin\t" << getBegin() << "\n"; + output_stream << "\t\t\tend\t" << getEnd() << "\n"; + output_stream << "\t\t\tscale_x\t" << getScaleX() << "\n"; + output_stream << "\t\t\tscale_y\t" << getScaleY() << "\n"; + output_stream << "\t\t\tshear_x\t" << getShearX() << "\n"; + output_stream << "\t\t\tshear_y\t" << getShearY() << "\n"; + output_stream <<"\t\t\ttwist\t" << getTwist() << "\n"; + + output_stream <<"\t\t\ttwist_begin\t" << getTwistBegin() << "\n"; + output_stream <<"\t\t\tradius_offset\t" << getRadiusOffset() << "\n"; + output_stream <<"\t\t\ttaper_x\t" << getTaperX() << "\n"; + output_stream <<"\t\t\ttaper_y\t" << getTaperY() << "\n"; + output_stream <<"\t\t\trevolutions\t" << getRevolutions() << "\n"; + output_stream <<"\t\t\tskew\t" << getSkew() << "\n"; + + output_stream << "\t\t}\n"; + return TRUE; } -void LLVolume::copyVolumeFaces(const LLVolume* volume) +LLSD LLPathParams::asLLSD() const { - mVolumeFaces = volume->mVolumeFaces; - mSculptLevel = 0; + LLSD sd = LLSD(); + sd["curve"] = getCurveType(); + sd["begin"] = getBegin(); + sd["end"] = getEnd(); + sd["scale_x"] = getScaleX(); + sd["scale_y"] = getScaleY(); + sd["shear_x"] = getShearX(); + sd["shear_y"] = getShearY(); + sd["twist"] = getTwist(); + sd["twist_begin"] = getTwistBegin(); + sd["radius_offset"] = getRadiusOffset(); + sd["taper_x"] = getTaperX(); + sd["taper_y"] = getTaperY(); + sd["revolutions"] = getRevolutions(); + sd["skew"] = getSkew(); + + return sd; } -bool LLVolume::cacheOptimize(bool gen_tangents) +bool LLPathParams::fromLLSD(LLSD& sd) { - for (S32 i = 0; i < mVolumeFaces.size(); ++i) - { - if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) - { - return false; - } - } - return true; + setCurveType(sd["curve"].asInteger()); + setBegin((F32)sd["begin"].asReal()); + setEnd((F32)sd["end"].asReal()); + setScaleX((F32)sd["scale_x"].asReal()); + setScaleY((F32)sd["scale_y"].asReal()); + setShearX((F32)sd["shear_x"].asReal()); + setShearY((F32)sd["shear_y"].asReal()); + setTwist((F32)sd["twist"].asReal()); + setTwistBegin((F32)sd["twist_begin"].asReal()); + setRadiusOffset((F32)sd["radius_offset"].asReal()); + setTaperX((F32)sd["taper_x"].asReal()); + setTaperY((F32)sd["taper_y"].asReal()); + setRevolutions((F32)sd["revolutions"].asReal()); + setSkew((F32)sd["skew"].asReal()); + return true; } - -S32 LLVolume::getNumFaces() const +void LLPathParams::copyParams(const LLPathParams ¶ms) { - return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size(); + setCurveType(params.getCurveType()); + setBegin(params.getBegin()); + setEnd(params.getEnd()); + setScale(params.getScaleX(), params.getScaleY() ); + setShear(params.getShearX(), params.getShearY() ); + setTwist(params.getTwist()); + setTwistBegin(params.getTwistBegin()); + setRadiusOffset(params.getRadiusOffset()); + setTaper( params.getTaperX(), params.getTaperY() ); + setRevolutions(params.getRevolutions()); + setSkew(params.getSkew()); } - -void LLVolume::createVolumeFaces() +LLProfile::~LLProfile() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - - if (mGenerateSingleFace) - { - // do nothing - } - else - { - S32 num_faces = getNumFaces(); - BOOL partial_build = TRUE; - if (num_faces != mVolumeFaces.size()) - { - partial_build = FALSE; - mVolumeFaces.resize(num_faces); - } - // Initialize volume faces with parameter data - for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++) - { - LLVolumeFace& vf = mVolumeFaces[i]; - LLProfile::Face& face = mProfilep->mFaces[i]; - vf.mBeginS = face.mIndex; - vf.mNumS = face.mCount; - if (vf.mNumS < 0) - { - LL_ERRS() << "Volume face corruption detected." << LL_ENDL; - } - - vf.mBeginT = 0; - vf.mNumT= getPath().mPath.size(); - vf.mID = i; - - // Set the type mask bits correctly - if (mParams.getProfileParams().getHollow() > 0) - { - vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK; - } - if (mProfilep->isOpen()) - { - vf.mTypeMask |= LLVolumeFace::OPEN_MASK; - } - if (face.mCap) - { - vf.mTypeMask |= LLVolumeFace::CAP_MASK; - if (face.mFaceID == LL_FACE_PATH_BEGIN) - { - vf.mTypeMask |= LLVolumeFace::TOP_MASK; - } - else - { - llassert(face.mFaceID == LL_FACE_PATH_END); - vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK; - } - } - else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) - { - vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK; - } - else - { - vf.mTypeMask |= LLVolumeFace::SIDE_MASK; - if (face.mFlat) - { - vf.mTypeMask |= LLVolumeFace::FLAT_MASK; - } - if (face.mFaceID & LL_FACE_INNER_SIDE) - { - vf.mTypeMask |= LLVolumeFace::INNER_MASK; - if (face.mFlat && vf.mNumS > 2) - { //flat inner faces have to copy vert normals - vf.mNumS = vf.mNumS*2; - if (vf.mNumS < 0) - { - LL_ERRS() << "Volume face corruption detected." << LL_ENDL; - } - } - } - else - { - vf.mTypeMask |= LLVolumeFace::OUTER_MASK; - } - } - } - - for (face_list_t::iterator iter = mVolumeFaces.begin(); - iter != mVolumeFaces.end(); ++iter) - { - (*iter).create(this, partial_build); - } - } } -inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b) -{ - // maps RGB values to vector values [0..255] -> [-0.5..0.5] - LLVector4a value; - LLVector4a sub(0.5f, 0.5f, 0.5f); +S32 LLVolume::sNumMeshPoints = 0; + +LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face, const BOOL is_unique) + : mParams(params) +{ + mUnique = is_unique; + mFaceMask = 0x0; + mDetail = detail; + mSculptLevel = -2; + mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims + mIsMeshAssetLoaded = false; + mIsMeshAssetUnavaliable = false; + mLODScaleBias.setVec(1,1,1); + mHullPoints = NULL; + mHullIndices = NULL; + mNumHullPoints = 0; + mNumHullIndices = 0; + + // set defaults + if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) + { + mPathp = new LLDynamicPath(); + } + else + { + mPathp = new LLPath(); + } + mProfilep = new LLProfile(); + + mGenerateSingleFace = generate_single_face; - value.set(r,g,b); - value.mul(1.f/255.f); - value.sub(sub); + generate(); - return value; + if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) + { + createVolumeFaces(); + } } -inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) +void LLVolume::resizePath(S32 length) { - U32 index = (x + y * sculpt_width) * sculpt_components; - return index; + mPathp->resizePath(length); + mVolumeFaces.clear(); + setDirty(); } - -inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) +void LLVolume::regen() { - U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); - U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); - - return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); + generate(); + createVolumeFaces(); } - -inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data) +void LLVolume::genTangents(S32 face) { - LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); - - return v; + // generate legacy tangents for the specified face + llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents + mVolumeFaces[face].createTangents(); } -inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +LLVolume::~LLVolume() { - U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); + sNumMeshPoints -= mMesh.size(); + delete mPathp; - return sculpt_index_to_vector(index, sculpt_data); -} + delete mProfilep; -inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) -{ - U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); + mPathp = NULL; + mProfilep = NULL; + mVolumeFaces.clear(); - return sculpt_index_to_vector(index, sculpt_data); + ll_aligned_free_16(mHullPoints); + mHullPoints = NULL; + ll_aligned_free_16(mHullIndices); + mHullIndices = NULL; } - -F32 LLVolume::sculptGetSurfaceArea() +BOOL LLVolume::generate() { - // test to see if image has enough variation to create non-degenerate geometry + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + + LL_CHECK_MEMORY + llassert_always(mProfilep); - F32 area = 0; + //Added 10.03.05 Dave Parks + // Split is a parameter to LLProfile::generate that tesselates edges on the profile + // to prevent lighting and texture interpolation errors on triangles that are + // stretched due to twisting or scaling on the path. + S32 split = (S32) ((mDetail)*0.66f); - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); - - for (S32 s = 0; s < sizeS-1; s++) - { - for (S32 t = 0; t < sizeT-1; t++) - { - // get four corners of quad - LLVector4a& p1 = mMesh[(s )*sizeT + (t )]; - LLVector4a& p2 = mMesh[(s+1)*sizeT + (t )]; - LLVector4a& p3 = mMesh[(s )*sizeT + (t+1)]; - LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)]; + if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE && + (mParams.getPathParams().getScale().mV[0] != 1.0f || + mParams.getPathParams().getScale().mV[1] != 1.0f) && + (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE || + mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI || + mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI || + mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI)) + { + split = 0; + } - // compute the area of the quad by taking the length of the cross product of the two triangles - LLVector4a v0,v1,v2,v3; - v0.setSub(p1,p2); - v1.setSub(p1,p3); - v2.setSub(p4,p2); - v3.setSub(p4,p3); + mLODScaleBias.setVec(0.5f, 0.5f, 0.5f); - LLVector4a cross1, cross2; - cross1.setCross3(v0,v1); - cross2.setCross3(v2,v3); + F32 profile_detail = mDetail; + F32 path_detail = mDetail; - //LLVector3 cross1 = (p1 - p2) % (p1 - p3); - //LLVector3 cross2 = (p4 - p2) % (p4 - p3); - - area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f; - } - } + if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) + { + U8 path_type = mParams.getPathParams().getCurveType(); + U8 profile_type = mParams.getProfileParams().getCurveType(); + if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE) + { + //cylinders don't care about Z-Axis + mLODScaleBias.setVec(0.6f, 0.6f, 0.0f); + } + else if (path_type == LL_PCODE_PATH_CIRCLE) + { + mLODScaleBias.setVec(0.6f, 0.6f, 0.6f); + } + } - return area; -} + BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split); + BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split); -// create empty placeholder shape -void LLVolume::sculptGenerateEmptyPlaceholder() -{ - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); + if (regenPath || regenProf ) + { + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); - S32 line = 0; + sNumMeshPoints -= mMesh.size(); + mMesh.resize(sizeT * sizeS); + sNumMeshPoints += mMesh.size(); - for (S32 s = 0; s < sizeS; s++) - { - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - LLVector4a& pt = mMesh[i]; - - F32* p = pt.getF32ptr(); + //generate vertex positions - p[0] = 0; - p[1] = 0; - p[2] = 0; + // Run along the path. + LLVector4a* dst = mMesh.mArray; - llassert(pt.isFinite3()); - } - line += sizeT; - } -} + for (S32 s = 0; s < sizeS; ++s) + { + F32* scale = mPathp->mPath[s].mScale.getF32ptr(); -// create sphere placeholder shape -void LLVolume::sculptGenerateSpherePlaceholder() -{ - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); + F32 sc [] = + { scale[0], 0, 0, 0, + 0, scale[1], 0, 0, + 0, 0, scale[2], 0, + 0, 0, 0, 1 }; - S32 line = 0; + LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); + LLMatrix4 scale_mat(sc); - for (S32 s = 0; s < sizeS; s++) - { - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - LLVector4a& pt = mMesh[i]; + scale_mat *= rot; + LLMatrix4a rot_mat; + rot_mat.loadu(scale_mat); - F32 u = (F32)s / (sizeS - 1); - F32 v = (F32)t / (sizeT - 1); + LLVector4a* profile = mProfilep->mProfile.mArray; + LLVector4a* end_profile = profile+sizeT; + LLVector4a offset = mPathp->mPath[s].mPos; + + // hack to work around MAINT-5660 for debug until we can suss out + // what is wrong with the path generated that inserts NaNs... + if (!offset.isFinite3()) + { + offset.clear(); + } - const F32 RADIUS = (F32) 0.3; + LLVector4a tmp; - F32* p = pt.getF32ptr(); + // Run along the profile. + while (profile < end_profile) + { + rot_mat.rotate(*profile++, tmp); + dst->setAdd(tmp,offset); + ++dst; + } + } - p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); - p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); - p[2] = (F32)(cos(F_PI * v) * RADIUS); + for (std::vector::iterator iter = mProfilep->mFaces.begin(); + iter != mProfilep->mFaces.end(); ++iter) + { + LLFaceID id = iter->mFaceID; + mFaceMask |= id; + } + LL_CHECK_MEMORY + return TRUE; + } - llassert(pt.isFinite3()); - } - line += sizeT; - } + LL_CHECK_MEMORY + return FALSE; } -// create the vertices from the map -void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) -{ - U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; - BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; - BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; - BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR - - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); - - S32 line = 0; - for (S32 s = 0; s < sizeS; s++) - { - // Run along the profile. - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - LLVector4a& pt = mMesh[i]; - - S32 reversed_t = t; - - if (reverse_horizontal) - { - reversed_t = sizeT - t - 1; - } - - U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width); - U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); - - - if (y == 0) // top row stitching - { - // pinch? - if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } - } - - if (y == sculpt_height) // bottom row stitching - { - // wrap? - if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) - { - y = 0; - } - else - { - y = sculpt_height - 1; - } - - // pinch? - if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } - } - - if (x == sculpt_width) // side stitching - { - // wrap? - if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || - (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || - (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) - { - x = 0; - } - - else - { - x = sculpt_width - 1; - } - } - - pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); - - if (sculpt_mirror) - { - LLVector4a scale(-1.f,1,1,1); - pt.mul(scale); - } - - llassert(pt.isFinite3()); - } - - line += sizeT; - } -} - - -const S32 SCULPT_REZ_1 = 6; // changed from 4 to 6 - 6 looks round whereas 4 looks square -const S32 SCULPT_REZ_2 = 8; -const S32 SCULPT_REZ_3 = 16; -const S32 SCULPT_REZ_4 = 32; - -S32 sculpt_sides(F32 detail) -{ - - // detail is usually one of: 1, 1.5, 2.5, 4.0. - - if (detail <= 1.0) - { - return SCULPT_REZ_1; - } - if (detail <= 2.0) - { - return SCULPT_REZ_2; - } - if (detail <= 3.0) - { - return SCULPT_REZ_3; - } - else - { - return SCULPT_REZ_4; - } -} - - - -// determine the number of vertices in both s and t direction for this sculpt -void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t) +void LLVolumeFace::VertexData::init() { - // this code has the following properties: - // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map - // while still using all available verts - // 2) the mesh cannot have more verts than is allowed by LOD - // 3) the mesh cannot have more verts than is allowed by the map - - S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0); - S32 max_vertices_map = width * height / 4; - - S32 vertices; - if (max_vertices_map > 0) - vertices = llmin(max_vertices_lod, max_vertices_map); - else - vertices = max_vertices_lod; - - - F32 ratio; - if ((width == 0) || (height == 0)) - ratio = 1.f; - else - ratio = (F32) width / (F32) height; - - - s = (S32)(F32) sqrt(((F32)vertices / ratio)); - - s = llmax(s, 4); // no degenerate sizes, please - t = vertices / s; - - t = llmax(t, 4); // no degenerate sizes, please - s = vertices / t; + if (!mData) + { + mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2); + } } -// sculpt replaces generate() for sculpted surfaces -void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder) +LLVolumeFace::VertexData::VertexData() { - U8 sculpt_type = mParams.getSculptType(); - - BOOL data_is_empty = FALSE; - - if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) - { - sculpt_level = -1; - data_is_empty = TRUE; - } - - S32 requested_sizeS = 0; - S32 requested_sizeT = 0; - - sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); - - mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); - mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); - - S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got - S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got - - // weird crash bug - DEV-11158 - trying to collect more data: - if ((sizeS == 0) || (sizeT == 0)) - { - LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL; - } - - sNumMeshPoints -= mMesh.size(); - mMesh.resize(sizeS * sizeT); - sNumMeshPoints += mMesh.size(); - - //generate vertex positions - if (!data_is_empty) - { - sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); - - // don't test lowest LOD to support legacy content DEV-33670 - if (mDetail > SCULPT_MIN_AREA_DETAIL) - { - F32 area = sculptGetSurfaceArea(); - - mSurfaceArea = area; - - const F32 SCULPT_MAX_AREA = 384.f; - - if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) - { - data_is_empty = TRUE; - visible_placeholder = true; - } - } - } - - if (data_is_empty) - { - if (visible_placeholder) - { - // Object should be visible since there will be nothing else to display - sculptGenerateSpherePlaceholder(); - } - else - { - sculptGenerateEmptyPlaceholder(); - } - } - - - - for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) - { - mFaceMask |= mProfilep->mFaces[i].mFaceID; - } - - mSculptLevel = sculpt_level; - - // Delete any existing faces so that they get regenerated - mVolumeFaces.clear(); - - createVolumeFaces(); + mData = NULL; + init(); } - - - -BOOL LLVolume::isCap(S32 face) +LLVolumeFace::VertexData::VertexData(const VertexData& rhs) { - return mProfilep->mFaces[face].mCap; + mData = NULL; + *this = rhs; } -BOOL LLVolume::isFlat(S32 face) +const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolumeFace::VertexData& rhs) { - return mProfilep->mFaces[face].mFlat; + if (this != &rhs) + { + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a)); + mTexCoord = rhs.mTexCoord; + } + return *this; } - -bool LLVolumeParams::isSculpt() const +LLVolumeFace::VertexData::~VertexData() { - return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE; + ll_aligned_free_16(mData); + mData = NULL; } -bool LLVolumeParams::isMeshSculpt() const +LLVector4a& LLVolumeFace::VertexData::getPosition() { - return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH; + return mData[POSITION]; } -bool LLVolumeParams::operator==(const LLVolumeParams ¶ms) const +LLVector4a& LLVolumeFace::VertexData::getNormal() { - return ( (getPathParams() == params.getPathParams()) && - (getProfileParams() == params.getProfileParams()) && - (mSculptID == params.mSculptID) && - (mSculptType == params.mSculptType) ); + return mData[NORMAL]; } -bool LLVolumeParams::operator!=(const LLVolumeParams ¶ms) const +const LLVector4a& LLVolumeFace::VertexData::getPosition() const { - return ( (getPathParams() != params.getPathParams()) || - (getProfileParams() != params.getProfileParams()) || - (mSculptID != params.mSculptID) || - (mSculptType != params.mSculptType) ); + return mData[POSITION]; } -bool LLVolumeParams::operator<(const LLVolumeParams ¶ms) const +const LLVector4a& LLVolumeFace::VertexData::getNormal() const { - if( getPathParams() != params.getPathParams() ) - { - return getPathParams() < params.getPathParams(); - } - - if (getProfileParams() != params.getProfileParams()) - { - return getProfileParams() < params.getProfileParams(); - } - - if (mSculptID != params.mSculptID) - { - return mSculptID < params.mSculptID; - } - - return mSculptType < params.mSculptType; - - + return mData[NORMAL]; } -void LLVolumeParams::copyParams(const LLVolumeParams ¶ms) -{ - mProfileParams.copyParams(params.mProfileParams); - mPathParams.copyParams(params.mPathParams); - mSculptID = params.getSculptID(); - mSculptType = params.getSculptType(); -} -// Less restricitve approx 0 for volumes -const F32 APPROXIMATELY_ZERO = 0.001f; -bool approx_zero( F32 f, F32 tolerance = APPROXIMATELY_ZERO) +void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos) { - return (f >= -tolerance) && (f <= tolerance); + mData[POSITION] = pos; } -// return true if in range (or nearly so) -static bool limit_range(F32& v, F32 min, F32 max, F32 tolerance = APPROXIMATELY_ZERO) +void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) { - F32 min_delta = v - min; - if (min_delta < 0.f) - { - v = min; - if (!approx_zero(min_delta, tolerance)) - return false; - } - F32 max_delta = max - v; - if (max_delta < 0.f) - { - v = max; - if (!approx_zero(max_delta, tolerance)) - return false; - } - return true; + mData[NORMAL] = norm; } -bool LLVolumeParams::setBeginAndEndS(const F32 b, const F32 e) +bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const { - bool valid = true; - - // First, clamp to valid ranges. - F32 begin = b; - valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); - - F32 end = e; - if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error - valid &= limit_range(end, MIN_CUT_DELTA, 1.f); + const F32* lp = this->getPosition().getF32ptr(); + const F32* rp = rhs.getPosition().getF32ptr(); - valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); - - // Now set them. - mProfileParams.setBegin(begin); - mProfileParams.setEnd(end); - - return valid; -} - -bool LLVolumeParams::setBeginAndEndT(const F32 b, const F32 e) -{ - bool valid = true; + if (lp[0] != rp[0]) + { + return lp[0] < rp[0]; + } - // First, clamp to valid ranges. - F32 begin = b; - valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); + if (rp[1] != lp[1]) + { + return lp[1] < rp[1]; + } - F32 end = e; - valid &= limit_range(end, MIN_CUT_DELTA, 1.f); + if (rp[2] != lp[2]) + { + return lp[2] < rp[2]; + } - valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); + lp = getNormal().getF32ptr(); + rp = rhs.getNormal().getF32ptr(); - // Now set them. - mPathParams.setBegin(begin); - mPathParams.setEnd(end); + if (lp[0] != rp[0]) + { + return lp[0] < rp[0]; + } - return valid; -} + if (rp[1] != lp[1]) + { + return lp[1] < rp[1]; + } -bool LLVolumeParams::setHollow(const F32 h) -{ - // Validate the hollow based on path and profile. - U8 profile = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; - U8 hole_type = mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK; - - F32 max_hollow = HOLLOW_MAX; - - // Only square holes have trouble. - if (LL_PCODE_HOLE_SQUARE == hole_type) - { - switch(profile) - { - case LL_PCODE_PROFILE_CIRCLE: - case LL_PCODE_PROFILE_CIRCLE_HALF: - case LL_PCODE_PROFILE_EQUALTRI: - max_hollow = HOLLOW_MAX_SQUARE; - } - } - - F32 hollow = h; - bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow); - mProfileParams.setHollow(hollow); - - return valid; -} + if (rp[2] != lp[2]) + { + return lp[2] < rp[2]; + } -bool LLVolumeParams::setTwistBegin(const F32 b) -{ - F32 twist_begin = b; - bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX); - mPathParams.setTwistBegin(twist_begin); - return valid; -} + if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0]) + { + return mTexCoord.mV[0] < rhs.mTexCoord.mV[0]; + } -bool LLVolumeParams::setTwistEnd(const F32 e) -{ - F32 twist_end = e; - bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX); - mPathParams.setTwistEnd(twist_end); - return valid; + return mTexCoord.mV[1] < rhs.mTexCoord.mV[1]; } -bool LLVolumeParams::setRatio(const F32 x, const F32 y) +bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const { - F32 min_x = RATIO_MIN; - F32 max_x = RATIO_MAX; - F32 min_y = RATIO_MIN; - F32 max_y = RATIO_MAX; - // If this is a circular path (and not a sphere) then 'ratio' is actually hole size. - U8 path_type = mPathParams.getCurveType(); - U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; - if ( LL_PCODE_PATH_CIRCLE == path_type && - LL_PCODE_PROFILE_CIRCLE_HALF != profile_type) - { - // Holes are more restricted... - min_x = HOLE_X_MIN; - max_x = HOLE_X_MAX; - min_y = HOLE_Y_MIN; - max_y = HOLE_Y_MAX; - } - - F32 ratio_x = x; - bool valid = limit_range(ratio_x, min_x, max_x); - F32 ratio_y = y; - valid &= limit_range(ratio_y, min_y, max_y); - - mPathParams.setScale(ratio_x, ratio_y); - - return valid; + return mData[POSITION].equals3(rhs.getPosition()) && + mData[NORMAL].equals3(rhs.getNormal()) && + mTexCoord == rhs.mTexCoord; } -bool LLVolumeParams::setShear(const F32 x, const F32 y) +bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const { - F32 shear_x = x; - bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX); - F32 shear_y = y; - valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX); - mPathParams.setShear(shear_x, shear_y); - return valid; -} + bool retval = false; -bool LLVolumeParams::setTaperX(const F32 v) -{ - F32 taper = v; - bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); - mPathParams.setTaperX(taper); - return valid; -} + const F32 epsilon = 0.00001f; -bool LLVolumeParams::setTaperY(const F32 v) -{ - F32 taper = v; - bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); - mPathParams.setTaperY(taper); - return valid; -} + if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && + fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && + fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) + { + if (angle_cutoff > 1.f) + { + retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); + } + else + { + F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32(); + retval = cur_angle > angle_cutoff; + } + } -bool LLVolumeParams::setRevolutions(const F32 r) -{ - F32 revolutions = r; - bool valid = limit_range(revolutions, REV_MIN, REV_MAX); - mPathParams.setRevolutions(revolutions); - return valid; + return retval; } -bool LLVolumeParams::setRadiusOffset(const F32 offset) +bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { - bool valid = true; - - // If this is a sphere, just set it to 0 and get out. - U8 path_type = mPathParams.getCurveType(); - U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; - if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type || - LL_PCODE_PATH_CIRCLE != path_type ) - { - mPathParams.setRadiusOffset(0.f); - return true; - } - - // Limit radius offset, based on taper and hole size y. - F32 radius_offset = offset; - F32 taper_y = getTaperY(); - F32 radius_mag = fabs(radius_offset); - F32 hole_y_mag = fabs(getRatioY()); - F32 taper_y_mag = fabs(taper_y); - // Check to see if the taper effects us. - if ( (radius_offset > 0.f && taper_y < 0.f) || - (radius_offset < 0.f && taper_y > 0.f) ) - { - // The taper does not help increase the radius offset range. - taper_y_mag = 0.f; - } - F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag); - - // Enforce the maximum magnitude. - F32 delta = max_radius_mag - radius_mag; - if (delta < 0.f) - { - // Check radius offset sign. - if (radius_offset < 0.f) - { - radius_offset = -max_radius_mag; - } - else - { - radius_offset = max_radius_mag; - } - valid = approx_zero(delta, .1f); - } - - mPathParams.setRadiusOffset(radius_offset); - return valid; -} + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME -bool LLVolumeParams::setSkew(const F32 skew_value) -{ - bool valid = true; - - // Check the skew value against the revolutions. - F32 skew = llclamp(skew_value, SKEW_MIN, SKEW_MAX); - F32 skew_mag = fabs(skew); - F32 revolutions = getRevolutions(); - F32 scale_x = getRatioX(); - F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f); - // Discontinuity; A revolution of 1 allows skews below 0.5. - if ( fabs(revolutions - 1.0f) < 0.001) - min_skew_mag = 0.0f; - - // Clip skew. - F32 delta = skew_mag - min_skew_mag; - if (delta < 0.f) - { - // Check skew sign. - if (skew < 0.0f) - { - skew = -min_skew_mag; - } - else - { - skew = min_skew_mag; - } - valid = approx_zero(delta, .01f); - } - - mPathParams.setSkew(skew); - return valid; + //input stream is now pointing at a zlib compressed block of LLSD + //decompress block + LLSD mdl; + U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; + return false; + } + return unpackVolumeFacesInternal(mdl); } -bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type) +bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) { - mSculptID = sculpt_id; - mSculptType = sculpt_type; - return true; + //input data is now pointing at a zlib compressed block of LLSD + //decompress block + LLSD mdl; + U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; + return false; + } + return unpackVolumeFacesInternal(mdl); } -bool LLVolumeParams::setType(U8 profile, U8 path) +bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) { - bool result = true; - // First, check profile and path for validity. - U8 profile_type = profile & LL_PCODE_PROFILE_MASK; - U8 hole_type = (profile & LL_PCODE_HOLE_MASK) >> 4; - U8 path_type = path >> 4; - - if (profile_type > LL_PCODE_PROFILE_MAX) - { - // Bad profile. Make it square. - profile = LL_PCODE_PROFILE_SQUARE; - result = false; - LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type - << ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL; - } - else if (hole_type > LL_PCODE_HOLE_MAX) - { - // Bad hole. Make it the same. - profile = profile_type; - result = false; - LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type - << ") to be LL_PCODE_HOLE_SAME" << LL_ENDL; - } - - if (path_type < LL_PCODE_PATH_MIN || - path_type > LL_PCODE_PATH_MAX) - { - // Bad path. Make it linear. - result = false; - LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path - << ") to be LL_PCODE_PATH_LINE" << LL_ENDL; - path = LL_PCODE_PATH_LINE; - } - - mProfileParams.setCurveType(profile); - mPathParams.setCurveType(path); - return result; -} - -// static -bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, - U8 path_curve, F32 path_begin, F32 path_end, - F32 scx, F32 scy, F32 shx, F32 shy, - F32 twistend, F32 twistbegin, F32 radiusoffset, - F32 tx, F32 ty, F32 revolutions, F32 skew) -{ - LLVolumeParams test_params; - if (!test_params.setType (prof_curve, path_curve)) - { - return false; - } - if (!test_params.setBeginAndEndS (prof_begin, prof_end)) - { - return false; - } - if (!test_params.setBeginAndEndT (path_begin, path_end)) - { - return false; - } - if (!test_params.setHollow (hollow)) - { - return false; - } - if (!test_params.setTwistBegin (twistbegin)) - { - return false; - } - if (!test_params.setTwistEnd (twistend)) - { - return false; - } - if (!test_params.setRatio (scx, scy)) - { - return false; - } - if (!test_params.setShear (shx, shy)) - { - return false; - } - if (!test_params.setTaper (tx, ty)) - { - return false; - } - if (!test_params.setRevolutions (revolutions)) - { - return false; - } - if (!test_params.setRadiusOffset (radiusoffset)) - { - return false; - } - if (!test_params.setSkew (skew)) - { - return false; - } - return true; -} + { + U32 face_count = mdl.size(); -void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts) -{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the - //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - F32 detail[] = {1.f, 1.5f, 2.5f, 4.f}; - for (S32 i = 0; i < 4; i++) - { - S32 count = 0; - S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]); - S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]); + if (face_count == 0) + { //no faces unpacked, treat as failed decode + LL_WARNS() << "found no faces!" << LL_ENDL; + return false; + } - count = (profile_points-1)*2*(path_points-1); - count += profile_points*2; + mVolumeFaces.resize(face_count); - counts[i] = count; - } -} + for (size_t i = 0; i < face_count; ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; + + if (mdl[i].has("NoGeometry")) + { //face has no geometry, continue + face.resizeIndices(3); + face.resizeVertices(1); + face.mPositions->clear(); + face.mNormals->clear(); + face.mTexCoords->setZero(); + memset(face.mIndices, 0, sizeof(U16)*3); + continue; + } + LLSD::Binary pos = mdl[i]["Position"]; + LLSD::Binary norm = mdl[i]["Normal"]; + LLSD::Binary tangent = mdl[i]["Tangent"]; + LLSD::Binary tc = mdl[i]["TexCoord0"]; + LLSD::Binary idx = mdl[i]["TriangleList"]; -S32 LLVolume::getNumTriangles(S32* vcount) const -{ - U32 triangle_count = 0; - U32 vertex_count = 0; + //copy out indices + S32 num_indices = idx.size() / 2; + const S32 indices_to_discard = num_indices % 3; + if (indices_to_discard > 0) + { + // Invalid number of triangle indices + LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; + num_indices -= indices_to_discard; + } + face.resizeIndices(num_indices); - for (S32 i = 0; i < getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = getVolumeFace(i); - triangle_count += face.mNumIndices/3; + if (num_indices > 2 && !face.mIndices) + { + LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL; + continue; + } - vertex_count += face.mNumVertices; - } + if (idx.empty() || face.mNumIndices < 3) + { //why is there an empty index list? + LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL; + continue; + } + U16* indices = (U16*) &(idx[0]); + for (U32 j = 0; j < num_indices; ++j) + { + face.mIndices[j] = indices[j]; + } - if (vcount) - { - *vcount = vertex_count; - } - - return triangle_count; -} + //copy out vertices + U32 num_verts = pos.size()/(3*2); + face.resizeVertices(num_verts); + if (num_verts > 0 && !face.mPositions) + { + LL_WARNS() << "Failed to allocate " << num_verts << " vertices for face index: " << i << " Total: " << face_count << LL_ENDL; + face.resizeIndices(0); + continue; + } -//----------------------------------------------------------------------------- -// generateSilhouetteVertices() -//----------------------------------------------------------------------------- -void LLVolume::generateSilhouetteVertices(std::vector &vertices, - std::vector &normals, - const LLVector3& obj_cam_vec_in, - const LLMatrix4& mat_in, - const LLMatrix3& norm_mat_in, - S32 face_mask) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - - LLMatrix4a mat; - mat.loadu(mat_in); - - LLMatrix4a norm_mat; - norm_mat.loadu(norm_mat_in); - - LLVector4a obj_cam_vec; - obj_cam_vec.load3(obj_cam_vec_in.mV); - - vertices.clear(); - normals.clear(); - - if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - { - return; - } - - S32 cur_index = 0; - //for each face - for (face_list_t::iterator iter = mVolumeFaces.begin(); - iter != mVolumeFaces.end(); ++iter) - { - LLVolumeFace& face = *iter; - - if (!(face_mask & (0x1 << cur_index++)) || - face.mNumIndices == 0 || face.mEdge.empty()) - { - continue; - } - - if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) - { - LLVector4a* v = (LLVector4a*)face.mPositions; - LLVector4a* n = (LLVector4a*)face.mNormals; - - for (U32 j = 0; j < face.mNumIndices / 3; j++) - { - for (S32 k = 0; k < 3; k++) - { - S32 index = face.mEdge[j * 3 + k]; - - if (index == -1) - { - // silhouette edge, currently only cubes, so no other conditions - - S32 v1 = face.mIndices[j * 3 + k]; - S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)]; - - LLVector4a t; - mat.affineTransform(v[v1], t); - vertices.push_back(LLVector3(t[0], t[1], t[2])); - - norm_mat.rotate(n[v1], t); - - t.normalize3fast(); - normals.push_back(LLVector3(t[0], t[1], t[2])); - - mat.affineTransform(v[v2], t); - vertices.push_back(LLVector3(t[0], t[1], t[2])); - - norm_mat.rotate(n[v2], t); - t.normalize3fast(); - normals.push_back(LLVector3(t[0], t[1], t[2])); - } - } - } - - } - else - { - - //============================================== - //DEBUG draw edge map instead of silhouette edge - //============================================== + LLVector3 minp; + LLVector3 maxp; + LLVector2 min_tc; + LLVector2 max_tc; -#if DEBUG_SILHOUETTE_EDGE_MAP + minp.setValue(mdl[i]["PositionDomain"]["Min"]); + maxp.setValue(mdl[i]["PositionDomain"]["Max"]); + LLVector4a min_pos, max_pos; + min_pos.load3(minp.mV); + max_pos.load3(maxp.mV); - //for each triangle - U32 tri_count = face.mNumIndices / 3; - for (U32 j = 0; j < tri_count; j++) { - //get vertices - S32 v1 = face.mIndices[j*3+0]; - S32 v2 = face.mIndices[j*3+1]; - S32 v3 = face.mIndices[j*3+2]; - - //get current face center - LLVector3 cCenter = (face.mVertices[v1].getPosition() + - face.mVertices[v2].getPosition() + - face.mVertices[v3].getPosition()) / 3.0f; - - //for each edge - for (S32 k = 0; k < 3; k++) { - S32 nIndex = face.mEdge[j*3+k]; - if (nIndex <= -1) { - continue; - } + min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); + max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); - if (nIndex >= (S32)tri_count) { - continue; - } - //get neighbor vertices - v1 = face.mIndices[nIndex*3+0]; - v2 = face.mIndices[nIndex*3+1]; - v3 = face.mIndices[nIndex*3+2]; - - //get neighbor face center - LLVector3 nCenter = (face.mVertices[v1].getPosition() + - face.mVertices[v2].getPosition() + - face.mVertices[v3].getPosition()) / 3.0f; - - //draw line - vertices.push_back(cCenter); - vertices.push_back(nCenter); - normals.push_back(LLVector3(1,1,1)); - normals.push_back(LLVector3(1,1,1)); - segments.push_back(vertices.size()); - } - } - - continue; - - //============================================== - //DEBUG - //============================================== - - //============================================== - //DEBUG draw normals instead of silhouette edge - //============================================== -#elif DEBUG_SILHOUETTE_NORMALS + //unpack normalized scale/translation + if (mdl[i].has("NormalizedScale")) + { + face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]); + } + else + { + face.mNormalizedScale.set(1, 1, 1); + } - //for each vertex - for (U32 j = 0; j < face.mNumVertices; j++) { - vertices.push_back(face.mVertices[j].getPosition()); - vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); - normals.push_back(LLVector3(0,0,1)); - normals.push_back(LLVector3(0,0,1)); - segments.push_back(vertices.size()); -#if DEBUG_SILHOUETTE_BINORMALS - vertices.push_back(face.mVertices[j].getPosition()); - vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f); - normals.push_back(LLVector3(0,0,1)); - normals.push_back(LLVector3(0,0,1)); - segments.push_back(vertices.size()); -#endif - } - - continue; -#else - //============================================== - //DEBUG - //============================================== - - static const U8 AWAY = 0x01, - TOWARDS = 0x02; - - //for each triangle - std::vector fFacing; - vector_append(fFacing, face.mNumIndices/3); - - LLVector4a* v = (LLVector4a*) face.mPositions; - LLVector4a* n = (LLVector4a*) face.mNormals; - - for (U32 j = 0; j < face.mNumIndices/3; j++) - { - //approximate normal - S32 v1 = face.mIndices[j*3+0]; - S32 v2 = face.mIndices[j*3+1]; - S32 v3 = face.mIndices[j*3+2]; - - LLVector4a c1,c2; - c1.setSub(v[v1], v[v2]); - c2.setSub(v[v2], v[v3]); - - LLVector4a norm; - - norm.setCross3(c1, c2); - - if (norm.dot3(norm) < 0.00000001f) - { - fFacing[j] = AWAY | TOWARDS; - } - else - { - //get view vector - LLVector4a view; - view.setSub(obj_cam_vec, v[v1]); - bool away = view.dot3(norm) > 0.0f; - if (away) - { - fFacing[j] = AWAY; - } - else - { - fFacing[j] = TOWARDS; - } - } - } - - //for each triangle - for (U32 j = 0; j < face.mNumIndices/3; j++) - { - if (fFacing[j] == (AWAY | TOWARDS)) - { //this is a degenerate triangle - //take neighbor facing (degenerate faces get facing of one of their neighbors) - // *FIX IF NEEDED: this does not deal with neighboring degenerate faces - for (S32 k = 0; k < 3; k++) - { - S32 index = face.mEdge[j*3+k]; - if (index != -1) - { - fFacing[j] = fFacing[index]; - break; - } - } - continue; //skip degenerate face - } - - //for each edge - for (S32 k = 0; k < 3; k++) { - S32 index = face.mEdge[j*3+k]; - if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) { - //our neighbor is degenerate, make him face our direction - fFacing[face.mEdge[j*3+k]] = fFacing[j]; - continue; - } - - if (index == -1 || //edge has no neighbor, MUST be a silhouette edge - (fFacing[index] & fFacing[j]) == 0) { //we found a silhouette edge - - S32 v1 = face.mIndices[j*3+k]; - S32 v2 = face.mIndices[j*3+((k+1)%3)]; - - LLVector4a t; - mat.affineTransform(v[v1], t); - vertices.push_back(LLVector3(t[0], t[1], t[2])); - - norm_mat.rotate(n[v1], t); - - t.normalize3fast(); - normals.push_back(LLVector3(t[0], t[1], t[2])); - - mat.affineTransform(v[v2], t); - vertices.push_back(LLVector3(t[0], t[1], t[2])); - - norm_mat.rotate(n[v2], t); - t.normalize3fast(); - normals.push_back(LLVector3(t[0], t[1], t[2])); - } - } - } -#endif - } - } -} - -S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out) -{ - S32 hit_face = -1; - - S32 start_face; - S32 end_face; - - if (face == -1) // ALL_SIDES - { - start_face = 0; - end_face = getNumVolumeFaces() - 1; - } - else - { - start_face = face; - end_face = face; - } - - LLVector4a dir; - dir.setSub(end, start); - - F32 closest_t = 2.f; // must be larger than 1 - - end_face = llmin(end_face, getNumVolumeFaces()-1); - - for (S32 i = start_face; i <= end_face; i++) - { - LLVolumeFace &face = mVolumeFaces[i]; - - LLVector4a box_center; - box_center.setAdd(face.mExtents[0], face.mExtents[1]); - box_center.mul(0.5f); - - LLVector4a box_size; - box_size.setSub(face.mExtents[1], face.mExtents[0]); + LLVector4a pos_range; + pos_range.setSub(max_pos, min_pos); + LLVector2 tc_range2 = max_tc - min_tc; - if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) - { - if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them - { - genTangents(i); - } - - if (isUnique()) - { //don't bother with an octree for flexi volumes - U32 tri_count = face.mNumIndices/3; - - for (U32 j = 0; j < tri_count; ++j) - { - U16 idx0 = face.mIndices[j*3+0]; - U16 idx1 = face.mIndices[j*3+1]; - U16 idx2 = face.mIndices[j*3+2]; - - const LLVector4a& v0 = face.mPositions[idx0]; - const LLVector4a& v1 = face.mPositions[idx1]; - const LLVector4a& v2 = face.mPositions[idx2]; - - F32 a,b,t; - - if (LLTriangleRayIntersect(v0, v1, v2, - start, dir, a, b, t)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < closest_t)) // and this hit is closer - { - closest_t = t; - hit_face = i; - - if (intersection != NULL) - { - LLVector4a intersect = dir; - intersect.mul(closest_t); - intersect.add(start); - *intersection = intersect; - } - - - if (tex_coord != NULL) - { - LLVector2* tc = (LLVector2*) face.mTexCoords; - *tex_coord = ((1.f - a - b) * tc[idx0] + - a * tc[idx1] + - b * tc[idx2]); - - } - - if (normal!= NULL) - { - LLVector4a* norm = face.mNormals; - - LLVector4a n1,n2,n3; - n1 = norm[idx0]; - n1.mul(1.f-a-b); - - n2 = norm[idx1]; - n2.mul(a); - - n3 = norm[idx2]; - n3.mul(b); - - n1.add(n2); - n1.add(n3); - - *normal = n1; - } - - if (tangent_out != NULL) - { - LLVector4a* tangents = face.mTangents; - - LLVector4a t1,t2,t3; - t1 = tangents[idx0]; - t1.mul(1.f-a-b); - - t2 = tangents[idx1]; - t2.mul(a); - - t3 = tangents[idx2]; - t3.mul(b); - - t1.add(t2); - t1.add(t3); - - *tangent_out = t1; - } - } - } - } - } - else - { - if (!face.getOctree()) - { - face.createOctree(); - } - - LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); - intersect.traverse(face.getOctree()); - if (intersect.mHitFace) - { - hit_face = i; - } - } - } - } - - - return hit_face; -} + LLVector4a tc_range; + tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]); + LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]); -class LLVertexIndexPair -{ -public: - LLVertexIndexPair(const LLVector3 &vertex, const S32 index); + LLVector4a* pos_out = face.mPositions; + LLVector4a* norm_out = face.mNormals; + LLVector4a* tc_out = (LLVector4a*) face.mTexCoords; - LLVector3 mVertex; - S32 mIndex; -}; + { + U16* v = (U16*) &(pos[0]); + for (U32 j = 0; j < num_verts; ++j) + { + pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); + pos_out->div(65535.f); + pos_out->mul(pos_range); + pos_out->add(min_pos); + pos_out++; + v += 3; + } -LLVertexIndexPair::LLVertexIndexPair(const LLVector3 &vertex, const S32 index) -{ - mVertex = vertex; - mIndex = index; -} + } -const F32 VERTEX_SLOP = 0.00001f; + { + if (!norm.empty()) + { + U16* n = (U16*) &(norm[0]); + for (U32 j = 0; j < num_verts; ++j) + { + norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); + norm_out->div(65535.f); + norm_out->mul(2.f); + norm_out->sub(1.f); + norm_out++; + n += 3; + } + } + else + { + for (U32 j = 0; j < num_verts; ++j) + { + norm_out->clear(); + norm_out++; // or just norm_out[j].clear(); + } + } + } -struct lessVertex -{ - bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b) - { - const F32 slop = VERTEX_SLOP; - - if (a->mVertex.mV[0] + slop < b->mVertex.mV[0]) - { - return TRUE; - } - else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0]) - { - return FALSE; - } - - if (a->mVertex.mV[1] + slop < b->mVertex.mV[1]) - { - return TRUE; - } - else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1]) - { - return FALSE; - } - - if (a->mVertex.mV[2] + slop < b->mVertex.mV[2]) - { - return TRUE; - } - else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2]) - { - return FALSE; - } - - return FALSE; - } -}; +#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents + { + if (!tangent.empty()) + { + face.allocateTangents(face.mNumVertices); + U16* t = (U16*)&(tangent[0]); -struct lessTriangle -{ - bool operator()(const S32 *a, const S32 *b) - { - if (*a < *b) - { - return TRUE; - } - else if (*a > *b) - { - return FALSE; - } - - if (*(a+1) < *(b+1)) - { - return TRUE; - } - else if (*(a+1) > *(b+1)) - { - return FALSE; - } - - if (*(a+2) < *(b+2)) - { - return TRUE; - } - else if (*(a+2) > *(b+2)) - { - return FALSE; - } - - return FALSE; - } -}; + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to + // maintain compliance with the GLTF spec + LLVector4a* t_out = face.mTangents; -BOOL equalTriangle(const S32 *a, const S32 *b) -{ - if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2))) - { - return TRUE; - } - return FALSE; -} + for (U32 j = 0; j < num_verts; ++j) + { + t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]); + t_out->div(65535.f); + t_out->mul(2.f); + t_out->sub(1.f); -BOOL LLVolumeParams::importFile(LLFILE *fp) -{ - //LL_INFOS() << "importing volume" << LL_ENDL; - const S32 BUFSIZE = 16384; - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - // *NOTE: changing the size or type of this buffer will require - // changing the sscanf below. - char keyword[256]; /* Flawfinder: ignore */ - keyword[0] = 0; - - while (!feof(fp)) - { - if (fgets(buffer, BUFSIZE, fp) == NULL) - { - buffer[0] = '\0'; - } - - sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */ - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("profile", keyword)) - { - mProfileParams.importFile(fp); - } - else if (!strcmp("path",keyword)) - { - mPathParams.importFile(fp); - } - else - { - LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; - } - } - - return TRUE; -} + F32* tp = t_out->getF32ptr(); + tp[3] = tp[3] < 0.f ? -1.f : 1.f; -BOOL LLVolumeParams::exportFile(LLFILE *fp) const -{ - fprintf(fp,"\tshape 0\n"); - fprintf(fp,"\t{\n"); - mPathParams.exportFile(fp); - mProfileParams.exportFile(fp); - fprintf(fp, "\t}\n"); - return TRUE; + t_out++; + t += 4; + } + } + } +#endif + + { + if (!tc.empty()) + { + U16* t = (U16*) &(tc[0]); + for (U32 j = 0; j < num_verts; j+=2) + { + if (j < num_verts-1) + { + tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); + } + else + { + tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); + } + + t += 4; + + tc_out->div(65535.f); + tc_out->mul(tc_range); + tc_out->add(min_tc4); + + tc_out++; + } + } + else + { + for (U32 j = 0; j < num_verts; j += 2) + { + tc_out->clear(); + tc_out++; + } + } + } + + if (mdl[i].has("Weights")) + { + face.allocateWeights(num_verts); + if (!face.mWeights && num_verts) + { + LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL; + face.resizeIndices(0); + face.resizeVertices(0); + continue; + } + + LLSD::Binary weights = mdl[i]["Weights"]; + + U32 idx = 0; + + U32 cur_vertex = 0; + while (idx < weights.size() && cur_vertex < num_verts) + { + const U8 END_INFLUENCES = 0xFF; + U8 joint = weights[idx++]; + + U32 cur_influence = 0; + LLVector4 wght(0,0,0,0); + U32 joints[4] = {0,0,0,0}; + LLVector4 joints_with_weights(0,0,0,0); + + while (joint != END_INFLUENCES && idx < weights.size()) + { + U16 influence = weights[idx++]; + influence |= ((U16) weights[idx++] << 8); + + F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); + wght.mV[cur_influence] = w; + joints[cur_influence] = joint; + cur_influence++; + + if (cur_influence >= 4) + { + joint = END_INFLUENCES; + } + else + { + joint = weights[idx++]; + } + } + F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; + if (wsum <= 0.f) + { + wght = LLVector4(0.999f,0.f,0.f,0.f); + } + for (U32 k=0; k<4; k++) + { + F32 f_combined = (F32) joints[k] + wght[k]; + joints_with_weights[k] = f_combined; + // Any weights we added above should wind up non-zero and applied to a specific bone. + // A failure here would indicate a floating point precision error in the math. + llassert((k >= cur_influence) || (f_combined - S32(f_combined) > 0.0f)); + } + face.mWeights[cur_vertex].loadua(joints_with_weights.mV); + + cur_vertex++; + } + + if (cur_vertex != num_verts || idx != weights.size()) + { + LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL; + } + + } + + // modifier flags? + bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); + bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); + + + // translate to actions: + bool do_reflect_x = false; + bool do_reverse_triangles = false; + bool do_invert_normals = false; + + if (do_mirror) + { + do_reflect_x = true; + do_reverse_triangles = !do_reverse_triangles; + } + + if (do_invert) + { + do_invert_normals = true; + do_reverse_triangles = !do_reverse_triangles; + } + + // now do the work + + if (do_reflect_x) + { + LLVector4a* p = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) + { + p[i].mul(-1.0f); + n[i].mul(-1.0f); + } + } + + if (do_invert_normals) + { + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) + { + n[i].mul(-1.0f); + } + } + + if (do_reverse_triangles) + { + for (U32 j = 0; j < face.mNumIndices; j += 3) + { + // swap the 2nd and 3rd index + S32 swap = face.mIndices[j+1]; + face.mIndices[j+1] = face.mIndices[j+2]; + face.mIndices[j+2] = swap; + } + } + + //calculate bounding box + // VFExtents change + LLVector4a& min = face.mExtents[0]; + LLVector4a& max = face.mExtents[1]; + + if (face.mNumVertices < 3) + { //empty face, use a dummy 1cm (at 1m scale) bounding box + min.splat(-0.005f); + max.splat(0.005f); + } + else + { + min = max = face.mPositions[0]; + + for (S32 i = 1; i < face.mNumVertices; ++i) + { + min.setMin(min, face.mPositions[i]); + max.setMax(max, face.mPositions[i]); + } + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (U32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0,0); + face.mTexCoordExtents[1].set(1,1); + } + } + } + } + + if (!cacheOptimize(true)) + { + // Out of memory? + LL_WARNS() << "Failed to optimize!" << LL_ENDL; + mVolumeFaces.clear(); + return false; + } + + mSculptLevel = 0; // success! + + return true; } -BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream) +bool LLVolume::isMeshAssetLoaded() { - //LL_INFOS() << "importing volume" << LL_ENDL; - const S32 BUFSIZE = 16384; - // *NOTE: changing the size or type of this buffer will require - // changing the sscanf below. - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - char keyword[256]; /* Flawfinder: ignore */ - keyword[0] = 0; - - while (input_stream.good()) - { - input_stream.getline(buffer, BUFSIZE); - sscanf(buffer, " %255s", keyword); - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("profile", keyword)) - { - mProfileParams.importLegacyStream(input_stream); - } - else if (!strcmp("path",keyword)) - { - mPathParams.importLegacyStream(input_stream); - } - else - { - LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; - } - } - - return TRUE; + return mIsMeshAssetLoaded; } -BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const +void LLVolume::setMeshAssetLoaded(bool loaded) { - output_stream <<"\tshape 0\n"; - output_stream <<"\t{\n"; - mPathParams.exportLegacyStream(output_stream); - mProfileParams.exportLegacyStream(output_stream); - output_stream << "\t}\n"; - return TRUE; + mIsMeshAssetLoaded = loaded; + if (loaded) + { + mIsMeshAssetUnavaliable = false; + } } -LLSD LLVolumeParams::sculptAsLLSD() const +void LLVolume::setMeshAssetUnavaliable(bool unavaliable) { - LLSD sd = LLSD(); - sd["id"] = getSculptID(); - sd["type"] = getSculptType(); - - return sd; + // Don't set it if at least one lod loaded + if (!mIsMeshAssetLoaded) + { + mIsMeshAssetUnavaliable = unavaliable; + } } -bool LLVolumeParams::sculptFromLLSD(LLSD& sd) +bool LLVolume::isMeshAssetUnavaliable() { - setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger()); - return true; + return mIsMeshAssetUnavaliable; } -LLSD LLVolumeParams::asLLSD() const +void LLVolume::copyFacesTo(std::vector &faces) const { - LLSD sd = LLSD(); - sd["path"] = mPathParams; - sd["profile"] = mProfileParams; - sd["sculpt"] = sculptAsLLSD(); - - return sd; + faces = mVolumeFaces; } -bool LLVolumeParams::fromLLSD(LLSD& sd) +void LLVolume::copyFacesFrom(const std::vector &faces) { - mPathParams.fromLLSD(sd["path"]); - mProfileParams.fromLLSD(sd["profile"]); - sculptFromLLSD(sd["sculpt"]); - - return true; + mVolumeFaces = faces; + mSculptLevel = 0; } -void LLVolumeParams::reduceS(F32 begin, F32 end) +void LLVolume::copyVolumeFaces(const LLVolume* volume) { - begin = llclampf(begin); - end = llclampf(end); - if (begin > end) - { - F32 temp = begin; - begin = end; - end = temp; - } - F32 a = mProfileParams.getBegin(); - F32 b = mProfileParams.getEnd(); - mProfileParams.setBegin(a + begin * (b - a)); - mProfileParams.setEnd(a + end * (b - a)); + mVolumeFaces = volume->mVolumeFaces; + mSculptLevel = 0; } -void LLVolumeParams::reduceT(F32 begin, F32 end) +bool LLVolume::cacheOptimize(bool gen_tangents) { - begin = llclampf(begin); - end = llclampf(end); - if (begin > end) - { - F32 temp = begin; - begin = end; - end = temp; - } - F32 a = mPathParams.getBegin(); - F32 b = mPathParams.getEnd(); - mPathParams.setBegin(a + begin * (b - a)); - mPathParams.setEnd(a + end * (b - a)); + for (S32 i = 0; i < mVolumeFaces.size(); ++i) + { + if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) + { + return false; + } + } + return true; } -const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity -const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity -// returns TRUE if the shape can be approximated with a convex shape -// for collison purposes -BOOL LLVolumeParams::isConvex() const +S32 LLVolume::getNumFaces() const { - if (!getSculptID().isNull()) - { - // can't determine, be safe and say no: - return FALSE; - } - - F32 path_length = mPathParams.getEnd() - mPathParams.getBegin(); - F32 hollow = mProfileParams.getHollow(); - - U8 path_type = mPathParams.getCurveType(); - if ( path_length > MIN_CONCAVE_PATH_WEDGE - && ( mPathParams.getTwist() != mPathParams.getTwistBegin() - || (hollow > 0.f - && LL_PCODE_PATH_LINE != path_type) ) ) - { - // twist along a "not too short" path is concave - return FALSE; - } - - F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin(); - BOOL same_hole = hollow == 0.f - || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME; - - F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE; - U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; - if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) - { - // it is a sphere and spheres get twice the minimum profile wedge - min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE; - } - - BOOL convex_profile = ( ( profile_length == 1.f - || profile_length <= 0.5f ) - && hollow == 0.f ) // trivially convex - || ( profile_length <= min_profile_wedge - && same_hole ); // effectvely convex (even when hollow) - - if (!convex_profile) - { - // profile is concave - return FALSE; - } - - if ( LL_PCODE_PATH_LINE == path_type ) - { - // straight paths with convex profile - return TRUE; - } - - BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f); - if (concave_path) - { - return FALSE; - } - - // we're left with spheres, toroids and tubes - if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) - { - // at this stage all spheres must be convex - return TRUE; - } - - // it's a toroid or tube - if ( path_length <= MIN_CONCAVE_PATH_WEDGE ) - { - // effectively convex - return TRUE; - } - - return FALSE; + return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size(); } -// debug -void LLVolumeParams::setCube() + +void LLVolume::createVolumeFaces() { - mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE); - mProfileParams.setBegin(0.f); - mProfileParams.setEnd(1.f); - mProfileParams.setHollow(0.f); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - mPathParams.setBegin(0.f); - mPathParams.setEnd(1.f); - mPathParams.setScale(1.f, 1.f); - mPathParams.setShear(0.f, 0.f); - mPathParams.setCurveType(LL_PCODE_PATH_LINE); - mPathParams.setTwistBegin(0.f); - mPathParams.setTwistEnd(0.f); - mPathParams.setRadiusOffset(0.f); - mPathParams.setTaper(0.f, 0.f); - mPathParams.setRevolutions(0.f); - mPathParams.setSkew(0.f); -} + if (mGenerateSingleFace) + { + // do nothing + } + else + { + S32 num_faces = getNumFaces(); + BOOL partial_build = TRUE; + if (num_faces != mVolumeFaces.size()) + { + partial_build = FALSE; + mVolumeFaces.resize(num_faces); + } + // Initialize volume faces with parameter data + for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++) + { + LLVolumeFace& vf = mVolumeFaces[i]; + LLProfile::Face& face = mProfilep->mFaces[i]; + vf.mBeginS = face.mIndex; + vf.mNumS = face.mCount; + if (vf.mNumS < 0) + { + LL_ERRS() << "Volume face corruption detected." << LL_ENDL; + } -LLFaceID LLVolume::generateFaceMask() -{ - LLFaceID new_mask = 0x0000; - - switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK) - { - case LL_PCODE_PROFILE_CIRCLE: - case LL_PCODE_PROFILE_CIRCLE_HALF: - new_mask |= LL_FACE_OUTER_SIDE_0; - break; - case LL_PCODE_PROFILE_SQUARE: - { - for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++) - { - new_mask |= LL_FACE_OUTER_SIDE_0 << side; - } - } - break; - case LL_PCODE_PROFILE_ISOTRI: - case LL_PCODE_PROFILE_EQUALTRI: - case LL_PCODE_PROFILE_RIGHTTRI: - { - for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++) - { - new_mask |= LL_FACE_OUTER_SIDE_0 << side; - } - } - break; - default: - LL_ERRS() << "Unknown profile!" << LL_ENDL; - break; - } - - // handle hollow objects - if (mParams.getProfileParams().getHollow() > 0) - { - new_mask |= LL_FACE_INNER_SIDE; - } - - // handle open profile curves - if (mProfilep->isOpen()) - { - new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END; - } - - // handle open path curves - if (mPathp->isOpen()) - { - new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END; - } - - return new_mask; -} + vf.mBeginT = 0; + vf.mNumT= getPath().mPath.size(); + vf.mID = i; -BOOL LLVolume::isFaceMaskValid(LLFaceID face_mask) -{ - LLFaceID test_mask = 0; - for(S32 i = 0; i < getNumFaces(); i++) - { - test_mask |= mProfilep->mFaces[i].mFaceID; - } + // Set the type mask bits correctly + if (mParams.getProfileParams().getHollow() > 0) + { + vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK; + } + if (mProfilep->isOpen()) + { + vf.mTypeMask |= LLVolumeFace::OPEN_MASK; + } + if (face.mCap) + { + vf.mTypeMask |= LLVolumeFace::CAP_MASK; + if (face.mFaceID == LL_FACE_PATH_BEGIN) + { + vf.mTypeMask |= LLVolumeFace::TOP_MASK; + } + else + { + llassert(face.mFaceID == LL_FACE_PATH_END); + vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK; + } + } + else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) + { + vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK; + } + else + { + vf.mTypeMask |= LLVolumeFace::SIDE_MASK; + if (face.mFlat) + { + vf.mTypeMask |= LLVolumeFace::FLAT_MASK; + } + if (face.mFaceID & LL_FACE_INNER_SIDE) + { + vf.mTypeMask |= LLVolumeFace::INNER_MASK; + if (face.mFlat && vf.mNumS > 2) + { //flat inner faces have to copy vert normals + vf.mNumS = vf.mNumS*2; + if (vf.mNumS < 0) + { + LL_ERRS() << "Volume face corruption detected." << LL_ENDL; + } + } + } + else + { + vf.mTypeMask |= LLVolumeFace::OUTER_MASK; + } + } + } - return test_mask == face_mask; + for (face_list_t::iterator iter = mVolumeFaces.begin(); + iter != mVolumeFaces.end(); ++iter) + { + (*iter).create(this, partial_build); + } + } } -BOOL LLVolume::isConvex() const + +inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b) { - // mParams.isConvex() may return FALSE even though the final - // geometry is actually convex due to LOD approximations. - // TODO -- provide LLPath and LLProfile with isConvex() methods - // that correctly determine convexity. -- Leviathan - return mParams.isConvex(); -} + // maps RGB values to vector values [0..255] -> [-0.5..0.5] + LLVector4a value; + LLVector4a sub(0.5f, 0.5f, 0.5f); + value.set(r,g,b); + value.mul(1.f/255.f); + value.sub(sub); -std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params) -{ - s << "{type=" << (U32) profile_params.mCurveType; - s << ", begin=" << profile_params.mBegin; - s << ", end=" << profile_params.mEnd; - s << ", hollow=" << profile_params.mHollow; - s << "}"; - return s; + return value; } - -std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params) +inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) { - s << "{type=" << (U32) path_params.mCurveType; - s << ", begin=" << path_params.mBegin; - s << ", end=" << path_params.mEnd; - s << ", twist=" << path_params.mTwistEnd; - s << ", scale=" << path_params.mScale; - s << ", shear=" << path_params.mShear; - s << ", twist_begin=" << path_params.mTwistBegin; - s << ", radius_offset=" << path_params.mRadiusOffset; - s << ", taper=" << path_params.mTaper; - s << ", revolutions=" << path_params.mRevolutions; - s << ", skew=" << path_params.mSkew; - s << "}"; - return s; + U32 index = (x + y * sculpt_width) * sculpt_components; + return index; } -std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params) +inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) { - s << "{profileparams = " << volume_params.mProfileParams; - s << ", pathparams = " << volume_params.mPathParams; - s << "}"; - return s; + U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); + U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); + + return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); } -std::ostream& operator<<(std::ostream &s, const LLProfile &profile) +inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data) { - s << " {open=" << (U32) profile.mOpen; - s << ", dirty=" << profile.mDirty; - s << ", totalout=" << profile.mTotalOut; - s << ", total=" << profile.mTotal; - s << "}"; - return s; -} + LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); + return v; +} -std::ostream& operator<<(std::ostream &s, const LLPath &path) +inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) { - s << "{open=" << (U32) path.mOpen; - s << ", dirty=" << path.mDirty; - s << ", step=" << path.mStep; - s << ", total=" << path.mTotal; - s << "}"; - return s; + U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); } -std::ostream& operator<<(std::ostream &s, const LLVolume &volume) +inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) { - s << "{params = " << volume.getParams(); - s << ", path = " << *volume.mPathp; - s << ", profile = " << *volume.mProfilep; - s << "}"; - return s; + U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); } -std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) -{ - s << "{params = " << volumep->getParams(); - s << ", path = " << *(volumep->mPathp); - s << ", profile = " << *(volumep->mProfilep); - s << "}"; - return s; -} - -LLVolumeFace::LLVolumeFace() : - mID(0), - mTypeMask(0), - mBeginS(0), - mBeginT(0), - mNumS(0), - mNumT(0), - mNumVertices(0), - mNumAllocatedVertices(0), - mNumIndices(0), - mPositions(NULL), - mNormals(NULL), - mTangents(NULL), - mTexCoords(NULL), - mIndices(NULL), - mWeights(NULL), -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - mJustWeights(NULL), - mJointIndices(NULL), -#endif - mWeightsScrubbed(FALSE), - mOctree(NULL), - mOctreeTriangles(NULL), - mOptimized(FALSE) +F32 LLVolume::sculptGetSurfaceArea() { - mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); - mExtents[0].splat(-0.5f); - mExtents[1].splat(0.5f); - mCenter = mExtents+2; -} + // test to see if image has enough variation to create non-degenerate geometry -LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) -: mID(0), - mTypeMask(0), - mBeginS(0), - mBeginT(0), - mNumS(0), - mNumT(0), - mNumVertices(0), - mNumAllocatedVertices(0), - mNumIndices(0), - mPositions(NULL), - mNormals(NULL), - mTangents(NULL), - mTexCoords(NULL), - mIndices(NULL), - mWeights(NULL), -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - mJustWeights(NULL), - mJointIndices(NULL), -#endif - mWeightsScrubbed(FALSE), - mOctree(NULL), - mOctreeTriangles(NULL) -{ - mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); - mCenter = mExtents+2; - *this = src; -} + F32 area = 0; -LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) -{ - if (&src == this) - { //self assignment, do nothing - return *this; - } - - mID = src.mID; - mTypeMask = src.mTypeMask; - mBeginS = src.mBeginS; - mBeginT = src.mBeginT; - mNumS = src.mNumS; - mNumT = src.mNumT; - - mExtents[0] = src.mExtents[0]; - mExtents[1] = src.mExtents[1]; - *mCenter = *src.mCenter; - - mNumVertices = 0; - mNumIndices = 0; - - freeData(); - - resizeVertices(src.mNumVertices); - resizeIndices(src.mNumIndices); - - if (mNumVertices) - { - S32 vert_size = mNumVertices*sizeof(LLVector4a); - S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; - - LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); - - if (src.mNormals) - { - LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); - } - - if(src.mTexCoords) - { - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); - } - - if (src.mTangents) - { - allocateTangents(src.mNumVertices); - LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); - } - else - { - ll_aligned_free_16(mTangents); - mTangents = NULL; - } - - if (src.mWeights) - { - llassert(!mWeights); // don't orphan an old alloc here accidentally - allocateWeights(src.mNumVertices); - LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); - mWeightsScrubbed = src.mWeightsScrubbed; - } - else - { - ll_aligned_free_16(mWeights); - mWeights = NULL; - mWeightsScrubbed = FALSE; - } + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); - #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - if (src.mJointIndices) + for (S32 s = 0; s < sizeS-1; s++) + { + for (S32 t = 0; t < sizeT-1; t++) { - llassert(!mJointIndices); // don't orphan an old alloc here accidentally - allocateJointIndices(src.mNumVertices); - LLVector4a::memcpyNonAliased16((F32*) mJointIndices, (F32*) src.mJointIndices, src.mNumVertices * sizeof(U8) * 4); + // get four corners of quad + LLVector4a& p1 = mMesh[(s )*sizeT + (t )]; + LLVector4a& p2 = mMesh[(s+1)*sizeT + (t )]; + LLVector4a& p3 = mMesh[(s )*sizeT + (t+1)]; + LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)]; + + // compute the area of the quad by taking the length of the cross product of the two triangles + LLVector4a v0,v1,v2,v3; + v0.setSub(p1,p2); + v1.setSub(p1,p3); + v2.setSub(p4,p2); + v3.setSub(p4,p3); + + LLVector4a cross1, cross2; + cross1.setCross3(v0,v1); + cross2.setCross3(v2,v3); + + //LLVector3 cross1 = (p1 - p2) % (p1 - p3); + //LLVector3 cross2 = (p4 - p2) % (p4 - p3); + + area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f; } - else*/ - { - ll_aligned_free_16(mJointIndices); - mJointIndices = NULL; - } - #endif - - } - - if (mNumIndices) - { - S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF; - - LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); - } - else - { - ll_aligned_free_16(mIndices); - mIndices = NULL; } - mOptimized = src.mOptimized; - mNormalizedScale = src.mNormalizedScale; - - //delete - return *this; + return area; } -LLVolumeFace::~LLVolumeFace() +// create empty placeholder shape +void LLVolume::sculptGenerateEmptyPlaceholder() { - ll_aligned_free_16(mExtents); - mExtents = NULL; - mCenter = NULL; + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + S32 line = 0; + + for (S32 s = 0; s < sizeS; s++) + { + for (S32 t = 0; t < sizeT; t++) + { + S32 i = t + line; + LLVector4a& pt = mMesh[i]; + + F32* p = pt.getF32ptr(); - freeData(); + p[0] = 0; + p[1] = 0; + p[2] = 0; + + llassert(pt.isFinite3()); + } + line += sizeT; + } } -void LLVolumeFace::freeData() +// create sphere placeholder shape +void LLVolume::sculptGenerateSpherePlaceholder() { - ll_aligned_free<64>(mPositions); - mPositions = NULL; + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); - //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately - mNormals = NULL; - mTexCoords = NULL; + S32 line = 0; - ll_aligned_free_16(mIndices); - mIndices = NULL; - ll_aligned_free_16(mTangents); - mTangents = NULL; - ll_aligned_free_16(mWeights); - mWeights = NULL; + for (S32 s = 0; s < sizeS; s++) + { + for (S32 t = 0; t < sizeT; t++) + { + S32 i = t + line; + LLVector4a& pt = mMesh[i]; -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - ll_aligned_free_16(mJointIndices); - mJointIndices = NULL; - ll_aligned_free_16(mJustWeights); - mJustWeights = NULL; -#endif - destroyOctree(); -} + F32 u = (F32)s / (sizeS - 1); + F32 v = (F32)t / (sizeT - 1); -BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + const F32 RADIUS = (F32) 0.3; - //tree for this face is no longer valid - destroyOctree(); + F32* p = pt.getF32ptr(); - LL_CHECK_MEMORY - BOOL ret = FALSE ; - if (mTypeMask & CAP_MASK) - { - ret = createCap(volume, partial_build); - LL_CHECK_MEMORY - } - else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) - { - ret = createSide(volume, partial_build); - LL_CHECK_MEMORY - } - else - { - LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL; - } - - return ret ; -} + p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); + p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); + p[2] = (F32)(cos(F_PI * v) * RADIUS); -void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) -{ - cv.setPosition(mPositions[index]); - if (mNormals) - { - cv.setNormal(mNormals[index]); - } - else - { - cv.getNormal().clear(); - } - - if (mTexCoords) - { - cv.mTexCoord = mTexCoords[index]; - } - else - { - cv.mTexCoord.clear(); - } + llassert(pt.isFinite3()); + } + line += sizeT; + } } -bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const +// create the vertices from the map +void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) { - return getPosition().equals3(rhs.getPosition()) && - mTexCoord == rhs.mTexCoord && - getNormal().equals3(rhs.getNormal()); -} + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; + BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; + BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR -bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const -{ - if (a.mV[0] != b.mV[0]) - { - return a.mV[0] < b.mV[0]; - } - - if (a.mV[1] != b.mV[1]) - { - return a.mV[1] < b.mV[1]; - } - - return a.mV[2] < b.mV[2]; -} + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); -void LLVolumeFace::remap() -{ - // Generate a remap buffer - std::vector remap(mNumVertices); - S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], - mIndices, - mNumIndices, - mPositions, - mNormals, - mTexCoords, - mNumVertices); + S32 line = 0; + for (S32 s = 0; s < sizeS; s++) + { + // Run along the profile. + for (S32 t = 0; t < sizeT; t++) + { + S32 i = t + line; + LLVector4a& pt = mMesh[i]; - // Allocate new buffers - S32 size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF; - U16* remap_indices = (U16*)ll_aligned_malloc_16(size); + S32 reversed_t = t; - S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size); - LLVector4a* remap_normals = remap_positions + remap_vertices_count; - LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count); + if (reverse_horizontal) + { + reversed_t = sizeT - t - 1; + } - // Fill the buffers - LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]); - LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]); - LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]); - LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]); + U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width); + U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); - // Free unused buffers - ll_aligned_free_16(mIndices); - ll_aligned_free<64>(mPositions); - // Tangets are now invalid - ll_aligned_free_16(mTangents); - mTangents = NULL; + if (y == 0) // top row stitching + { + // pinch? + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) + { + x = sculpt_width / 2; + } + } - // Assign new values - mIndices = remap_indices; - mPositions = remap_positions; - mNormals = remap_normals; - mTexCoords = remap_tex_coords; - mNumVertices = remap_vertices_count; - mNumAllocatedVertices = remap_vertices_count; -} + if (y == sculpt_height) // bottom row stitching + { + // wrap? + if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) + { + y = 0; + } + else + { + y = sculpt_height - 1; + } -void LLVolumeFace::optimize(F32 angle_cutoff) -{ - LLVolumeFace new_face; + // pinch? + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) + { + x = sculpt_width / 2; + } + } - //map of points to vector of vertices at that point - std::map > point_map; + if (x == sculpt_width) // side stitching + { + // wrap? + if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || + (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || + (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) + { + x = 0; + } - LLVector4a range; - range.setSub(mExtents[1],mExtents[0]); + else + { + x = sculpt_width - 1; + } + } - //remove redundant vertices - for (U32 i = 0; i < mNumIndices; ++i) - { - U16 index = mIndices[i]; + pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); - if (index >= mNumVertices) - { - // invalid index - // replace with a valid index to avoid crashes - index = mNumVertices - 1; - mIndices[i] = index; + if (sculpt_mirror) + { + LLVector4a scale(-1.f,1,1,1); + pt.mul(scale); + } - // Needs better logging - LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + llassert(pt.isFinite3()); } - LLVolumeFace::VertexData cv; - getVertexData(index, cv); - - BOOL found = FALSE; - - LLVector4a pos; - pos.setSub(mPositions[index], mExtents[0]); - pos.div(range); - - U64 pos64 = 0; - - pos64 = (U16) (pos[0]*65535); - pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); - pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); - - std::map >::iterator point_iter = point_map.find(pos64); - - if (point_iter != point_map.end()) - { //duplicate point might exist - for (U32 j = 0; j < point_iter->second.size(); ++j) - { - LLVolumeFace::VertexData& tv = (point_iter->second)[j]; - if (tv.compareNormal(cv, angle_cutoff)) - { - found = TRUE; - new_face.pushIndex((point_iter->second)[j].mIndex); - break; - } - } - } - - if (!found) - { - new_face.pushVertex(cv); - U16 index = (U16) new_face.mNumVertices-1; - new_face.pushIndex(index); - - VertexMapData d; - d.setPosition(cv.getPosition()); - d.mTexCoord = cv.mTexCoord; - d.setNormal(cv.getNormal()); - d.mIndex = index; - if (point_iter != point_map.end()) - { - point_iter->second.push_back(d); - } - else - { - point_map[pos64].push_back(d); - } - } - } - - - if (angle_cutoff > 1.f && !mNormals) - { - // Now alloc'd with positions - //ll_aligned_free_16(new_face.mNormals); - new_face.mNormals = NULL; - } - - if (!mTexCoords) - { - // Now alloc'd with positions - //ll_aligned_free_16(new_face.mTexCoords); - new_face.mTexCoords = NULL; - } - - // Only swap data if we've actually optimized the mesh - // - if (new_face.mNumVertices <= mNumVertices) - { - llassert(new_face.mNumIndices == mNumIndices); - swapData(new_face); - } - + line += sizeT; + } } -class LLVCacheTriangleData; -class LLVCacheVertexData -{ -public: - S32 mIdx; - S32 mCacheTag; - F64 mScore; - U32 mActiveTriangles; - std::vector mTriangles; - - LLVCacheVertexData() - { - mCacheTag = -1; - mScore = 0.0; - mActiveTriangles = 0; - mIdx = -1; - } -}; +const S32 SCULPT_REZ_1 = 6; // changed from 4 to 6 - 6 looks round whereas 4 looks square +const S32 SCULPT_REZ_2 = 8; +const S32 SCULPT_REZ_3 = 16; +const S32 SCULPT_REZ_4 = 32; -class LLVCacheTriangleData +S32 sculpt_sides(F32 detail) { -public: - bool mActive; - F64 mScore; - LLVCacheVertexData* mVertex[3]; - - LLVCacheTriangleData() - { - mActive = true; - mScore = 0.0; - mVertex[0] = mVertex[1] = mVertex[2] = NULL; - } - - void complete() - { - mActive = false; - for (S32 i = 0; i < 3; ++i) - { - if (mVertex[i]) - { - llassert(mVertex[i]->mActiveTriangles > 0); - mVertex[i]->mActiveTriangles--; - } - } - } - - bool operator<(const LLVCacheTriangleData& rhs) const - { //highest score first - return rhs.mScore < mScore; - } -}; -const F64 FindVertexScore_CacheDecayPower = 1.5; -const F64 FindVertexScore_LastTriScore = 0.75; -const F64 FindVertexScore_ValenceBoostScale = 2.0; -const F64 FindVertexScore_ValenceBoostPower = 0.5; -const U32 MaxSizeVertexCache = 32; -const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3); + // detail is usually one of: 1, 1.5, 2.5, 4.0. -F64 find_vertex_score(LLVCacheVertexData& data) + if (detail <= 1.0) + { + return SCULPT_REZ_1; + } + if (detail <= 2.0) + { + return SCULPT_REZ_2; + } + if (detail <= 3.0) + { + return SCULPT_REZ_3; + } + else + { + return SCULPT_REZ_4; + } +} + + + +// determine the number of vertices in both s and t direction for this sculpt +void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t) { - F64 score = -1.0; + // this code has the following properties: + // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map + // while still using all available verts + // 2) the mesh cannot have more verts than is allowed by LOD + // 3) the mesh cannot have more verts than is allowed by the map - score = 0.0; + S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0); + S32 max_vertices_map = width * height / 4; - S32 cache_idx = data.mCacheTag; + S32 vertices; + if (max_vertices_map > 0) + vertices = llmin(max_vertices_lod, max_vertices_map); + else + vertices = max_vertices_lod; - if (cache_idx < 0) - { - //not in cache - } - else - { - if (cache_idx < 3) - { //vertex was in the last triangle - score = FindVertexScore_LastTriScore; - } - else - { //more points for being higher in the cache - score = 1.0-((cache_idx-3)*FindVertexScore_Scaler); - score = pow(score, FindVertexScore_CacheDecayPower); - } - } - //bonus points for having low valence - F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); - score += FindVertexScore_ValenceBoostScale * valence_boost; + F32 ratio; + if ((width == 0) || (height == 0)) + ratio = 1.f; + else + ratio = (F32) width / (F32) height; - return score; -} -class LLVCacheFIFO -{ -public: - LLVCacheVertexData* mCache[MaxSizeVertexCache]; - U32 mMisses; - - LLVCacheFIFO() - { - mMisses = 0; - for (U32 i = 0; i < MaxSizeVertexCache; ++i) - { - mCache[i] = NULL; - } - } - - void addVertex(LLVCacheVertexData* data) - { - if (data->mCacheTag == -1) - { - mMisses++; - - S32 end = MaxSizeVertexCache-1; - - if (mCache[end]) - { - mCache[end]->mCacheTag = -1; - } - - for (S32 i = end; i > 0; --i) - { - mCache[i] = mCache[i-1]; - if (mCache[i]) - { - mCache[i]->mCacheTag = i; - } - } - - mCache[0] = data; - data->mCacheTag = 0; - } - } -}; + s = (S32)(F32) sqrt(((F32)vertices / ratio)); -class LLVCacheLRU -{ -public: - LLVCacheVertexData* mCache[MaxSizeVertexCache+3]; - - LLVCacheTriangleData* mBestTriangle; - - U32 mMisses; - - LLVCacheLRU() - { - for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) - { - mCache[i] = NULL; - } - - mBestTriangle = NULL; - mMisses = 0; - } - - void addVertex(LLVCacheVertexData* data) - { - S32 end = MaxSizeVertexCache+2; - if (data->mCacheTag != -1) - { //just moving a vertex to the front of the cache - end = data->mCacheTag; - } - else - { - mMisses++; - if (mCache[end]) - { //adding a new vertex, vertex at end of cache falls off - mCache[end]->mCacheTag = -1; - } - } - - for (S32 i = end; i > 0; --i) - { //adjust cache pointers and tags - mCache[i] = mCache[i-1]; - - if (mCache[i]) - { - mCache[i]->mCacheTag = i; - } - } - - mCache[0] = data; - mCache[0]->mCacheTag = 0; - } - - void addTriangle(LLVCacheTriangleData* data) - { - addVertex(data->mVertex[0]); - addVertex(data->mVertex[1]); - addVertex(data->mVertex[2]); - } - - void updateScores() - { - LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; - LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; - - while(data_iter != end_data) - { - LLVCacheVertexData* data = *data_iter++; - //trailing 3 vertices aren't actually in the cache for scoring purposes - if (data) - { - data->mCacheTag = -1; - } - } - - data_iter = mCache; - end_data = mCache+MaxSizeVertexCache; - - while (data_iter != end_data) - { //update scores of vertices in cache - LLVCacheVertexData* data = *data_iter++; - if (data) - { - data->mScore = find_vertex_score(*data); - } - } - - mBestTriangle = NULL; - //update triangle scores - data_iter = mCache; - end_data = mCache+MaxSizeVertexCache+3; - - while (data_iter != end_data) - { - LLVCacheVertexData* data = *data_iter++; - if (data) - { - for (std::vector::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter) - { - LLVCacheTriangleData* tri = *iter; - if (tri->mActive) - { - tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0; - tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0; - tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0; - - if (!mBestTriangle || mBestTriangle->mScore < tri->mScore) - { - mBestTriangle = tri; - } - } - } - } - } - - //knock trailing 3 vertices off the cache - data_iter = mCache+MaxSizeVertexCache; - end_data = mCache+MaxSizeVertexCache+3; - while (data_iter != end_data) - { - LLVCacheVertexData* data = *data_iter; - if (data) - { - llassert(data->mCacheTag == -1); - *data_iter = NULL; - } - ++data_iter; - } - } -}; + s = llmax(s, 4); // no degenerate sizes, please + t = vertices / s; -// data structures for tangent generation + t = llmax(t, 4); // no degenerate sizes, please + s = vertices / t; +} -struct MikktData +// sculpt replaces generate() for sculpted surfaces +void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder) { - LLVolumeFace* face; - std::vector p; - std::vector n; - std::vector tc; - std::vector w; - std::vector t; + U8 sculpt_type = mParams.getSculptType(); - MikktData(LLVolumeFace* f) - : face(f) + BOOL data_is_empty = FALSE; + + if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) { - U32 count = face->mNumIndices; + sculpt_level = -1; + data_is_empty = TRUE; + } - p.resize(count); - n.resize(count); - tc.resize(count); - t.resize(count); + S32 requested_sizeS = 0; + S32 requested_sizeT = 0; - if (face->mWeights) - { - w.resize(count); - } + sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); + mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); + mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); - LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); - + S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got + S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got - for (int i = 0; i < face->mNumIndices; ++i) - { - U32 idx = face->mIndices[i]; + // weird crash bug - DEV-11158 - trying to collect more data: + if ((sizeS == 0) || (sizeT == 0)) + { + LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL; + } - p[i].set(face->mPositions[idx].getF32ptr()); - p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents - n[i].set(face->mNormals[idx].getF32ptr()); - n[i].scaleVec(inv_scale); - n[i].normalize(); - tc[i].set(face->mTexCoords[idx]); + sNumMeshPoints -= mMesh.size(); + mMesh.resize(sizeS * sizeT); + sNumMeshPoints += mMesh.size(); - if (idx >= face->mNumVertices) - { - // invalid index - // replace with a valid index to avoid crashes - idx = face->mNumVertices - 1; - face->mIndices[i] = idx; + //generate vertex positions + if (!data_is_empty) + { + sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); - // Needs better logging - LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; - } + // don't test lowest LOD to support legacy content DEV-33670 + if (mDetail > SCULPT_MIN_AREA_DETAIL) + { + F32 area = sculptGetSurfaceArea(); - if (face->mWeights) + mSurfaceArea = area; + + const F32 SCULPT_MAX_AREA = 384.f; + + if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) { - w[i].set(face->mWeights[idx].getF32ptr()); + data_is_empty = TRUE; + visible_placeholder = true; } } } - uint32_t GetNumFaces() - { - return uint32_t(face->mNumIndices / 3); - } - - uint32_t GetNumVerticesOfFace(const uint32_t face_num) - { - return 3; - } - - mikk::float3 GetPosition(const uint32_t face_num, const uint32_t vert_num) - { - F32* v = p[face_num * 3 + vert_num].mV; - return mikk::float3(v); - } - - mikk::float3 GetTexCoord(const uint32_t face_num, const uint32_t vert_num) - { - F32* uv = tc[face_num * 3 + vert_num].mV; - return mikk::float3(uv[0], uv[1], 1.0f); - } - - mikk::float3 GetNormal(const uint32_t face_num, const uint32_t vert_num) - { - F32* normal = n[face_num * 3 + vert_num].mV; - return mikk::float3(normal); - } - - void SetTangentSpace(const uint32_t face_num, const uint32_t vert_num, mikk::float3 T, bool orientation) - { - S32 i = face_num * 3 + vert_num; - t[i].set(T.x, T.y, T.z, orientation ? 1.0f : -1.0f); - } -}; + if (data_is_empty) + { + if (visible_placeholder) + { + // Object should be visible since there will be nothing else to display + sculptGenerateSpherePlaceholder(); + } + else + { + sculptGenerateEmptyPlaceholder(); + } + } -bool LLVolumeFace::cacheOptimize(bool gen_tangents) -{ //optimize for vertex cache according to Forsyth method: - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - llassert(!mOptimized); - mOptimized = TRUE; - if (gen_tangents && mNormals && mTexCoords) - { // generate mikkt space tangents before cache optimizing since the index buffer may change - // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh - // and is executed on a background thread - MikktData data(this); - mikk::Mikktspace ctx(data); - ctx.genTangSpace(); - //re-weld - meshopt_Stream mos[] = - { - { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, - { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, - { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } - }; + for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) + { + mFaceMask |= mProfilep->mFaces[i].mFaceID; + } - std::vector remap; - remap.resize(data.p.size()); + mSculptLevel = sculpt_level; - U32 stream_count = data.w.empty() ? 4 : 5; + // Delete any existing faces so that they get regenerated + mVolumeFaces.clear(); - size_t vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); + createVolumeFaces(); +} - if (vert_count < 65535 && vert_count != 0) - { - //copy results back into volume - resizeVertices(vert_count); - if (!data.w.empty()) - { - allocateWeights(vert_count); - } - allocateTangents(mNumVertices); - for (int i = 0; i < mNumIndices; ++i) - { - U32 src_idx = i; - U32 dst_idx = remap[i]; - if (dst_idx >= mNumVertices) - { +BOOL LLVolume::isCap(S32 face) +{ + return mProfilep->mFaces[face].mCap; +} + +BOOL LLVolume::isFlat(S32 face) +{ + return mProfilep->mFaces[face].mFlat; +} + + +bool LLVolumeParams::isSculpt() const +{ + return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE; +} + +bool LLVolumeParams::isMeshSculpt() const +{ + return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH; +} + +bool LLVolumeParams::operator==(const LLVolumeParams ¶ms) const +{ + return ( (getPathParams() == params.getPathParams()) && + (getProfileParams() == params.getProfileParams()) && + (mSculptID == params.mSculptID) && + (mSculptType == params.mSculptType) ); +} + +bool LLVolumeParams::operator!=(const LLVolumeParams ¶ms) const +{ + return ( (getPathParams() != params.getPathParams()) || + (getProfileParams() != params.getProfileParams()) || + (mSculptID != params.mSculptID) || + (mSculptType != params.mSculptType) ); +} + +bool LLVolumeParams::operator<(const LLVolumeParams ¶ms) const +{ + if( getPathParams() != params.getPathParams() ) + { + return getPathParams() < params.getPathParams(); + } + + if (getProfileParams() != params.getProfileParams()) + { + return getProfileParams() < params.getProfileParams(); + } + + if (mSculptID != params.mSculptID) + { + return mSculptID < params.mSculptID; + } + + return mSculptType < params.mSculptType; + + +} + +void LLVolumeParams::copyParams(const LLVolumeParams ¶ms) +{ + mProfileParams.copyParams(params.mProfileParams); + mPathParams.copyParams(params.mPathParams); + mSculptID = params.getSculptID(); + mSculptType = params.getSculptType(); +} + +// Less restricitve approx 0 for volumes +const F32 APPROXIMATELY_ZERO = 0.001f; +bool approx_zero( F32 f, F32 tolerance = APPROXIMATELY_ZERO) +{ + return (f >= -tolerance) && (f <= tolerance); +} + +// return true if in range (or nearly so) +static bool limit_range(F32& v, F32 min, F32 max, F32 tolerance = APPROXIMATELY_ZERO) +{ + F32 min_delta = v - min; + if (min_delta < 0.f) + { + v = min; + if (!approx_zero(min_delta, tolerance)) + return false; + } + F32 max_delta = max - v; + if (max_delta < 0.f) + { + v = max; + if (!approx_zero(max_delta, tolerance)) + return false; + } + return true; +} + +bool LLVolumeParams::setBeginAndEndS(const F32 b, const F32 e) +{ + bool valid = true; + + // First, clamp to valid ranges. + F32 begin = b; + valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); + + F32 end = e; + if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error + valid &= limit_range(end, MIN_CUT_DELTA, 1.f); + + valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); + + // Now set them. + mProfileParams.setBegin(begin); + mProfileParams.setEnd(end); + + return valid; +} + +bool LLVolumeParams::setBeginAndEndT(const F32 b, const F32 e) +{ + bool valid = true; + + // First, clamp to valid ranges. + F32 begin = b; + valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); + + F32 end = e; + valid &= limit_range(end, MIN_CUT_DELTA, 1.f); + + valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); + + // Now set them. + mPathParams.setBegin(begin); + mPathParams.setEnd(end); + + return valid; +} + +bool LLVolumeParams::setHollow(const F32 h) +{ + // Validate the hollow based on path and profile. + U8 profile = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; + U8 hole_type = mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK; + + F32 max_hollow = HOLLOW_MAX; + + // Only square holes have trouble. + if (LL_PCODE_HOLE_SQUARE == hole_type) + { + switch(profile) + { + case LL_PCODE_PROFILE_CIRCLE: + case LL_PCODE_PROFILE_CIRCLE_HALF: + case LL_PCODE_PROFILE_EQUALTRI: + max_hollow = HOLLOW_MAX_SQUARE; + } + } + + F32 hollow = h; + bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow); + mProfileParams.setHollow(hollow); + + return valid; +} + +bool LLVolumeParams::setTwistBegin(const F32 b) +{ + F32 twist_begin = b; + bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX); + mPathParams.setTwistBegin(twist_begin); + return valid; +} + +bool LLVolumeParams::setTwistEnd(const F32 e) +{ + F32 twist_end = e; + bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX); + mPathParams.setTwistEnd(twist_end); + return valid; +} + +bool LLVolumeParams::setRatio(const F32 x, const F32 y) +{ + F32 min_x = RATIO_MIN; + F32 max_x = RATIO_MAX; + F32 min_y = RATIO_MIN; + F32 max_y = RATIO_MAX; + // If this is a circular path (and not a sphere) then 'ratio' is actually hole size. + U8 path_type = mPathParams.getCurveType(); + U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; + if ( LL_PCODE_PATH_CIRCLE == path_type && + LL_PCODE_PROFILE_CIRCLE_HALF != profile_type) + { + // Holes are more restricted... + min_x = HOLE_X_MIN; + max_x = HOLE_X_MAX; + min_y = HOLE_Y_MIN; + max_y = HOLE_Y_MAX; + } + + F32 ratio_x = x; + bool valid = limit_range(ratio_x, min_x, max_x); + F32 ratio_y = y; + valid &= limit_range(ratio_y, min_y, max_y); + + mPathParams.setScale(ratio_x, ratio_y); + + return valid; +} + +bool LLVolumeParams::setShear(const F32 x, const F32 y) +{ + F32 shear_x = x; + bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX); + F32 shear_y = y; + valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX); + mPathParams.setShear(shear_x, shear_y); + return valid; +} + +bool LLVolumeParams::setTaperX(const F32 v) +{ + F32 taper = v; + bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); + mPathParams.setTaperX(taper); + return valid; +} + +bool LLVolumeParams::setTaperY(const F32 v) +{ + F32 taper = v; + bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); + mPathParams.setTaperY(taper); + return valid; +} + +bool LLVolumeParams::setRevolutions(const F32 r) +{ + F32 revolutions = r; + bool valid = limit_range(revolutions, REV_MIN, REV_MAX); + mPathParams.setRevolutions(revolutions); + return valid; +} + +bool LLVolumeParams::setRadiusOffset(const F32 offset) +{ + bool valid = true; + + // If this is a sphere, just set it to 0 and get out. + U8 path_type = mPathParams.getCurveType(); + U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; + if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type || + LL_PCODE_PATH_CIRCLE != path_type ) + { + mPathParams.setRadiusOffset(0.f); + return true; + } + + // Limit radius offset, based on taper and hole size y. + F32 radius_offset = offset; + F32 taper_y = getTaperY(); + F32 radius_mag = fabs(radius_offset); + F32 hole_y_mag = fabs(getRatioY()); + F32 taper_y_mag = fabs(taper_y); + // Check to see if the taper effects us. + if ( (radius_offset > 0.f && taper_y < 0.f) || + (radius_offset < 0.f && taper_y > 0.f) ) + { + // The taper does not help increase the radius offset range. + taper_y_mag = 0.f; + } + F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag); + + // Enforce the maximum magnitude. + F32 delta = max_radius_mag - radius_mag; + if (delta < 0.f) + { + // Check radius offset sign. + if (radius_offset < 0.f) + { + radius_offset = -max_radius_mag; + } + else + { + radius_offset = max_radius_mag; + } + valid = approx_zero(delta, .1f); + } + + mPathParams.setRadiusOffset(radius_offset); + return valid; +} + +bool LLVolumeParams::setSkew(const F32 skew_value) +{ + bool valid = true; + + // Check the skew value against the revolutions. + F32 skew = llclamp(skew_value, SKEW_MIN, SKEW_MAX); + F32 skew_mag = fabs(skew); + F32 revolutions = getRevolutions(); + F32 scale_x = getRatioX(); + F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f); + // Discontinuity; A revolution of 1 allows skews below 0.5. + if ( fabs(revolutions - 1.0f) < 0.001) + min_skew_mag = 0.0f; + + // Clip skew. + F32 delta = skew_mag - min_skew_mag; + if (delta < 0.f) + { + // Check skew sign. + if (skew < 0.0f) + { + skew = -min_skew_mag; + } + else + { + skew = min_skew_mag; + } + valid = approx_zero(delta, .01f); + } + + mPathParams.setSkew(skew); + return valid; +} + +bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type) +{ + mSculptID = sculpt_id; + mSculptType = sculpt_type; + return true; +} + +bool LLVolumeParams::setType(U8 profile, U8 path) +{ + bool result = true; + // First, check profile and path for validity. + U8 profile_type = profile & LL_PCODE_PROFILE_MASK; + U8 hole_type = (profile & LL_PCODE_HOLE_MASK) >> 4; + U8 path_type = path >> 4; + + if (profile_type > LL_PCODE_PROFILE_MAX) + { + // Bad profile. Make it square. + profile = LL_PCODE_PROFILE_SQUARE; + result = false; + LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type + << ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL; + } + else if (hole_type > LL_PCODE_HOLE_MAX) + { + // Bad hole. Make it the same. + profile = profile_type; + result = false; + LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type + << ") to be LL_PCODE_HOLE_SAME" << LL_ENDL; + } + + if (path_type < LL_PCODE_PATH_MIN || + path_type > LL_PCODE_PATH_MAX) + { + // Bad path. Make it linear. + result = false; + LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path + << ") to be LL_PCODE_PATH_LINE" << LL_ENDL; + path = LL_PCODE_PATH_LINE; + } + + mProfileParams.setCurveType(profile); + mPathParams.setCurveType(path); + return result; +} + +// static +bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, + U8 path_curve, F32 path_begin, F32 path_end, + F32 scx, F32 scy, F32 shx, F32 shy, + F32 twistend, F32 twistbegin, F32 radiusoffset, + F32 tx, F32 ty, F32 revolutions, F32 skew) +{ + LLVolumeParams test_params; + if (!test_params.setType (prof_curve, path_curve)) + { + return false; + } + if (!test_params.setBeginAndEndS (prof_begin, prof_end)) + { + return false; + } + if (!test_params.setBeginAndEndT (path_begin, path_end)) + { + return false; + } + if (!test_params.setHollow (hollow)) + { + return false; + } + if (!test_params.setTwistBegin (twistbegin)) + { + return false; + } + if (!test_params.setTwistEnd (twistend)) + { + return false; + } + if (!test_params.setRatio (scx, scy)) + { + return false; + } + if (!test_params.setShear (shx, shy)) + { + return false; + } + if (!test_params.setTaper (tx, ty)) + { + return false; + } + if (!test_params.setRevolutions (revolutions)) + { + return false; + } + if (!test_params.setRadiusOffset (radiusoffset)) + { + return false; + } + if (!test_params.setSkew (skew)) + { + return false; + } + return true; +} + +void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts) +{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the + //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + F32 detail[] = {1.f, 1.5f, 2.5f, 4.f}; + for (S32 i = 0; i < 4; i++) + { + S32 count = 0; + S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]); + S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]); + + count = (profile_points-1)*2*(path_points-1); + count += profile_points*2; + + counts[i] = count; + } +} + + +S32 LLVolume::getNumTriangles(S32* vcount) const +{ + U32 triangle_count = 0; + U32 vertex_count = 0; + + for (S32 i = 0; i < getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = getVolumeFace(i); + triangle_count += face.mNumIndices/3; + + vertex_count += face.mNumVertices; + } + + + if (vcount) + { + *vcount = vertex_count; + } + + return triangle_count; +} + + +//----------------------------------------------------------------------------- +// generateSilhouetteVertices() +//----------------------------------------------------------------------------- +void LLVolume::generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + const LLVector3& obj_cam_vec_in, + const LLMatrix4& mat_in, + const LLMatrix3& norm_mat_in, + S32 face_mask) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + + LLMatrix4a mat; + mat.loadu(mat_in); + + LLMatrix4a norm_mat; + norm_mat.loadu(norm_mat_in); + + LLVector4a obj_cam_vec; + obj_cam_vec.load3(obj_cam_vec_in.mV); + + vertices.clear(); + normals.clear(); + + if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { + return; + } + + S32 cur_index = 0; + //for each face + for (face_list_t::iterator iter = mVolumeFaces.begin(); + iter != mVolumeFaces.end(); ++iter) + { + LLVolumeFace& face = *iter; + + if (!(face_mask & (0x1 << cur_index++)) || + face.mNumIndices == 0 || face.mEdge.empty()) + { + continue; + } + + if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) + { + LLVector4a* v = (LLVector4a*)face.mPositions; + LLVector4a* n = (LLVector4a*)face.mNormals; + + for (U32 j = 0; j < face.mNumIndices / 3; j++) + { + for (S32 k = 0; k < 3; k++) + { + S32 index = face.mEdge[j * 3 + k]; + + if (index == -1) + { + // silhouette edge, currently only cubes, so no other conditions + + S32 v1 = face.mIndices[j * 3 + k]; + S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)]; + + LLVector4a t; + mat.affineTransform(v[v1], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v1], t); + + t.normalize3fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); + + mat.affineTransform(v[v2], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v2], t); + t.normalize3fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); + } + } + } + + } + else + { + + //============================================== + //DEBUG draw edge map instead of silhouette edge + //============================================== + +#if DEBUG_SILHOUETTE_EDGE_MAP + + //for each triangle + U32 tri_count = face.mNumIndices / 3; + for (U32 j = 0; j < tri_count; j++) { + //get vertices + S32 v1 = face.mIndices[j*3+0]; + S32 v2 = face.mIndices[j*3+1]; + S32 v3 = face.mIndices[j*3+2]; + + //get current face center + LLVector3 cCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; + + //for each edge + for (S32 k = 0; k < 3; k++) { + S32 nIndex = face.mEdge[j*3+k]; + if (nIndex <= -1) { + continue; + } + + if (nIndex >= (S32)tri_count) { + continue; + } + //get neighbor vertices + v1 = face.mIndices[nIndex*3+0]; + v2 = face.mIndices[nIndex*3+1]; + v3 = face.mIndices[nIndex*3+2]; + + //get neighbor face center + LLVector3 nCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; + + //draw line + vertices.push_back(cCenter); + vertices.push_back(nCenter); + normals.push_back(LLVector3(1,1,1)); + normals.push_back(LLVector3(1,1,1)); + segments.push_back(vertices.size()); + } + } + + continue; + + //============================================== + //DEBUG + //============================================== + + //============================================== + //DEBUG draw normals instead of silhouette edge + //============================================== +#elif DEBUG_SILHOUETTE_NORMALS + + //for each vertex + for (U32 j = 0; j < face.mNumVertices; j++) { + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); + normals.push_back(LLVector3(0,0,1)); + normals.push_back(LLVector3(0,0,1)); + segments.push_back(vertices.size()); +#if DEBUG_SILHOUETTE_BINORMALS + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f); + normals.push_back(LLVector3(0,0,1)); + normals.push_back(LLVector3(0,0,1)); + segments.push_back(vertices.size()); +#endif + } + + continue; +#else + //============================================== + //DEBUG + //============================================== + + static const U8 AWAY = 0x01, + TOWARDS = 0x02; + + //for each triangle + std::vector fFacing; + vector_append(fFacing, face.mNumIndices/3); + + LLVector4a* v = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (U32 j = 0; j < face.mNumIndices/3; j++) + { + //approximate normal + S32 v1 = face.mIndices[j*3+0]; + S32 v2 = face.mIndices[j*3+1]; + S32 v3 = face.mIndices[j*3+2]; + + LLVector4a c1,c2; + c1.setSub(v[v1], v[v2]); + c2.setSub(v[v2], v[v3]); + + LLVector4a norm; + + norm.setCross3(c1, c2); + + if (norm.dot3(norm) < 0.00000001f) + { + fFacing[j] = AWAY | TOWARDS; + } + else + { + //get view vector + LLVector4a view; + view.setSub(obj_cam_vec, v[v1]); + bool away = view.dot3(norm) > 0.0f; + if (away) + { + fFacing[j] = AWAY; + } + else + { + fFacing[j] = TOWARDS; + } + } + } + + //for each triangle + for (U32 j = 0; j < face.mNumIndices/3; j++) + { + if (fFacing[j] == (AWAY | TOWARDS)) + { //this is a degenerate triangle + //take neighbor facing (degenerate faces get facing of one of their neighbors) + // *FIX IF NEEDED: this does not deal with neighboring degenerate faces + for (S32 k = 0; k < 3; k++) + { + S32 index = face.mEdge[j*3+k]; + if (index != -1) + { + fFacing[j] = fFacing[index]; + break; + } + } + continue; //skip degenerate face + } + + //for each edge + for (S32 k = 0; k < 3; k++) { + S32 index = face.mEdge[j*3+k]; + if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) { + //our neighbor is degenerate, make him face our direction + fFacing[face.mEdge[j*3+k]] = fFacing[j]; + continue; + } + + if (index == -1 || //edge has no neighbor, MUST be a silhouette edge + (fFacing[index] & fFacing[j]) == 0) { //we found a silhouette edge + + S32 v1 = face.mIndices[j*3+k]; + S32 v2 = face.mIndices[j*3+((k+1)%3)]; + + LLVector4a t; + mat.affineTransform(v[v1], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v1], t); + + t.normalize3fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); + + mat.affineTransform(v[v2], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v2], t); + t.normalize3fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); + } + } + } +#endif + } + } +} + +S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out) +{ + S32 hit_face = -1; + + S32 start_face; + S32 end_face; + + if (face == -1) // ALL_SIDES + { + start_face = 0; + end_face = getNumVolumeFaces() - 1; + } + else + { + start_face = face; + end_face = face; + } + + LLVector4a dir; + dir.setSub(end, start); + + F32 closest_t = 2.f; // must be larger than 1 + + end_face = llmin(end_face, getNumVolumeFaces()-1); + + for (S32 i = start_face; i <= end_face; i++) + { + LLVolumeFace &face = mVolumeFaces[i]; + + LLVector4a box_center; + box_center.setAdd(face.mExtents[0], face.mExtents[1]); + box_center.mul(0.5f); + + LLVector4a box_size; + box_size.setSub(face.mExtents[1], face.mExtents[0]); + + if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) + { + if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them + { + genTangents(i); + } + + if (isUnique()) + { //don't bother with an octree for flexi volumes + U32 tri_count = face.mNumIndices/3; + + for (U32 j = 0; j < tri_count; ++j) + { + U16 idx0 = face.mIndices[j*3+0]; + U16 idx1 = face.mIndices[j*3+1]; + U16 idx2 = face.mIndices[j*3+2]; + + const LLVector4a& v0 = face.mPositions[idx0]; + const LLVector4a& v1 = face.mPositions[idx1]; + const LLVector4a& v2 = face.mPositions[idx2]; + + F32 a,b,t; + + if (LLTriangleRayIntersect(v0, v1, v2, + start, dir, a, b, t)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < closest_t)) // and this hit is closer + { + closest_t = t; + hit_face = i; + + if (intersection != NULL) + { + LLVector4a intersect = dir; + intersect.mul(closest_t); + intersect.add(start); + *intersection = intersect; + } + + + if (tex_coord != NULL) + { + LLVector2* tc = (LLVector2*) face.mTexCoords; + *tex_coord = ((1.f - a - b) * tc[idx0] + + a * tc[idx1] + + b * tc[idx2]); + + } + + if (normal!= NULL) + { + LLVector4a* norm = face.mNormals; + + LLVector4a n1,n2,n3; + n1 = norm[idx0]; + n1.mul(1.f-a-b); + + n2 = norm[idx1]; + n2.mul(a); + + n3 = norm[idx2]; + n3.mul(b); + + n1.add(n2); + n1.add(n3); + + *normal = n1; + } + + if (tangent_out != NULL) + { + LLVector4a* tangents = face.mTangents; + + LLVector4a t1,t2,t3; + t1 = tangents[idx0]; + t1.mul(1.f-a-b); + + t2 = tangents[idx1]; + t2.mul(a); + + t3 = tangents[idx2]; + t3.mul(b); + + t1.add(t2); + t1.add(t3); + + *tangent_out = t1; + } + } + } + } + } + else + { + if (!face.getOctree()) + { + face.createOctree(); + } + + LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); + intersect.traverse(face.getOctree()); + if (intersect.mHitFace) + { + hit_face = i; + } + } + } + } + + + return hit_face; +} + +class LLVertexIndexPair +{ +public: + LLVertexIndexPair(const LLVector3 &vertex, const S32 index); + + LLVector3 mVertex; + S32 mIndex; +}; + +LLVertexIndexPair::LLVertexIndexPair(const LLVector3 &vertex, const S32 index) +{ + mVertex = vertex; + mIndex = index; +} + +const F32 VERTEX_SLOP = 0.00001f; + +struct lessVertex +{ + bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b) + { + const F32 slop = VERTEX_SLOP; + + if (a->mVertex.mV[0] + slop < b->mVertex.mV[0]) + { + return TRUE; + } + else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0]) + { + return FALSE; + } + + if (a->mVertex.mV[1] + slop < b->mVertex.mV[1]) + { + return TRUE; + } + else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1]) + { + return FALSE; + } + + if (a->mVertex.mV[2] + slop < b->mVertex.mV[2]) + { + return TRUE; + } + else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2]) + { + return FALSE; + } + + return FALSE; + } +}; + +struct lessTriangle +{ + bool operator()(const S32 *a, const S32 *b) + { + if (*a < *b) + { + return TRUE; + } + else if (*a > *b) + { + return FALSE; + } + + if (*(a+1) < *(b+1)) + { + return TRUE; + } + else if (*(a+1) > *(b+1)) + { + return FALSE; + } + + if (*(a+2) < *(b+2)) + { + return TRUE; + } + else if (*(a+2) > *(b+2)) + { + return FALSE; + } + + return FALSE; + } +}; + +BOOL equalTriangle(const S32 *a, const S32 *b) +{ + if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2))) + { + return TRUE; + } + return FALSE; +} + +BOOL LLVolumeParams::importFile(LLFILE *fp) +{ + //LL_INFOS() << "importing volume" << LL_ENDL; + const S32 BUFSIZE = 16384; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + // *NOTE: changing the size or type of this buffer will require + // changing the sscanf below. + char keyword[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + + while (!feof(fp)) + { + if (fgets(buffer, BUFSIZE, fp) == NULL) + { + buffer[0] = '\0'; + } + + sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */ + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("profile", keyword)) + { + mProfileParams.importFile(fp); + } + else if (!strcmp("path",keyword)) + { + mPathParams.importFile(fp); + } + else + { + LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; + } + } + + return TRUE; +} + +BOOL LLVolumeParams::exportFile(LLFILE *fp) const +{ + fprintf(fp,"\tshape 0\n"); + fprintf(fp,"\t{\n"); + mPathParams.exportFile(fp); + mProfileParams.exportFile(fp); + fprintf(fp, "\t}\n"); + return TRUE; +} + + +BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream) +{ + //LL_INFOS() << "importing volume" << LL_ENDL; + const S32 BUFSIZE = 16384; + // *NOTE: changing the size or type of this buffer will require + // changing the sscanf below. + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + char keyword[256]; /* Flawfinder: ignore */ + keyword[0] = 0; + + while (input_stream.good()) + { + input_stream.getline(buffer, BUFSIZE); + sscanf(buffer, " %255s", keyword); + if (!strcmp("{", keyword)) + { + continue; + } + if (!strcmp("}",keyword)) + { + break; + } + else if (!strcmp("profile", keyword)) + { + mProfileParams.importLegacyStream(input_stream); + } + else if (!strcmp("path",keyword)) + { + mPathParams.importLegacyStream(input_stream); + } + else + { + LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; + } + } + + return TRUE; +} + +BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const +{ + output_stream <<"\tshape 0\n"; + output_stream <<"\t{\n"; + mPathParams.exportLegacyStream(output_stream); + mProfileParams.exportLegacyStream(output_stream); + output_stream << "\t}\n"; + return TRUE; +} + +LLSD LLVolumeParams::sculptAsLLSD() const +{ + LLSD sd = LLSD(); + sd["id"] = getSculptID(); + sd["type"] = getSculptType(); + + return sd; +} + +bool LLVolumeParams::sculptFromLLSD(LLSD& sd) +{ + setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger()); + return true; +} + +LLSD LLVolumeParams::asLLSD() const +{ + LLSD sd = LLSD(); + sd["path"] = mPathParams; + sd["profile"] = mProfileParams; + sd["sculpt"] = sculptAsLLSD(); + + return sd; +} + +bool LLVolumeParams::fromLLSD(LLSD& sd) +{ + mPathParams.fromLLSD(sd["path"]); + mProfileParams.fromLLSD(sd["profile"]); + sculptFromLLSD(sd["sculpt"]); + + return true; +} + +void LLVolumeParams::reduceS(F32 begin, F32 end) +{ + begin = llclampf(begin); + end = llclampf(end); + if (begin > end) + { + F32 temp = begin; + begin = end; + end = temp; + } + F32 a = mProfileParams.getBegin(); + F32 b = mProfileParams.getEnd(); + mProfileParams.setBegin(a + begin * (b - a)); + mProfileParams.setEnd(a + end * (b - a)); +} + +void LLVolumeParams::reduceT(F32 begin, F32 end) +{ + begin = llclampf(begin); + end = llclampf(end); + if (begin > end) + { + F32 temp = begin; + begin = end; + end = temp; + } + F32 a = mPathParams.getBegin(); + F32 b = mPathParams.getEnd(); + mPathParams.setBegin(a + begin * (b - a)); + mPathParams.setEnd(a + end * (b - a)); +} + +const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity +const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity + +// returns TRUE if the shape can be approximated with a convex shape +// for collison purposes +BOOL LLVolumeParams::isConvex() const +{ + if (!getSculptID().isNull()) + { + // can't determine, be safe and say no: + return FALSE; + } + + F32 path_length = mPathParams.getEnd() - mPathParams.getBegin(); + F32 hollow = mProfileParams.getHollow(); + + U8 path_type = mPathParams.getCurveType(); + if ( path_length > MIN_CONCAVE_PATH_WEDGE + && ( mPathParams.getTwist() != mPathParams.getTwistBegin() + || (hollow > 0.f + && LL_PCODE_PATH_LINE != path_type) ) ) + { + // twist along a "not too short" path is concave + return FALSE; + } + + F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin(); + BOOL same_hole = hollow == 0.f + || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME; + + F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE; + U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; + if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) + { + // it is a sphere and spheres get twice the minimum profile wedge + min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE; + } + + BOOL convex_profile = ( ( profile_length == 1.f + || profile_length <= 0.5f ) + && hollow == 0.f ) // trivially convex + || ( profile_length <= min_profile_wedge + && same_hole ); // effectvely convex (even when hollow) + + if (!convex_profile) + { + // profile is concave + return FALSE; + } + + if ( LL_PCODE_PATH_LINE == path_type ) + { + // straight paths with convex profile + return TRUE; + } + + BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f); + if (concave_path) + { + return FALSE; + } + + // we're left with spheres, toroids and tubes + if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) + { + // at this stage all spheres must be convex + return TRUE; + } + + // it's a toroid or tube + if ( path_length <= MIN_CONCAVE_PATH_WEDGE ) + { + // effectively convex + return TRUE; + } + + return FALSE; +} + +// debug +void LLVolumeParams::setCube() +{ + mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE); + mProfileParams.setBegin(0.f); + mProfileParams.setEnd(1.f); + mProfileParams.setHollow(0.f); + + mPathParams.setBegin(0.f); + mPathParams.setEnd(1.f); + mPathParams.setScale(1.f, 1.f); + mPathParams.setShear(0.f, 0.f); + mPathParams.setCurveType(LL_PCODE_PATH_LINE); + mPathParams.setTwistBegin(0.f); + mPathParams.setTwistEnd(0.f); + mPathParams.setRadiusOffset(0.f); + mPathParams.setTaper(0.f, 0.f); + mPathParams.setRevolutions(0.f); + mPathParams.setSkew(0.f); +} + +LLFaceID LLVolume::generateFaceMask() +{ + LLFaceID new_mask = 0x0000; + + switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK) + { + case LL_PCODE_PROFILE_CIRCLE: + case LL_PCODE_PROFILE_CIRCLE_HALF: + new_mask |= LL_FACE_OUTER_SIDE_0; + break; + case LL_PCODE_PROFILE_SQUARE: + { + for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++) + { + new_mask |= LL_FACE_OUTER_SIDE_0 << side; + } + } + break; + case LL_PCODE_PROFILE_ISOTRI: + case LL_PCODE_PROFILE_EQUALTRI: + case LL_PCODE_PROFILE_RIGHTTRI: + { + for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++) + { + new_mask |= LL_FACE_OUTER_SIDE_0 << side; + } + } + break; + default: + LL_ERRS() << "Unknown profile!" << LL_ENDL; + break; + } + + // handle hollow objects + if (mParams.getProfileParams().getHollow() > 0) + { + new_mask |= LL_FACE_INNER_SIDE; + } + + // handle open profile curves + if (mProfilep->isOpen()) + { + new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END; + } + + // handle open path curves + if (mPathp->isOpen()) + { + new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END; + } + + return new_mask; +} + +BOOL LLVolume::isFaceMaskValid(LLFaceID face_mask) +{ + LLFaceID test_mask = 0; + for(S32 i = 0; i < getNumFaces(); i++) + { + test_mask |= mProfilep->mFaces[i].mFaceID; + } + + return test_mask == face_mask; +} + +BOOL LLVolume::isConvex() const +{ + // mParams.isConvex() may return FALSE even though the final + // geometry is actually convex due to LOD approximations. + // TODO -- provide LLPath and LLProfile with isConvex() methods + // that correctly determine convexity. -- Leviathan + return mParams.isConvex(); +} + + +std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params) +{ + s << "{type=" << (U32) profile_params.mCurveType; + s << ", begin=" << profile_params.mBegin; + s << ", end=" << profile_params.mEnd; + s << ", hollow=" << profile_params.mHollow; + s << "}"; + return s; +} + + +std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params) +{ + s << "{type=" << (U32) path_params.mCurveType; + s << ", begin=" << path_params.mBegin; + s << ", end=" << path_params.mEnd; + s << ", twist=" << path_params.mTwistEnd; + s << ", scale=" << path_params.mScale; + s << ", shear=" << path_params.mShear; + s << ", twist_begin=" << path_params.mTwistBegin; + s << ", radius_offset=" << path_params.mRadiusOffset; + s << ", taper=" << path_params.mTaper; + s << ", revolutions=" << path_params.mRevolutions; + s << ", skew=" << path_params.mSkew; + s << "}"; + return s; +} + + +std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params) +{ + s << "{profileparams = " << volume_params.mProfileParams; + s << ", pathparams = " << volume_params.mPathParams; + s << "}"; + return s; +} + + +std::ostream& operator<<(std::ostream &s, const LLProfile &profile) +{ + s << " {open=" << (U32) profile.mOpen; + s << ", dirty=" << profile.mDirty; + s << ", totalout=" << profile.mTotalOut; + s << ", total=" << profile.mTotal; + s << "}"; + return s; +} + + +std::ostream& operator<<(std::ostream &s, const LLPath &path) +{ + s << "{open=" << (U32) path.mOpen; + s << ", dirty=" << path.mDirty; + s << ", step=" << path.mStep; + s << ", total=" << path.mTotal; + s << "}"; + return s; +} + +std::ostream& operator<<(std::ostream &s, const LLVolume &volume) +{ + s << "{params = " << volume.getParams(); + s << ", path = " << *volume.mPathp; + s << ", profile = " << *volume.mProfilep; + s << "}"; + return s; +} + + +std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) +{ + s << "{params = " << volumep->getParams(); + s << ", path = " << *(volumep->mPathp); + s << ", profile = " << *(volumep->mProfilep); + s << "}"; + return s; +} + +LLVolumeFace::LLVolumeFace() : + mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumAllocatedVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mTangents(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL), +#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS + mJustWeights(NULL), + mJointIndices(NULL), +#endif + mWeightsScrubbed(FALSE), + mOctree(NULL), + mOctreeTriangles(NULL), + mOptimized(FALSE) +{ + mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); + mExtents[0].splat(-0.5f); + mExtents[1].splat(0.5f); + mCenter = mExtents+2; +} + +LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +: mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumAllocatedVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mTangents(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL), +#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS + mJustWeights(NULL), + mJointIndices(NULL), +#endif + mWeightsScrubbed(FALSE), + mOctree(NULL), + mOctreeTriangles(NULL) +{ + mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); + mCenter = mExtents+2; + *this = src; +} + +LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) +{ + if (&src == this) + { //self assignment, do nothing + return *this; + } + + mID = src.mID; + mTypeMask = src.mTypeMask; + mBeginS = src.mBeginS; + mBeginT = src.mBeginT; + mNumS = src.mNumS; + mNumT = src.mNumT; + + mExtents[0] = src.mExtents[0]; + mExtents[1] = src.mExtents[1]; + *mCenter = *src.mCenter; + + mNumVertices = 0; + mNumIndices = 0; + + freeData(); + + resizeVertices(src.mNumVertices); + resizeIndices(src.mNumIndices); + + if (mNumVertices) + { + S32 vert_size = mNumVertices*sizeof(LLVector4a); + S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; + + LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); + + if (src.mNormals) + { + LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); + } + + if(src.mTexCoords) + { + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + } + + if (src.mTangents) + { + allocateTangents(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); + } + else + { + ll_aligned_free_16(mTangents); + mTangents = NULL; + } + + if (src.mWeights) + { + llassert(!mWeights); // don't orphan an old alloc here accidentally + allocateWeights(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); + mWeightsScrubbed = src.mWeightsScrubbed; + } + else + { + ll_aligned_free_16(mWeights); + mWeights = NULL; + mWeightsScrubbed = FALSE; + } + + #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS + if (src.mJointIndices) + { + llassert(!mJointIndices); // don't orphan an old alloc here accidentally + allocateJointIndices(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mJointIndices, (F32*) src.mJointIndices, src.mNumVertices * sizeof(U8) * 4); + } + else*/ + { + ll_aligned_free_16(mJointIndices); + mJointIndices = NULL; + } + #endif + + } + + if (mNumIndices) + { + S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF; + + LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); + } + else + { + ll_aligned_free_16(mIndices); + mIndices = NULL; + } + + mOptimized = src.mOptimized; + mNormalizedScale = src.mNormalizedScale; + + //delete + return *this; +} + +LLVolumeFace::~LLVolumeFace() +{ + ll_aligned_free_16(mExtents); + mExtents = NULL; + mCenter = NULL; + + freeData(); +} + +void LLVolumeFace::freeData() +{ + ll_aligned_free<64>(mPositions); + mPositions = NULL; + + //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately + mNormals = NULL; + mTexCoords = NULL; + + ll_aligned_free_16(mIndices); + mIndices = NULL; + ll_aligned_free_16(mTangents); + mTangents = NULL; + ll_aligned_free_16(mWeights); + mWeights = NULL; + +#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS + ll_aligned_free_16(mJointIndices); + mJointIndices = NULL; + ll_aligned_free_16(mJustWeights); + mJustWeights = NULL; +#endif + + destroyOctree(); +} + +BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + + //tree for this face is no longer valid + destroyOctree(); + + LL_CHECK_MEMORY + BOOL ret = FALSE ; + if (mTypeMask & CAP_MASK) + { + ret = createCap(volume, partial_build); + LL_CHECK_MEMORY + } + else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) + { + ret = createSide(volume, partial_build); + LL_CHECK_MEMORY + } + else + { + LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL; + } + + return ret ; +} + +void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) +{ + cv.setPosition(mPositions[index]); + if (mNormals) + { + cv.setNormal(mNormals[index]); + } + else + { + cv.getNormal().clear(); + } + + if (mTexCoords) + { + cv.mTexCoord = mTexCoords[index]; + } + else + { + cv.mTexCoord.clear(); + } +} + +bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const +{ + return getPosition().equals3(rhs.getPosition()) && + mTexCoord == rhs.mTexCoord && + getNormal().equals3(rhs.getNormal()); +} + +bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const +{ + if (a.mV[0] != b.mV[0]) + { + return a.mV[0] < b.mV[0]; + } + + if (a.mV[1] != b.mV[1]) + { + return a.mV[1] < b.mV[1]; + } + + return a.mV[2] < b.mV[2]; +} + +void LLVolumeFace::remap() +{ + // Generate a remap buffer + std::vector remap(mNumVertices); + S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], + mIndices, + mNumIndices, + mPositions, + mNormals, + mTexCoords, + mNumVertices); + + // Allocate new buffers + S32 size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF; + U16* remap_indices = (U16*)ll_aligned_malloc_16(size); + + S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF; + LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size); + LLVector4a* remap_normals = remap_positions + remap_vertices_count; + LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count); + + // Fill the buffers + LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]); + LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]); + LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]); + LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]); + + // Free unused buffers + ll_aligned_free_16(mIndices); + ll_aligned_free<64>(mPositions); + + // Tangets are now invalid + ll_aligned_free_16(mTangents); + mTangents = NULL; + + // Assign new values + mIndices = remap_indices; + mPositions = remap_positions; + mNormals = remap_normals; + mTexCoords = remap_tex_coords; + mNumVertices = remap_vertices_count; + mNumAllocatedVertices = remap_vertices_count; +} + +void LLVolumeFace::optimize(F32 angle_cutoff) +{ + LLVolumeFace new_face; + + //map of points to vector of vertices at that point + std::map > point_map; + + LLVector4a range; + range.setSub(mExtents[1],mExtents[0]); + + //remove redundant vertices + for (U32 i = 0; i < mNumIndices; ++i) + { + U16 index = mIndices[i]; + + if (index >= mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + index = mNumVertices - 1; + mIndices[i] = index; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + + LLVolumeFace::VertexData cv; + getVertexData(index, cv); + + BOOL found = FALSE; + + LLVector4a pos; + pos.setSub(mPositions[index], mExtents[0]); + pos.div(range); + + U64 pos64 = 0; + + pos64 = (U16) (pos[0]*65535); + pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); + pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + + std::map >::iterator point_iter = point_map.find(pos64); + + if (point_iter != point_map.end()) + { //duplicate point might exist + for (U32 j = 0; j < point_iter->second.size(); ++j) + { + LLVolumeFace::VertexData& tv = (point_iter->second)[j]; + if (tv.compareNormal(cv, angle_cutoff)) + { + found = TRUE; + new_face.pushIndex((point_iter->second)[j].mIndex); + break; + } + } + } + + if (!found) + { + new_face.pushVertex(cv); + U16 index = (U16) new_face.mNumVertices-1; + new_face.pushIndex(index); + + VertexMapData d; + d.setPosition(cv.getPosition()); + d.mTexCoord = cv.mTexCoord; + d.setNormal(cv.getNormal()); + d.mIndex = index; + if (point_iter != point_map.end()) + { + point_iter->second.push_back(d); + } + else + { + point_map[pos64].push_back(d); + } + } + } + + + if (angle_cutoff > 1.f && !mNormals) + { + // Now alloc'd with positions + //ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!mTexCoords) + { + // Now alloc'd with positions + //ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + + // Only swap data if we've actually optimized the mesh + // + if (new_face.mNumVertices <= mNumVertices) + { + llassert(new_face.mNumIndices == mNumIndices); + swapData(new_face); + } + +} + +class LLVCacheTriangleData; + +class LLVCacheVertexData +{ +public: + S32 mIdx; + S32 mCacheTag; + F64 mScore; + U32 mActiveTriangles; + std::vector mTriangles; + + LLVCacheVertexData() + { + mCacheTag = -1; + mScore = 0.0; + mActiveTriangles = 0; + mIdx = -1; + } +}; + +class LLVCacheTriangleData +{ +public: + bool mActive; + F64 mScore; + LLVCacheVertexData* mVertex[3]; + + LLVCacheTriangleData() + { + mActive = true; + mScore = 0.0; + mVertex[0] = mVertex[1] = mVertex[2] = NULL; + } + + void complete() + { + mActive = false; + for (S32 i = 0; i < 3; ++i) + { + if (mVertex[i]) + { + llassert(mVertex[i]->mActiveTriangles > 0); + mVertex[i]->mActiveTriangles--; + } + } + } + + bool operator<(const LLVCacheTriangleData& rhs) const + { //highest score first + return rhs.mScore < mScore; + } +}; + +const F64 FindVertexScore_CacheDecayPower = 1.5; +const F64 FindVertexScore_LastTriScore = 0.75; +const F64 FindVertexScore_ValenceBoostScale = 2.0; +const F64 FindVertexScore_ValenceBoostPower = 0.5; +const U32 MaxSizeVertexCache = 32; +const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3); + +F64 find_vertex_score(LLVCacheVertexData& data) +{ + F64 score = -1.0; + + score = 0.0; + + S32 cache_idx = data.mCacheTag; + + if (cache_idx < 0) + { + //not in cache + } + else + { + if (cache_idx < 3) + { //vertex was in the last triangle + score = FindVertexScore_LastTriScore; + } + else + { //more points for being higher in the cache + score = 1.0-((cache_idx-3)*FindVertexScore_Scaler); + score = pow(score, FindVertexScore_CacheDecayPower); + } + } + + //bonus points for having low valence + F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); + score += FindVertexScore_ValenceBoostScale * valence_boost; + + return score; +} + +class LLVCacheFIFO +{ +public: + LLVCacheVertexData* mCache[MaxSizeVertexCache]; + U32 mMisses; + + LLVCacheFIFO() + { + mMisses = 0; + for (U32 i = 0; i < MaxSizeVertexCache; ++i) + { + mCache[i] = NULL; + } + } + + void addVertex(LLVCacheVertexData* data) + { + if (data->mCacheTag == -1) + { + mMisses++; + + S32 end = MaxSizeVertexCache-1; + + if (mCache[end]) + { + mCache[end]->mCacheTag = -1; + } + + for (S32 i = end; i > 0; --i) + { + mCache[i] = mCache[i-1]; + if (mCache[i]) + { + mCache[i]->mCacheTag = i; + } + } + + mCache[0] = data; + data->mCacheTag = 0; + } + } +}; + +class LLVCacheLRU +{ +public: + LLVCacheVertexData* mCache[MaxSizeVertexCache+3]; + + LLVCacheTriangleData* mBestTriangle; + + U32 mMisses; + + LLVCacheLRU() + { + for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) + { + mCache[i] = NULL; + } + + mBestTriangle = NULL; + mMisses = 0; + } + + void addVertex(LLVCacheVertexData* data) + { + S32 end = MaxSizeVertexCache+2; + if (data->mCacheTag != -1) + { //just moving a vertex to the front of the cache + end = data->mCacheTag; + } + else + { + mMisses++; + if (mCache[end]) + { //adding a new vertex, vertex at end of cache falls off + mCache[end]->mCacheTag = -1; + } + } + + for (S32 i = end; i > 0; --i) + { //adjust cache pointers and tags + mCache[i] = mCache[i-1]; + + if (mCache[i]) + { + mCache[i]->mCacheTag = i; + } + } + + mCache[0] = data; + mCache[0]->mCacheTag = 0; + } + + void addTriangle(LLVCacheTriangleData* data) + { + addVertex(data->mVertex[0]); + addVertex(data->mVertex[1]); + addVertex(data->mVertex[2]); + } + + void updateScores() + { + LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; + LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; + + while(data_iter != end_data) + { + LLVCacheVertexData* data = *data_iter++; + //trailing 3 vertices aren't actually in the cache for scoring purposes + if (data) + { + data->mCacheTag = -1; + } + } + + data_iter = mCache; + end_data = mCache+MaxSizeVertexCache; + + while (data_iter != end_data) + { //update scores of vertices in cache + LLVCacheVertexData* data = *data_iter++; + if (data) + { + data->mScore = find_vertex_score(*data); + } + } + + mBestTriangle = NULL; + //update triangle scores + data_iter = mCache; + end_data = mCache+MaxSizeVertexCache+3; + + while (data_iter != end_data) + { + LLVCacheVertexData* data = *data_iter++; + if (data) + { + for (std::vector::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter) + { + LLVCacheTriangleData* tri = *iter; + if (tri->mActive) + { + tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0; + tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0; + tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0; + + if (!mBestTriangle || mBestTriangle->mScore < tri->mScore) + { + mBestTriangle = tri; + } + } + } + } + } + + //knock trailing 3 vertices off the cache + data_iter = mCache+MaxSizeVertexCache; + end_data = mCache+MaxSizeVertexCache+3; + while (data_iter != end_data) + { + LLVCacheVertexData* data = *data_iter; + if (data) + { + llassert(data->mCacheTag == -1); + *data_iter = NULL; + } + ++data_iter; + } + } +}; + +// data structures for tangent generation + +struct MikktData +{ + LLVolumeFace* face; + std::vector p; + std::vector n; + std::vector tc; + std::vector w; + std::vector t; + + MikktData(LLVolumeFace* f) + : face(f) + { + U32 count = face->mNumIndices; + + p.resize(count); + n.resize(count); + tc.resize(count); + t.resize(count); + + if (face->mWeights) + { + w.resize(count); + } + + + LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); + + + for (int i = 0; i < face->mNumIndices; ++i) + { + U32 idx = face->mIndices[i]; + + p[i].set(face->mPositions[idx].getF32ptr()); + p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents + n[i].set(face->mNormals[idx].getF32ptr()); + n[i].scaleVec(inv_scale); + n[i].normalize(); + tc[i].set(face->mTexCoords[idx]); + + if (idx >= face->mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + idx = face->mNumVertices - 1; + face->mIndices[i] = idx; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + + if (face->mWeights) + { + w[i].set(face->mWeights[idx].getF32ptr()); + } + } + } + + uint32_t GetNumFaces() + { + return uint32_t(face->mNumIndices / 3); + } + + uint32_t GetNumVerticesOfFace(const uint32_t face_num) + { + return 3; + } + + mikk::float3 GetPosition(const uint32_t face_num, const uint32_t vert_num) + { + F32* v = p[face_num * 3 + vert_num].mV; + return mikk::float3(v); + } + + mikk::float3 GetTexCoord(const uint32_t face_num, const uint32_t vert_num) + { + F32* uv = tc[face_num * 3 + vert_num].mV; + return mikk::float3(uv[0], uv[1], 1.0f); + } + + mikk::float3 GetNormal(const uint32_t face_num, const uint32_t vert_num) + { + F32* normal = n[face_num * 3 + vert_num].mV; + return mikk::float3(normal); + } + + void SetTangentSpace(const uint32_t face_num, const uint32_t vert_num, mikk::float3 T, bool orientation) + { + S32 i = face_num * 3 + vert_num; + t[i].set(T.x, T.y, T.z, orientation ? 1.0f : -1.0f); + } +}; + +bool LLVolumeFace::cacheOptimize(bool gen_tangents) +{ //optimize for vertex cache according to Forsyth method: + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + llassert(!mOptimized); + mOptimized = TRUE; + + if (gen_tangents && mNormals && mTexCoords) + { // generate mikkt space tangents before cache optimizing since the index buffer may change + // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh + // and is executed on a background thread + MikktData data(this); + mikk::Mikktspace ctx(data); + ctx.genTangSpace(); + + //re-weld + meshopt_Stream mos[] = + { + { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, + { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, + { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } + }; + + std::vector remap; + remap.resize(data.p.size()); + + U32 stream_count = data.w.empty() ? 4 : 5; + + size_t vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); + + if (vert_count < 65535 && vert_count != 0) + { + //copy results back into volume + resizeVertices(vert_count); + + if (!data.w.empty()) + { + allocateWeights(vert_count); + } + + allocateTangents(mNumVertices); + + for (int i = 0; i < mNumIndices; ++i) + { + U32 src_idx = i; + U32 dst_idx = remap[i]; + if (dst_idx >= mNumVertices) + { dst_idx = mNumVertices - 1; // Shouldn't happen, figure out what gets returned in remap and why. llassert(false); @@ -5575,20 +5575,20 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) resizeIndices(mNumIndices); meshopt_optimizeVertexCache(mIndices, src_indices, mNumIndices, mNumVertices); - + ll_aligned_free_16(src_indices); - return true; + return true; } void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if (getOctree()) - { - return; - } + { + return; + } llassert(mNumIndices % 3 == 0); @@ -5598,63 +5598,63 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe mOctreeTriangles = new LLVolumeTriangle[num_triangles]; for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) - { //for each triangle + { //for each triangle const U32 index = triangle_index * 3; LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; - - const LLVector4a& v0 = mPositions[mIndices[index]]; - const LLVector4a& v1 = mPositions[mIndices[index + 1]]; - const LLVector4a& v2 = mPositions[mIndices[index + 2]]; - - //store pointers to vertex data - tri->mV[0] = &v0; - tri->mV[1] = &v1; - tri->mV[2] = &v2; - - //store indices - tri->mIndex[0] = mIndices[index]; - tri->mIndex[1] = mIndices[index + 1]; - tri->mIndex[2] = mIndices[index + 2]; - - //get minimum point - LLVector4a min = v0; - min.setMin(min, v1); - min.setMin(min, v2); - - //get maximum point - LLVector4a max = v0; - max.setMax(max, v1); - max.setMax(max, v2); - - //compute center - LLVector4a center; - center.setAdd(min, max); - center.mul(0.5f); - - tri->mPositionGroup = center; - - //compute "radius" - LLVector4a size; - size.setSub(max,min); - - tri->mRadius = size.getLength3().getF32() * scaler; - - //insert - mOctree->insert(tri); - } - - //remove unneeded octree layers - while (!mOctree->balance()) { } - - //calculate AABB for each node - LLVolumeOctreeRebound rebound; - rebound.traverse(mOctree); - - if (gDebugGL) - { - LLVolumeOctreeValidate validate; - validate.traverse(mOctree); - } + + const LLVector4a& v0 = mPositions[mIndices[index]]; + const LLVector4a& v1 = mPositions[mIndices[index + 1]]; + const LLVector4a& v2 = mPositions[mIndices[index + 2]]; + + //store pointers to vertex data + tri->mV[0] = &v0; + tri->mV[1] = &v1; + tri->mV[2] = &v2; + + //store indices + tri->mIndex[0] = mIndices[index]; + tri->mIndex[1] = mIndices[index + 1]; + tri->mIndex[2] = mIndices[index + 2]; + + //get minimum point + LLVector4a min = v0; + min.setMin(min, v1); + min.setMin(min, v2); + + //get maximum point + LLVector4a max = v0; + max.setMax(max, v1); + max.setMax(max, v2); + + //compute center + LLVector4a center; + center.setAdd(min, max); + center.mul(0.5f); + + tri->mPositionGroup = center; + + //compute "radius" + LLVector4a size; + size.setSub(max,min); + + tri->mRadius = size.getLength3().getF32() * scaler; + + //insert + mOctree->insert(tri); + } + + //remove unneeded octree layers + while (!mOctree->balance()) { } + + //calculate AABB for each node + LLVolumeOctreeRebound rebound; + rebound.traverse(mOctree); + + if (gDebugGL) + { + LLVolumeOctreeValidate validate; + validate.traverse(mOctree); + } } void LLVolumeFace::destroyOctree() @@ -5673,145 +5673,145 @@ const LLVolumeOctree* LLVolumeFace::getOctree() const void LLVolumeFace::swapData(LLVolumeFace& rhs) { - llswap(rhs.mPositions, mPositions); - llswap(rhs.mNormals, mNormals); - llswap(rhs.mTangents, mTangents); - llswap(rhs.mTexCoords, mTexCoords); - llswap(rhs.mIndices,mIndices); - llswap(rhs.mNumVertices, mNumVertices); - llswap(rhs.mNumIndices, mNumIndices); + llswap(rhs.mPositions, mPositions); + llswap(rhs.mNormals, mNormals); + llswap(rhs.mTangents, mTangents); + llswap(rhs.mTexCoords, mTexCoords); + llswap(rhs.mIndices,mIndices); + llswap(rhs.mNumVertices, mNumVertices); + llswap(rhs.mNumIndices, mNumIndices); } -void LerpPlanarVertex(LLVolumeFace::VertexData& v0, - LLVolumeFace::VertexData& v1, - LLVolumeFace::VertexData& v2, - LLVolumeFace::VertexData& vout, - F32 coef01, - F32 coef02) +void LerpPlanarVertex(LLVolumeFace::VertexData& v0, + LLVolumeFace::VertexData& v1, + LLVolumeFace::VertexData& v2, + LLVolumeFace::VertexData& vout, + F32 coef01, + F32 coef02) { - LLVector4a lhs; - lhs.setSub(v1.getPosition(), v0.getPosition()); - lhs.mul(coef01); - LLVector4a rhs; - rhs.setSub(v2.getPosition(), v0.getPosition()); - rhs.mul(coef02); + LLVector4a lhs; + lhs.setSub(v1.getPosition(), v0.getPosition()); + lhs.mul(coef01); + LLVector4a rhs; + rhs.setSub(v2.getPosition(), v0.getPosition()); + rhs.mul(coef02); - rhs.add(lhs); - rhs.add(v0.getPosition()); + rhs.add(lhs); + rhs.add(v0.getPosition()); - vout.setPosition(rhs); - - vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); - vout.setNormal(v0.getNormal()); + vout.setPosition(rhs); + + vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); + vout.setNormal(v0.getNormal()); } BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) { - LL_CHECK_MEMORY - - const LLAlignedArray& mesh = volume->getMesh(); - const LLAlignedArray& profile = volume->getProfile().mProfile; - S32 max_s = volume->getProfile().getTotal(); - S32 max_t = volume->getPath().mPath.size(); - - // S32 i; - S32 grid_size = (profile.size()-1)/4; - // VFExtents change - LLVector4a& min = mExtents[0]; - LLVector4a& max = mExtents[1]; - - S32 offset = 0; - if (mTypeMask & TOP_MASK) - { - offset = (max_t-1) * max_s; - } - else - { - offset = mBeginS; - } - - { - VertexData corners[4]; - VertexData baseVert; - for(S32 t = 0; t < 4; t++) - { - corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr()); - corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f; - corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1]; - } - - { - LLVector4a lhs; - lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); - LLVector4a rhs; - rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); - baseVert.getNormal().setCross3(lhs, rhs); - baseVert.getNormal().normalize3fast(); - } - - if(!(mTypeMask & TOP_MASK)) - { - baseVert.getNormal().mul(-1.0f); - } - else - { - //Swap the UVs on the U(X) axis for top face - LLVector2 swap; - swap = corners[0].mTexCoord; - corners[0].mTexCoord=corners[3].mTexCoord; - corners[3].mTexCoord=swap; - swap = corners[1].mTexCoord; - corners[1].mTexCoord=corners[2].mTexCoord; - corners[2].mTexCoord=swap; - } - - S32 size = (grid_size+1)*(grid_size+1); - resizeVertices(size); - - LLVector4a* pos = (LLVector4a*) mPositions; - LLVector4a* norm = (LLVector4a*) mNormals; - LLVector2* tc = (LLVector2*) mTexCoords; - - for(int gx = 0;gxsetAdd(min, max); - mCenter->mul(0.5f); - } - - if (!partial_build) - { - resizeIndices(grid_size*grid_size*6); - if (!volume->isMeshAssetLoaded()) - { + LL_CHECK_MEMORY + + const LLAlignedArray& mesh = volume->getMesh(); + const LLAlignedArray& profile = volume->getProfile().mProfile; + S32 max_s = volume->getProfile().getTotal(); + S32 max_t = volume->getPath().mPath.size(); + + // S32 i; + S32 grid_size = (profile.size()-1)/4; + // VFExtents change + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; + + S32 offset = 0; + if (mTypeMask & TOP_MASK) + { + offset = (max_t-1) * max_s; + } + else + { + offset = mBeginS; + } + + { + VertexData corners[4]; + VertexData baseVert; + for(S32 t = 0; t < 4; t++) + { + corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr()); + corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f; + corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1]; + } + + { + LLVector4a lhs; + lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); + LLVector4a rhs; + rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); + baseVert.getNormal().setCross3(lhs, rhs); + baseVert.getNormal().normalize3fast(); + } + + if(!(mTypeMask & TOP_MASK)) + { + baseVert.getNormal().mul(-1.0f); + } + else + { + //Swap the UVs on the U(X) axis for top face + LLVector2 swap; + swap = corners[0].mTexCoord; + corners[0].mTexCoord=corners[3].mTexCoord; + corners[3].mTexCoord=swap; + swap = corners[1].mTexCoord; + corners[1].mTexCoord=corners[2].mTexCoord; + corners[2].mTexCoord=swap; + } + + S32 size = (grid_size+1)*(grid_size+1); + resizeVertices(size); + + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + LLVector2* tc = (LLVector2*) mTexCoords; + + for(int gx = 0;gxsetAdd(min, max); + mCenter->mul(0.5f); + } + + if (!partial_build) + { + resizeIndices(grid_size*grid_size*6); + if (!volume->isMeshAssetLoaded()) + { S32 size = grid_size * grid_size * 6; try { @@ -5822,562 +5822,562 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL; return false; } - } - - U16* out = mIndices; - - S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; - - int cur_edge = 0; - - for(S32 gx = 0;gx=0;i--) - { - *out++ = ((gy*(grid_size+1))+gx+idxs[i]); - } - - S32 edge_value = grid_size * 2 * gy + gx * 2; - - if (gx > 0) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; // Mark face to higlight it - } - - if (gy < grid_size - 1) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - mEdge[cur_edge++] = edge_value; - - if (gx < grid_size - 1) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - if (gy > 0) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - mEdge[cur_edge++] = edge_value; - } - else - { - for(S32 i=0;i<6;i++) - { - *out++ = ((gy*(grid_size+1))+gx+idxs[i]); - } - - S32 edge_value = grid_size * 2 * gy + gx * 2; - - if (gy > 0) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - if (gx < grid_size - 1) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - mEdge[cur_edge++] = edge_value; - - if (gy < grid_size - 1) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - if (gx > 0) - { - mEdge[cur_edge++] = edge_value; - } - else - { - mEdge[cur_edge++] = -1; - } - - mEdge[cur_edge++] = edge_value; - } - } - } - } - - LL_CHECK_MEMORY - return TRUE; + } + + U16* out = mIndices; + + S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; + + int cur_edge = 0; + + for(S32 gx = 0;gx=0;i--) + { + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); + } + + S32 edge_value = grid_size * 2 * gy + gx * 2; + + if (gx > 0) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; // Mark face to higlight it + } + + if (gy < grid_size - 1) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + mEdge[cur_edge++] = edge_value; + + if (gx < grid_size - 1) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + if (gy > 0) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + mEdge[cur_edge++] = edge_value; + } + else + { + for(S32 i=0;i<6;i++) + { + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); + } + + S32 edge_value = grid_size * 2 * gy + gx * 2; + + if (gy > 0) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + if (gx < grid_size - 1) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + mEdge[cur_edge++] = edge_value; + + if (gy < grid_size - 1) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + if (gx > 0) + { + mEdge[cur_edge++] = edge_value; + } + else + { + mEdge[cur_edge++] = -1; + } + + mEdge[cur_edge++] = edge_value; + } + } + } + } + + LL_CHECK_MEMORY + return TRUE; } -BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) -{ - if (!(mTypeMask & HOLLOW_MASK) && - !(mTypeMask & OPEN_MASK) && - ((volume->getParams().getPathParams().getBegin()==0.0f)&& - (volume->getParams().getPathParams().getEnd()==1.0f))&& - (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE && - volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE) - ){ - return createUnCutCubeCap(volume, partial_build); - } - - S32 num_vertices = 0, num_indices = 0; - - const LLAlignedArray& mesh = volume->getMesh(); - const LLAlignedArray& profile = volume->getProfile().mProfile; - - // All types of caps have the same number of vertices and indices - num_vertices = profile.size(); - num_indices = (profile.size() - 2)*3; - - if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) - { - resizeVertices(num_vertices+1); - - //if (!partial_build) - { - resizeIndices(num_indices+3); - } - } - else - { - resizeVertices(num_vertices); - //if (!partial_build) - { - resizeIndices(num_indices); - } - } - - LL_CHECK_MEMORY; - - S32 max_s = volume->getProfile().getTotal(); - S32 max_t = volume->getPath().mPath.size(); - - mCenter->clear(); - - S32 offset = 0; - if (mTypeMask & TOP_MASK) - { - offset = (max_t-1) * max_s; - } - else - { - offset = mBeginS; - } - - // Figure out the normal, assume all caps are flat faces. - // Cross product to get normals. - - LLVector2 cuv; - LLVector2 min_uv, max_uv; - // VFExtents change - LLVector4a& min = mExtents[0]; - LLVector4a& max = mExtents[1]; - - LLVector2* tc = (LLVector2*) mTexCoords; - LLVector4a* pos = (LLVector4a*) mPositions; - LLVector4a* norm = (LLVector4a*) mNormals; - - // Copy the vertices into the array - - const LLVector4a* src = mesh.mArray+offset; - const LLVector4a* end = src+num_vertices; - - min = *src; - max = min; - - - const LLVector4a* p = profile.mArray; - - if (mTypeMask & TOP_MASK) - { - min_uv.set((*p)[0]+0.5f, - (*p)[1]+0.5f); - - max_uv = min_uv; - - while(src < end) - { - tc->mV[0] = (*p)[0]+0.5f; - tc->mV[1] = (*p)[1]+0.5f; - - llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds - update_min_max(min,max,*src); - update_min_max(min_uv, max_uv, *tc); - - *pos = *src; - - llassert(pos->isFinite3()); - - ++p; - ++tc; - ++src; - ++pos; - } - } - else - { - - min_uv.set((*p)[0]+0.5f, - 0.5f - (*p)[1]); - max_uv = min_uv; - - while(src < end) - { - // Mirror for underside. - tc->mV[0] = (*p)[0]+0.5f; - tc->mV[1] = 0.5f - (*p)[1]; - - llassert(src->isFinite3()); - update_min_max(min,max,*src); - update_min_max(min_uv, max_uv, *tc); - - *pos = *src; - - llassert(pos->isFinite3()); - - ++p; - ++tc; - ++src; - ++pos; - } - } - - LL_CHECK_MEMORY - - mCenter->setAdd(min, max); - mCenter->mul(0.5f); - - cuv = (min_uv + max_uv)*0.5f; - - - VertexData vd; - vd.setPosition(*mCenter); - vd.mTexCoord = cuv; - - if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) - { - *pos++ = *mCenter; - *tc++ = cuv; - num_vertices++; - } - - LL_CHECK_MEMORY - - //if (partial_build) - //{ - // return TRUE; - //} - - if (mTypeMask & HOLLOW_MASK) - { - if (mTypeMask & TOP_MASK) - { - // HOLLOW TOP - // Does it matter if it's open or closed? - djs - - S32 pt1 = 0, pt2 = num_vertices - 1; - S32 i = 0; - while (pt2 - pt1 > 1) - { - // Use the profile points instead of the mesh, since you want - // the un-transformed profile distances. - const LLVector4a& p1 = profile[pt1]; - const LLVector4a& p2 = profile[pt2]; - const LLVector4a& pa = profile[pt1+1]; - const LLVector4a& pb = profile[pt2-1]; - - const F32* p1V = p1.getF32ptr(); - const F32* p2V = p2.getF32ptr(); - const F32* paV = pa.getF32ptr(); - const F32* pbV = pb.getF32ptr(); - - //p1.mV[VZ] = 0.f; - //p2.mV[VZ] = 0.f; - //pa.mV[VZ] = 0.f; - //pb.mV[VZ] = 0.f; - - // Use area of triangle to determine backfacing - F32 area_1a2, area_1ba, area_21b, area_2ab; - area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) + - (paV[0]*p2V[1] - p2V[0]*paV[1]) + - (p2V[0]*p1V[1] - p1V[0]*p2V[1]); - - area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + - (pbV[0]*paV[1] - paV[0]*pbV[1]) + - (paV[0]*p1V[1] - p1V[0]*paV[1]); - - area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + - (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + - (pbV[0]*p2V[1] - p2V[0]*pbV[1]); - - area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) + - (paV[0]*pbV[1] - pbV[0]*paV[1]) + - (pbV[0]*p2V[1] - p2V[0]*pbV[1]); - - BOOL use_tri1a2 = TRUE; - BOOL tri_1a2 = TRUE; - BOOL tri_21b = TRUE; - - if (area_1a2 < 0) - { - tri_1a2 = FALSE; - } - if (area_2ab < 0) - { - // Can't use, because it contains point b - tri_1a2 = FALSE; - } - if (area_21b < 0) - { - tri_21b = FALSE; - } - if (area_1ba < 0) - { - // Can't use, because it contains point b - tri_21b = FALSE; - } - - if (!tri_1a2) - { - use_tri1a2 = FALSE; - } - else if (!tri_21b) - { - use_tri1a2 = TRUE; - } - else - { - LLVector4a d1; - d1.setSub(p1, pa); - - LLVector4a d2; - d2.setSub(p2, pb); - - if (d1.dot3(d1) < d2.dot3(d2)) - { - use_tri1a2 = TRUE; - } - else - { - use_tri1a2 = FALSE; - } - } - - if (use_tri1a2) - { - mIndices[i++] = pt1; - mIndices[i++] = pt1 + 1; - mIndices[i++] = pt2; - pt1++; - } - else - { - mIndices[i++] = pt1; - mIndices[i++] = pt2 - 1; - mIndices[i++] = pt2; - pt2--; - } - } - } - else - { - // HOLLOW BOTTOM - // Does it matter if it's open or closed? - djs - - llassert(mTypeMask & BOTTOM_MASK); - S32 pt1 = 0, pt2 = num_vertices - 1; - - S32 i = 0; - while (pt2 - pt1 > 1) - { - // Use the profile points instead of the mesh, since you want - // the un-transformed profile distances. - const LLVector4a& p1 = profile[pt1]; - const LLVector4a& p2 = profile[pt2]; - const LLVector4a& pa = profile[pt1+1]; - const LLVector4a& pb = profile[pt2-1]; - - const F32* p1V = p1.getF32ptr(); - const F32* p2V = p2.getF32ptr(); - const F32* paV = pa.getF32ptr(); - const F32* pbV = pb.getF32ptr(); - - // Use area of triangle to determine backfacing - F32 area_1a2, area_1ba, area_21b, area_2ab; - area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) + - (paV[0]*p2V[1] - p2V[0]*paV[1]) + - (p2V[0]*p1V[1] - p1V[0]*p2V[1]); - - area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + - (pbV[0]*paV[1] - paV[0]*pbV[1]) + - (paV[0]*p1V[1] - p1V[0]*paV[1]); - - area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + - (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + - (pbV[0]*p2V[1] - p2V[0]*pbV[1]); - - area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) + - (paV[0]*pbV[1] - pbV[0]*paV[1]) + - (pbV[0]*p2V[1] - p2V[0]*pbV[1]); - - BOOL use_tri1a2 = TRUE; - BOOL tri_1a2 = TRUE; - BOOL tri_21b = TRUE; - - if (area_1a2 < 0) - { - tri_1a2 = FALSE; - } - if (area_2ab < 0) - { - // Can't use, because it contains point b - tri_1a2 = FALSE; - } - if (area_21b < 0) - { - tri_21b = FALSE; - } - if (area_1ba < 0) - { - // Can't use, because it contains point b - tri_21b = FALSE; - } - - if (!tri_1a2) - { - use_tri1a2 = FALSE; - } - else if (!tri_21b) - { - use_tri1a2 = TRUE; - } - else - { - LLVector4a d1; - d1.setSub(p1,pa); - LLVector4a d2; - d2.setSub(p2,pb); - - if (d1.dot3(d1) < d2.dot3(d2)) - { - use_tri1a2 = TRUE; - } - else - { - use_tri1a2 = FALSE; - } - } - - // Flipped backfacing from top - if (use_tri1a2) - { - mIndices[i++] = pt1; - mIndices[i++] = pt2; - mIndices[i++] = pt1 + 1; - pt1++; - } - else - { - mIndices[i++] = pt1; - mIndices[i++] = pt2; - mIndices[i++] = pt2 - 1; - pt2--; - } - } - } - } - else - { - // Not hollow, generate the triangle fan. - U16 v1 = 2; - U16 v2 = 1; - - if (mTypeMask & TOP_MASK) - { - v1 = 1; - v2 = 2; - } - - for (S32 i = 0; i < (num_vertices - 2); i++) - { - mIndices[3*i] = num_vertices - 1; - mIndices[3*i+v1] = i; - mIndices[3*i+v2] = i + 1; - } - - - } - - LLVector4a d0,d1; - LL_CHECK_MEMORY - - - d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); - d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); - - LLVector4a normal; - normal.setCross3(d0,d1); - - if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) - { - normal.normalize3fast(); - } - else - { //degenerate, make up a value - if(normal.getF32ptr()[2] >= 0) - normal.set(0.f,0.f,1.f); - else - normal.set(0.f,0.f,-1.f); - } - - llassert(llfinite(normal.getF32ptr()[0])); - llassert(llfinite(normal.getF32ptr()[1])); - llassert(llfinite(normal.getF32ptr()[2])); - - llassert(!llisnan(normal.getF32ptr()[0])); - llassert(!llisnan(normal.getF32ptr()[1])); - llassert(!llisnan(normal.getF32ptr()[2])); - - for (S32 i = 0; i < num_vertices; i++) - { - norm[i].load4a(normal.getF32ptr()); - } - - return TRUE; +BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) +{ + if (!(mTypeMask & HOLLOW_MASK) && + !(mTypeMask & OPEN_MASK) && + ((volume->getParams().getPathParams().getBegin()==0.0f)&& + (volume->getParams().getPathParams().getEnd()==1.0f))&& + (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE && + volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE) + ){ + return createUnCutCubeCap(volume, partial_build); + } + + S32 num_vertices = 0, num_indices = 0; + + const LLAlignedArray& mesh = volume->getMesh(); + const LLAlignedArray& profile = volume->getProfile().mProfile; + + // All types of caps have the same number of vertices and indices + num_vertices = profile.size(); + num_indices = (profile.size() - 2)*3; + + if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) + { + resizeVertices(num_vertices+1); + + //if (!partial_build) + { + resizeIndices(num_indices+3); + } + } + else + { + resizeVertices(num_vertices); + //if (!partial_build) + { + resizeIndices(num_indices); + } + } + + LL_CHECK_MEMORY; + + S32 max_s = volume->getProfile().getTotal(); + S32 max_t = volume->getPath().mPath.size(); + + mCenter->clear(); + + S32 offset = 0; + if (mTypeMask & TOP_MASK) + { + offset = (max_t-1) * max_s; + } + else + { + offset = mBeginS; + } + + // Figure out the normal, assume all caps are flat faces. + // Cross product to get normals. + + LLVector2 cuv; + LLVector2 min_uv, max_uv; + // VFExtents change + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; + + LLVector2* tc = (LLVector2*) mTexCoords; + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + + // Copy the vertices into the array + + const LLVector4a* src = mesh.mArray+offset; + const LLVector4a* end = src+num_vertices; + + min = *src; + max = min; + + + const LLVector4a* p = profile.mArray; + + if (mTypeMask & TOP_MASK) + { + min_uv.set((*p)[0]+0.5f, + (*p)[1]+0.5f); + + max_uv = min_uv; + + while(src < end) + { + tc->mV[0] = (*p)[0]+0.5f; + tc->mV[1] = (*p)[1]+0.5f; + + llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds + update_min_max(min,max,*src); + update_min_max(min_uv, max_uv, *tc); + + *pos = *src; + + llassert(pos->isFinite3()); + + ++p; + ++tc; + ++src; + ++pos; + } + } + else + { + + min_uv.set((*p)[0]+0.5f, + 0.5f - (*p)[1]); + max_uv = min_uv; + + while(src < end) + { + // Mirror for underside. + tc->mV[0] = (*p)[0]+0.5f; + tc->mV[1] = 0.5f - (*p)[1]; + + llassert(src->isFinite3()); + update_min_max(min,max,*src); + update_min_max(min_uv, max_uv, *tc); + + *pos = *src; + + llassert(pos->isFinite3()); + + ++p; + ++tc; + ++src; + ++pos; + } + } + + LL_CHECK_MEMORY + + mCenter->setAdd(min, max); + mCenter->mul(0.5f); + + cuv = (min_uv + max_uv)*0.5f; + + + VertexData vd; + vd.setPosition(*mCenter); + vd.mTexCoord = cuv; + + if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) + { + *pos++ = *mCenter; + *tc++ = cuv; + num_vertices++; + } + + LL_CHECK_MEMORY + + //if (partial_build) + //{ + // return TRUE; + //} + + if (mTypeMask & HOLLOW_MASK) + { + if (mTypeMask & TOP_MASK) + { + // HOLLOW TOP + // Does it matter if it's open or closed? - djs + + S32 pt1 = 0, pt2 = num_vertices - 1; + S32 i = 0; + while (pt2 - pt1 > 1) + { + // Use the profile points instead of the mesh, since you want + // the un-transformed profile distances. + const LLVector4a& p1 = profile[pt1]; + const LLVector4a& p2 = profile[pt2]; + const LLVector4a& pa = profile[pt1+1]; + const LLVector4a& pb = profile[pt2-1]; + + const F32* p1V = p1.getF32ptr(); + const F32* p2V = p2.getF32ptr(); + const F32* paV = pa.getF32ptr(); + const F32* pbV = pb.getF32ptr(); + + //p1.mV[VZ] = 0.f; + //p2.mV[VZ] = 0.f; + //pa.mV[VZ] = 0.f; + //pb.mV[VZ] = 0.f; + + // Use area of triangle to determine backfacing + F32 area_1a2, area_1ba, area_21b, area_2ab; + area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) + + (paV[0]*p2V[1] - p2V[0]*paV[1]) + + (p2V[0]*p1V[1] - p1V[0]*p2V[1]); + + area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + + (pbV[0]*paV[1] - paV[0]*pbV[1]) + + (paV[0]*p1V[1] - p1V[0]*paV[1]); + + area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + + (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + + (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + + area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) + + (paV[0]*pbV[1] - pbV[0]*paV[1]) + + (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + + BOOL use_tri1a2 = TRUE; + BOOL tri_1a2 = TRUE; + BOOL tri_21b = TRUE; + + if (area_1a2 < 0) + { + tri_1a2 = FALSE; + } + if (area_2ab < 0) + { + // Can't use, because it contains point b + tri_1a2 = FALSE; + } + if (area_21b < 0) + { + tri_21b = FALSE; + } + if (area_1ba < 0) + { + // Can't use, because it contains point b + tri_21b = FALSE; + } + + if (!tri_1a2) + { + use_tri1a2 = FALSE; + } + else if (!tri_21b) + { + use_tri1a2 = TRUE; + } + else + { + LLVector4a d1; + d1.setSub(p1, pa); + + LLVector4a d2; + d2.setSub(p2, pb); + + if (d1.dot3(d1) < d2.dot3(d2)) + { + use_tri1a2 = TRUE; + } + else + { + use_tri1a2 = FALSE; + } + } + + if (use_tri1a2) + { + mIndices[i++] = pt1; + mIndices[i++] = pt1 + 1; + mIndices[i++] = pt2; + pt1++; + } + else + { + mIndices[i++] = pt1; + mIndices[i++] = pt2 - 1; + mIndices[i++] = pt2; + pt2--; + } + } + } + else + { + // HOLLOW BOTTOM + // Does it matter if it's open or closed? - djs + + llassert(mTypeMask & BOTTOM_MASK); + S32 pt1 = 0, pt2 = num_vertices - 1; + + S32 i = 0; + while (pt2 - pt1 > 1) + { + // Use the profile points instead of the mesh, since you want + // the un-transformed profile distances. + const LLVector4a& p1 = profile[pt1]; + const LLVector4a& p2 = profile[pt2]; + const LLVector4a& pa = profile[pt1+1]; + const LLVector4a& pb = profile[pt2-1]; + + const F32* p1V = p1.getF32ptr(); + const F32* p2V = p2.getF32ptr(); + const F32* paV = pa.getF32ptr(); + const F32* pbV = pb.getF32ptr(); + + // Use area of triangle to determine backfacing + F32 area_1a2, area_1ba, area_21b, area_2ab; + area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) + + (paV[0]*p2V[1] - p2V[0]*paV[1]) + + (p2V[0]*p1V[1] - p1V[0]*p2V[1]); + + area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + + (pbV[0]*paV[1] - paV[0]*pbV[1]) + + (paV[0]*p1V[1] - p1V[0]*paV[1]); + + area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + + (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + + (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + + area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) + + (paV[0]*pbV[1] - pbV[0]*paV[1]) + + (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + + BOOL use_tri1a2 = TRUE; + BOOL tri_1a2 = TRUE; + BOOL tri_21b = TRUE; + + if (area_1a2 < 0) + { + tri_1a2 = FALSE; + } + if (area_2ab < 0) + { + // Can't use, because it contains point b + tri_1a2 = FALSE; + } + if (area_21b < 0) + { + tri_21b = FALSE; + } + if (area_1ba < 0) + { + // Can't use, because it contains point b + tri_21b = FALSE; + } + + if (!tri_1a2) + { + use_tri1a2 = FALSE; + } + else if (!tri_21b) + { + use_tri1a2 = TRUE; + } + else + { + LLVector4a d1; + d1.setSub(p1,pa); + LLVector4a d2; + d2.setSub(p2,pb); + + if (d1.dot3(d1) < d2.dot3(d2)) + { + use_tri1a2 = TRUE; + } + else + { + use_tri1a2 = FALSE; + } + } + + // Flipped backfacing from top + if (use_tri1a2) + { + mIndices[i++] = pt1; + mIndices[i++] = pt2; + mIndices[i++] = pt1 + 1; + pt1++; + } + else + { + mIndices[i++] = pt1; + mIndices[i++] = pt2; + mIndices[i++] = pt2 - 1; + pt2--; + } + } + } + } + else + { + // Not hollow, generate the triangle fan. + U16 v1 = 2; + U16 v2 = 1; + + if (mTypeMask & TOP_MASK) + { + v1 = 1; + v2 = 2; + } + + for (S32 i = 0; i < (num_vertices - 2); i++) + { + mIndices[3*i] = num_vertices - 1; + mIndices[3*i+v1] = i; + mIndices[3*i+v2] = i + 1; + } + + + } + + LLVector4a d0,d1; + LL_CHECK_MEMORY + + + d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); + d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); + + LLVector4a normal; + normal.setCross3(d0,d1); + + if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) + { + normal.normalize3fast(); + } + else + { //degenerate, make up a value + if(normal.getF32ptr()[2] >= 0) + normal.set(0.f,0.f,1.f); + else + normal.set(0.f,0.f,-1.f); + } + + llassert(llfinite(normal.getF32ptr()[0])); + llassert(llfinite(normal.getF32ptr()[1])); + llassert(llfinite(normal.getF32ptr()[2])); + + llassert(!llisnan(normal.getF32ptr()[0])); + llassert(!llisnan(normal.getF32ptr()[1])); + llassert(!llisnan(normal.getF32ptr()[2])); + + for (S32 i = 0; i < num_vertices; i++) + { + norm[i].load4a(normal.getF32ptr()); + } + + return TRUE; } void LLVolumeFace::createTangents() @@ -6387,7 +6387,7 @@ void LLVolumeFace::createTangents() if (!mTangents) { allocateTangents(mNumVertices); - + //generate tangents LLVector4a* ptr = (LLVector4a*)mTangents; @@ -6411,29 +6411,29 @@ void LLVolumeFace::createTangents() void LLVolumeFace::resizeVertices(S32 num_verts) { - ll_aligned_free<64>(mPositions); - //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer - ll_aligned_free_16(mTangents); + ll_aligned_free<64>(mPositions); + //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer + ll_aligned_free_16(mTangents); - mTangents = NULL; + mTangents = NULL; - if (num_verts) - { - //pad texture coordinate block end to allow for QWORD reads - S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; + if (num_verts) + { + //pad texture coordinate block end to allow for QWORD reads + S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size); - mNormals = mPositions+num_verts; - mTexCoords = (LLVector2*) (mNormals+num_verts); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size); + mNormals = mPositions+num_verts; + mTexCoords = (LLVector2*) (mNormals+num_verts); - ll_assert_aligned(mPositions, 64); - } - else - { - mPositions = NULL; - mNormals = NULL; - mTexCoords = NULL; - } + ll_assert_aligned(mPositions, 64); + } + else + { + mPositions = NULL; + mNormals = NULL; + mTexCoords = NULL; + } if (mPositions) @@ -6454,70 +6454,70 @@ void LLVolumeFace::resizeVertices(S32 num_verts) void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) { - pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord); + pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord); } void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc) { - S32 new_verts = mNumVertices+1; + S32 new_verts = mNumVertices+1; + + if (new_verts > mNumAllocatedVertices) + { + // double buffer size on expansion + new_verts *= 2; - if (new_verts > mNumAllocatedVertices) - { - // double buffer size on expansion - new_verts *= 2; + S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; + S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; - S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; - S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; + S32 old_vsize = mNumVertices*16; - S32 old_vsize = mNumVertices*16; - - S32 new_size = new_verts*16*2+new_tc_size; + S32 new_size = new_verts*16*2+new_tc_size; - LLVector4a* old_buf = mPositions; + LLVector4a* old_buf = mPositions; - mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); - mNormals = mPositions+new_verts; - mTexCoords = (LLVector2*) (mNormals+new_verts); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); + mNormals = mPositions+new_verts; + mTexCoords = (LLVector2*) (mNormals+new_verts); - if (old_buf != NULL) - { - // copy old positions into new buffer - LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize); + if (old_buf != NULL) + { + // copy old positions into new buffer + LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize); - // normals - LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize); + // normals + LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize); - // tex coords - LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size); - } + // tex coords + LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size); + } - // just clear tangents - ll_aligned_free_16(mTangents); - mTangents = NULL; - ll_aligned_free<64>(old_buf); + // just clear tangents + ll_aligned_free_16(mTangents); + mTangents = NULL; + ll_aligned_free<64>(old_buf); - mNumAllocatedVertices = new_verts; + mNumAllocatedVertices = new_verts; - } + } - mPositions[mNumVertices] = pos; - mNormals[mNumVertices] = norm; - mTexCoords[mNumVertices] = tc; + mPositions[mNumVertices] = pos; + mNormals[mNumVertices] = norm; + mTexCoords[mNumVertices] = tc; - mNumVertices++; + mNumVertices++; } void LLVolumeFace::allocateTangents(S32 num_verts) { - ll_aligned_free_16(mTangents); - mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + ll_aligned_free_16(mTangents); + mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } void LLVolumeFace::allocateWeights(S32 num_verts) { - ll_aligned_free_16(mWeights); - mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - + ll_aligned_free_16(mWeights); + mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + } void LLVolumeFace::allocateJointIndices(S32 num_verts) @@ -6526,27 +6526,27 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts) ll_aligned_free_16(mJointIndices); ll_aligned_free_16(mJustWeights); - mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts); - mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts); + mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts); + mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts); #endif } void LLVolumeFace::resizeIndices(S32 num_indices) { - ll_aligned_free_16(mIndices); + ll_aligned_free_16(mIndices); llassert(num_indices % 3 == 0); - - if (num_indices) - { - //pad index block end to allow for QWORD reads - S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF; - - mIndices = (U16*) ll_aligned_malloc_16(size); - } - else - { - mIndices = NULL; - } + + if (num_indices) + { + //pad index block end to allow for QWORD reads + S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF; + + mIndices = (U16*) ll_aligned_malloc_16(size); + } + else + { + mIndices = NULL; + } if (mIndices) { @@ -6561,73 +6561,73 @@ void LLVolumeFace::resizeIndices(S32 num_indices) void LLVolumeFace::pushIndex(const U16& idx) { - S32 new_count = mNumIndices + 1; - S32 new_size = ((new_count*2)+0xF) & ~0xF; + S32 new_count = mNumIndices + 1; + S32 new_size = ((new_count*2)+0xF) & ~0xF; + + S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; + if (new_size != old_size) + { + mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); + ll_assert_aligned(mIndices,16); + } - S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; - if (new_size != old_size) - { - mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); - ll_assert_aligned(mIndices,16); - } - - mIndices[mNumIndices++] = idx; + mIndices[mNumIndices++] = idx; } void LLVolumeFace::fillFromLegacyData(std::vector& v, std::vector& idx) { - resizeVertices(v.size()); - resizeIndices(idx.size()); + resizeVertices(v.size()); + resizeIndices(idx.size()); - for (U32 i = 0; i < v.size(); ++i) - { - mPositions[i] = v[i].getPosition(); - mNormals[i] = v[i].getNormal(); - mTexCoords[i] = v[i].mTexCoord; - } + for (U32 i = 0; i < v.size(); ++i) + { + mPositions[i] = v[i].getPosition(); + mNormals[i] = v[i].getNormal(); + mTexCoords[i] = v[i].mTexCoord; + } - for (U32 i = 0; i < idx.size(); ++i) - { - mIndices[i] = idx[i]; - } + for (U32 i = 0; i < idx.size(); ++i) + { + mIndices[i] = idx[i]; + } } BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + + LL_CHECK_MEMORY + BOOL flat = mTypeMask & FLAT_MASK; - LL_CHECK_MEMORY - BOOL flat = mTypeMask & FLAT_MASK; + U8 sculpt_type = volume->getParams().getSculptType(); + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; + BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; + BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR - U8 sculpt_type = volume->getParams().getSculptType(); - U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; - BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; - BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; - BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR - - S32 num_vertices, num_indices; + S32 num_vertices, num_indices; - const LLAlignedArray& mesh = volume->getMesh(); - const LLAlignedArray& profile = volume->getProfile().mProfile; - const LLAlignedArray& path_data = volume->getPath().mPath; + const LLAlignedArray& mesh = volume->getMesh(); + const LLAlignedArray& profile = volume->getProfile().mProfile; + const LLAlignedArray& path_data = volume->getPath().mPath; - S32 max_s = volume->getProfile().getTotal(); + S32 max_s = volume->getProfile().getTotal(); - S32 s, t, i; - F32 ss, tt; + S32 s, t, i; + F32 ss, tt; - num_vertices = mNumS*mNumT; - num_indices = (mNumS-1)*(mNumT-1)*6; + num_vertices = mNumS*mNumT; + num_indices = (mNumS-1)*(mNumT-1)*6; - partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build; + partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build; - if (!partial_build) - { - resizeVertices(num_vertices); - resizeIndices(num_indices); + if (!partial_build) + { + resizeVertices(num_vertices); + resizeIndices(num_indices); - if (!volume->isMeshAssetLoaded()) - { + if (!volume->isMeshAssetLoaded()) + { try { mEdge.resize(num_indices); @@ -6637,237 +6637,237 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL; return false; } - } - } - - LL_CHECK_MEMORY - - LLVector4a* pos = (LLVector4a*) mPositions; - LLVector2* tc = (LLVector2*) mTexCoords; - F32 begin_stex = floorf(profile[mBeginS][2]); - S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; - - S32 cur_vertex = 0; - S32 end_t = mBeginT+mNumT; - bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; - - // Copy the vertices into the array - for (t = mBeginT; t < end_t; t++) - { - tt = path_data[t].mTexT; - for (s = 0; s < num_s; s++) - { - if (mTypeMask & END_MASK) - { - if (s) - { - ss = 1.f; - } - else - { - ss = 0.f; - } - } - else - { - // Get s value for tex-coord. + } + } + + LL_CHECK_MEMORY + + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector2* tc = (LLVector2*) mTexCoords; + F32 begin_stex = floorf(profile[mBeginS][2]); + S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; + + S32 cur_vertex = 0; + S32 end_t = mBeginT+mNumT; + bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; + + // Copy the vertices into the array + for (t = mBeginT; t < end_t; t++) + { + tt = path_data[t].mTexT; + for (s = 0; s < num_s; s++) + { + if (mTypeMask & END_MASK) + { + if (s) + { + ss = 1.f; + } + else + { + ss = 0.f; + } + } + else + { + // Get s value for tex-coord. S32 index = mBeginS + s; if (index >= profile.size()) { // edge? ss = flat ? 1.f - begin_stex : 1.f; } - else if (!flat) - { - ss = profile[index][2]; - } - else - { - ss = profile[index][2] - begin_stex; - } - } - - if (sculpt_reverse_horizontal) - { - ss = 1.f - ss; - } - - // Check to see if this triangle wraps around the array. - if (mBeginS + s >= max_s) - { - // We're wrapping - i = mBeginS + s + max_s*(t-1); - } - else - { - i = mBeginS + s + max_s*t; - } - - mesh[i].store4a((F32*)(pos+cur_vertex)); - tc[cur_vertex].set(ss,tt); - - cur_vertex++; - - if (test && s > 0) - { - mesh[i].store4a((F32*)(pos+cur_vertex)); - tc[cur_vertex].set(ss,tt); - cur_vertex++; - } - } - - if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) - { - if (mTypeMask & OPEN_MASK) - { - s = num_s-1; - } - else - { - s = 0; - } - - i = mBeginS + s + max_s*t; - ss = profile[mBeginS + s][2] - begin_stex; - - mesh[i].store4a((F32*)(pos+cur_vertex)); - tc[cur_vertex].set(ss,tt); - - cur_vertex++; - } - } - LL_CHECK_MEMORY - - mCenter->clear(); - - LLVector4a* cur_pos = pos; - LLVector4a* end_pos = pos + mNumVertices; - - //get bounding box for this side - LLVector4a face_min; - LLVector4a face_max; - - face_min = face_max = *cur_pos++; - - while (cur_pos < end_pos) - { - update_min_max(face_min, face_max, *cur_pos++); - } - // VFExtents change - mExtents[0] = face_min; - mExtents[1] = face_max; - - U32 tc_count = mNumVertices; - if (tc_count%2 == 1) - { //odd number of texture coordinates, duplicate last entry to padded end of array - tc_count++; - mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1]; - } - - LLVector4a* cur_tc = (LLVector4a*) mTexCoords; - LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count); - - LLVector4a tc_min; - LLVector4a tc_max; - - tc_min = tc_max = *cur_tc++; - - while (cur_tc < end_tc) - { - update_min_max(tc_min, tc_max, *cur_tc++); - } - - F32* minp = tc_min.getF32ptr(); - F32* maxp = tc_max.getF32ptr(); - - mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]); - mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]); - mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]); - mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]); - - mCenter->setAdd(face_min, face_max); - mCenter->mul(0.5f); - - S32 cur_index = 0; - S32 cur_edge = 0; - BOOL flat_face = mTypeMask & FLAT_MASK; - - if (!partial_build) - { - // Now we generate the indices. - for (t = 0; t < (mNumT-1); t++) - { - for (s = 0; s < (mNumS-1); s++) - { - mIndices[cur_index++] = s + mNumS*t; //bottom left - mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right - mIndices[cur_index++] = s + mNumS*(t+1); //top left - mIndices[cur_index++] = s + mNumS*t; //bottom left - mIndices[cur_index++] = s+1 + mNumS*t; //bottom right - mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right - - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face - if (t < mNumT-2) { //top right/top left neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; - } - else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on T - mEdge[cur_edge++] = s*2+1; - } - if (s > 0) { //top left/bottom left neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; - } - else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on S - mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; - } - - if (t > 0) { //bottom left/bottom right neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; - } - else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on T - mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; - } - if (s < mNumS-2) { //bottom right/top right neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; - } - else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on S - mEdge[cur_edge++] = (mNumS-1)*2*t; - } - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face - } - } - } - - LL_CHECK_MEMORY - - //clear normals - F32* dst = (F32*) mNormals; - F32* end = (F32*) (mNormals+mNumVertices); - LLVector4a zero = LLVector4a::getZero(); - - while (dst < end) - { - zero.store4a(dst); - dst += 4; - } - - LL_CHECK_MEMORY - - //generate normals - U32 count = mNumIndices/3; - - LLVector4a* norm = mNormals; + else if (!flat) + { + ss = profile[index][2]; + } + else + { + ss = profile[index][2] - begin_stex; + } + } + + if (sculpt_reverse_horizontal) + { + ss = 1.f - ss; + } + + // Check to see if this triangle wraps around the array. + if (mBeginS + s >= max_s) + { + // We're wrapping + i = mBeginS + s + max_s*(t-1); + } + else + { + i = mBeginS + s + max_s*t; + } + + mesh[i].store4a((F32*)(pos+cur_vertex)); + tc[cur_vertex].set(ss,tt); + + cur_vertex++; + + if (test && s > 0) + { + mesh[i].store4a((F32*)(pos+cur_vertex)); + tc[cur_vertex].set(ss,tt); + cur_vertex++; + } + } + + if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) + { + if (mTypeMask & OPEN_MASK) + { + s = num_s-1; + } + else + { + s = 0; + } + + i = mBeginS + s + max_s*t; + ss = profile[mBeginS + s][2] - begin_stex; + + mesh[i].store4a((F32*)(pos+cur_vertex)); + tc[cur_vertex].set(ss,tt); + + cur_vertex++; + } + } + LL_CHECK_MEMORY + + mCenter->clear(); + + LLVector4a* cur_pos = pos; + LLVector4a* end_pos = pos + mNumVertices; + + //get bounding box for this side + LLVector4a face_min; + LLVector4a face_max; + + face_min = face_max = *cur_pos++; + + while (cur_pos < end_pos) + { + update_min_max(face_min, face_max, *cur_pos++); + } + // VFExtents change + mExtents[0] = face_min; + mExtents[1] = face_max; + + U32 tc_count = mNumVertices; + if (tc_count%2 == 1) + { //odd number of texture coordinates, duplicate last entry to padded end of array + tc_count++; + mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1]; + } + + LLVector4a* cur_tc = (LLVector4a*) mTexCoords; + LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count); + + LLVector4a tc_min; + LLVector4a tc_max; + + tc_min = tc_max = *cur_tc++; + + while (cur_tc < end_tc) + { + update_min_max(tc_min, tc_max, *cur_tc++); + } + + F32* minp = tc_min.getF32ptr(); + F32* maxp = tc_max.getF32ptr(); + + mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]); + mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]); + mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]); + mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]); + + mCenter->setAdd(face_min, face_max); + mCenter->mul(0.5f); + + S32 cur_index = 0; + S32 cur_edge = 0; + BOOL flat_face = mTypeMask & FLAT_MASK; + + if (!partial_build) + { + // Now we generate the indices. + for (t = 0; t < (mNumT-1); t++) + { + for (s = 0; s < (mNumS-1); s++) + { + mIndices[cur_index++] = s + mNumS*t; //bottom left + mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right + mIndices[cur_index++] = s + mNumS*(t+1); //top left + mIndices[cur_index++] = s + mNumS*t; //bottom left + mIndices[cur_index++] = s+1 + mNumS*t; //bottom right + mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right + + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face + if (t < mNumT-2) { //top right/top left neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; + } + else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on T + mEdge[cur_edge++] = s*2+1; + } + if (s > 0) { //top left/bottom left neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; + } + else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on S + mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; + } + + if (t > 0) { //bottom left/bottom right neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; + } + else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on T + mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; + } + if (s < mNumS-2) { //bottom right/top right neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; + } + else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on S + mEdge[cur_edge++] = (mNumS-1)*2*t; + } + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face + } + } + } + + LL_CHECK_MEMORY + + //clear normals + F32* dst = (F32*) mNormals; + F32* end = (F32*) (mNormals+mNumVertices); + LLVector4a zero = LLVector4a::getZero(); + + while (dst < end) + { + zero.store4a(dst); + dst += 4; + } + + LL_CHECK_MEMORY + + //generate normals + U32 count = mNumIndices/3; + + LLVector4a* norm = mNormals; static thread_local LLAlignedArray triangle_normals; try @@ -6879,242 +6879,242 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL; return false; } - LLVector4a* output = triangle_normals.mArray; - LLVector4a* end_output = output+count; - - U16* idx = mIndices; - - while (output < end_output) - { - LLVector4a b,v1,v2; - b.load4a((F32*) (pos+idx[0])); - v1.load4a((F32*) (pos+idx[1])); - v2.load4a((F32*) (pos+idx[2])); - - //calculate triangle normal - LLVector4a a; - - a.setSub(b, v1); - b.sub(v2); - - - LLQuad& vector1 = *((LLQuad*) &v1); - LLQuad& vector2 = *((LLQuad*) &v2); - - LLQuad& amQ = *((LLQuad*) &a); - LLQuad& bmQ = *((LLQuad*) &b); - - //v1.setCross3(t,v0); - //setCross3(const LLVector4a& a, const LLVector4a& b) - // Vectors are stored in memory in w, z, y, x order from high to low - // Set vector1 = { a[W], a[X], a[Z], a[Y] } - vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 )); - // Set vector2 = { b[W], b[Y], b[X], b[Z] } - vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 )); - // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } - vector2 = _mm_mul_ps( vector1, vector2 ); - // vector3 = { a[W], a[Y], a[X], a[Z] } - amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 )); - // vector4 = { b[W], b[X], b[Z], b[Y] } - bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 )); - // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } - vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ )); - - llassert(v1.isFinite3()); - - v1.store4a((F32*) output); - - - output++; - idx += 3; - } - - idx = mIndices; - - LLVector4a* src = triangle_normals.mArray; - - for (U32 i = 0; i < count; i++) //for each triangle - { - LLVector4a c; - c.load4a((F32*) (src++)); - - LLVector4a* n0p = norm+idx[0]; - LLVector4a* n1p = norm+idx[1]; - LLVector4a* n2p = norm+idx[2]; - - idx += 3; - - LLVector4a n0,n1,n2; - n0.load4a((F32*) n0p); - n1.load4a((F32*) n1p); - n2.load4a((F32*) n2p); - - n0.add(c); - n1.add(c); - n2.add(c); - - llassert(c.isFinite3()); - - //even out quad contributions - switch (i%2+1) - { - case 0: n0.add(c); break; - case 1: n1.add(c); break; - case 2: n2.add(c); break; - }; - - n0.store4a((F32*) n0p); - n1.store4a((F32*) n1p); - n2.store4a((F32*) n2p); - } - - LL_CHECK_MEMORY - - // adjust normals based on wrapping and stitching - - LLVector4a top; - top.setSub(pos[0], pos[mNumS*(mNumT-2)]); - BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); - - top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); - BOOL s_top_converges = (top.dot3(top) < 0.000001f); - - if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes - { - if (volume->getPath().isOpen() == FALSE) - { //wrap normals on T - for (S32 i = 0; i < mNumS; i++) - { - LLVector4a n; - n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); - norm[i] = n; - norm[mNumS*(mNumT-1)+i] = n; - } - } - - if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges)) - { //wrap normals on S - for (S32 i = 0; i < mNumT; i++) - { - LLVector4a n; - n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); - norm[mNumS * i] = n; - norm[mNumS * i+mNumS-1] = n; - } - } - - if (volume->getPathType() == LL_PCODE_PATH_CIRCLE && - ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) - { - if (s_bottom_converges) - { //all lower S have same normal - for (S32 i = 0; i < mNumT; i++) - { - norm[mNumS*i].set(1,0,0); - } - } - - if (s_top_converges) - { //all upper S have same normal - for (S32 i = 0; i < mNumT; i++) - { - norm[mNumS*i+mNumS-1].set(-1,0,0); - } - } - } - } - else // logic for sculpt volumes - { - BOOL average_poles = FALSE; - BOOL wrap_s = FALSE; - BOOL wrap_t = FALSE; - - if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) - average_poles = TRUE; - - if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || - (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || - (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) - wrap_s = TRUE; - - if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) - wrap_t = TRUE; - - - if (average_poles) - { - // average normals for north pole - - LLVector4a average; - average.clear(); - - for (S32 i = 0; i < mNumS; i++) - { - average.add(norm[i]); - } - - // set average - for (S32 i = 0; i < mNumS; i++) - { - norm[i] = average; - } - - // average normals for south pole - - average.clear(); - - for (S32 i = 0; i < mNumS; i++) - { - average.add(norm[i + mNumS * (mNumT - 1)]); - } - - // set average - for (S32 i = 0; i < mNumS; i++) - { - norm[i + mNumS * (mNumT - 1)] = average; - } - - } - - - if (wrap_s) - { - for (S32 i = 0; i < mNumT; i++) - { - LLVector4a n; - n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); - norm[mNumS * i] = n; - norm[mNumS * i+mNumS-1] = n; - } - } - - if (wrap_t) - { - for (S32 i = 0; i < mNumS; i++) - { - LLVector4a n; - n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); - norm[i] = n; - norm[mNumS*(mNumT-1)+i] = n; - } - } - - } - - LL_CHECK_MEMORY - - return TRUE; + LLVector4a* output = triangle_normals.mArray; + LLVector4a* end_output = output+count; + + U16* idx = mIndices; + + while (output < end_output) + { + LLVector4a b,v1,v2; + b.load4a((F32*) (pos+idx[0])); + v1.load4a((F32*) (pos+idx[1])); + v2.load4a((F32*) (pos+idx[2])); + + //calculate triangle normal + LLVector4a a; + + a.setSub(b, v1); + b.sub(v2); + + + LLQuad& vector1 = *((LLQuad*) &v1); + LLQuad& vector2 = *((LLQuad*) &v2); + + LLQuad& amQ = *((LLQuad*) &a); + LLQuad& bmQ = *((LLQuad*) &b); + + //v1.setCross3(t,v0); + //setCross3(const LLVector4a& a, const LLVector4a& b) + // Vectors are stored in memory in w, z, y, x order from high to low + // Set vector1 = { a[W], a[X], a[Z], a[Y] } + vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 )); + // Set vector2 = { b[W], b[Y], b[X], b[Z] } + vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 )); + // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } + vector2 = _mm_mul_ps( vector1, vector2 ); + // vector3 = { a[W], a[Y], a[X], a[Z] } + amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 )); + // vector4 = { b[W], b[X], b[Z], b[Y] } + bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 )); + // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } + vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ )); + + llassert(v1.isFinite3()); + + v1.store4a((F32*) output); + + + output++; + idx += 3; + } + + idx = mIndices; + + LLVector4a* src = triangle_normals.mArray; + + for (U32 i = 0; i < count; i++) //for each triangle + { + LLVector4a c; + c.load4a((F32*) (src++)); + + LLVector4a* n0p = norm+idx[0]; + LLVector4a* n1p = norm+idx[1]; + LLVector4a* n2p = norm+idx[2]; + + idx += 3; + + LLVector4a n0,n1,n2; + n0.load4a((F32*) n0p); + n1.load4a((F32*) n1p); + n2.load4a((F32*) n2p); + + n0.add(c); + n1.add(c); + n2.add(c); + + llassert(c.isFinite3()); + + //even out quad contributions + switch (i%2+1) + { + case 0: n0.add(c); break; + case 1: n1.add(c); break; + case 2: n2.add(c); break; + }; + + n0.store4a((F32*) n0p); + n1.store4a((F32*) n1p); + n2.store4a((F32*) n2p); + } + + LL_CHECK_MEMORY + + // adjust normals based on wrapping and stitching + + LLVector4a top; + top.setSub(pos[0], pos[mNumS*(mNumT-2)]); + BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); + + top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); + BOOL s_top_converges = (top.dot3(top) < 0.000001f); + + if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes + { + if (volume->getPath().isOpen() == FALSE) + { //wrap normals on T + for (S32 i = 0; i < mNumS; i++) + { + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; + } + } + + if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges)) + { //wrap normals on S + for (S32 i = 0; i < mNumT; i++) + { + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; + } + } + + if (volume->getPathType() == LL_PCODE_PATH_CIRCLE && + ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) + { + if (s_bottom_converges) + { //all lower S have same normal + for (S32 i = 0; i < mNumT; i++) + { + norm[mNumS*i].set(1,0,0); + } + } + + if (s_top_converges) + { //all upper S have same normal + for (S32 i = 0; i < mNumT; i++) + { + norm[mNumS*i+mNumS-1].set(-1,0,0); + } + } + } + } + else // logic for sculpt volumes + { + BOOL average_poles = FALSE; + BOOL wrap_s = FALSE; + BOOL wrap_t = FALSE; + + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) + average_poles = TRUE; + + if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || + (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || + (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) + wrap_s = TRUE; + + if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) + wrap_t = TRUE; + + + if (average_poles) + { + // average normals for north pole + + LLVector4a average; + average.clear(); + + for (S32 i = 0; i < mNumS; i++) + { + average.add(norm[i]); + } + + // set average + for (S32 i = 0; i < mNumS; i++) + { + norm[i] = average; + } + + // average normals for south pole + + average.clear(); + + for (S32 i = 0; i < mNumS; i++) + { + average.add(norm[i + mNumS * (mNumT - 1)]); + } + + // set average + for (S32 i = 0; i < mNumS; i++) + { + norm[i + mNumS * (mNumT - 1)] = average; + } + + } + + + if (wrap_s) + { + for (S32 i = 0; i < mNumT; i++) + { + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; + } + } + + if (wrap_t) + { + for (S32 i = 0; i < mNumS; i++) + { + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; + } + } + + } + + LL_CHECK_MEMORY + + return TRUE; } //adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; - LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); - // new(tan1) LLVector4a; + LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); + // new(tan1) LLVector4a; LLVector4a* tan2 = tan1 + vertexCount; @@ -7129,86 +7129,86 @@ void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LL U32 i1 = *index_array++; U32 i2 = *index_array++; U32 i3 = *index_array++; - + const LLVector4a& v1 = vertex[i1]; const LLVector4a& v2 = vertex[i2]; const LLVector4a& v3 = vertex[i3]; - + const LLVector2& w1 = texcoord[i1]; const LLVector2& w2 = texcoord[i2]; const LLVector2& w3 = texcoord[i3]; - - const F32* v1ptr = v1.getF32ptr(); - const F32* v2ptr = v2.getF32ptr(); - const F32* v3ptr = v3.getF32ptr(); - + + const F32* v1ptr = v1.getF32ptr(); + const F32* v2ptr = v2.getF32ptr(); + const F32* v3ptr = v3.getF32ptr(); + float x1 = v2ptr[0] - v1ptr[0]; float x2 = v3ptr[0] - v1ptr[0]; float y1 = v2ptr[1] - v1ptr[1]; float y2 = v3ptr[1] - v1ptr[1]; float z1 = v2ptr[2] - v1ptr[2]; float z2 = v3ptr[2] - v1ptr[2]; - + float s1 = w2.mV[0] - w1.mV[0]; float s2 = w3.mV[0] - w1.mV[0]; float t1 = w2.mV[1] - w1.mV[1]; float t2 = w3.mV[1] - w1.mV[1]; - - F32 rd = s1*t2-s2*t1; - - float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) - : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero - - llassert(llfinite(r)); - llassert(!llisnan(r)); - - LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); - - tan1[i1].add(sdir); - tan1[i2].add(sdir); - tan1[i3].add(sdir); - - tan2[i1].add(tdir); - tan2[i2].add(tdir); - tan2[i3].add(tdir); - } - + + F32 rd = s1*t2-s2*t1; + + float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) + : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero + + llassert(llfinite(r)); + llassert(!llisnan(r)); + + LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + + tan1[i1].add(sdir); + tan1[i2].add(sdir); + tan1[i3].add(sdir); + + tan2[i1].add(tdir); + tan2[i2].add(tdir); + tan2[i3].add(tdir); + } + for (U32 a = 0; a < vertexCount; a++) { LLVector4a n = normal[a]; - const LLVector4a& t = tan1[a]; + const LLVector4a& t = tan1[a]; - LLVector4a ncrosst; - ncrosst.setCross3(n,t); + LLVector4a ncrosst; + ncrosst.setCross3(n,t); // Gram-Schmidt orthogonalize n.mul(n.dot3(t).getF32()); - LLVector4a tsubn; - tsubn.setSub(t,n); - - if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) - { - tsubn.normalize3fast(); - - // Calculate handedness - F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; - - tsubn.getF32ptr()[3] = handedness; - - tangent[a] = tsubn; - } - else - { //degenerate, make up a value - tangent[a].set(0,0,1,1); - } - } - - ll_aligned_free_16(tan1); + LLVector4a tsubn; + tsubn.setSub(t,n); + + if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) + { + tsubn.normalize3fast(); + + // Calculate handedness + F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; + + tsubn.getF32ptr()[3] = handedness; + + tangent[a] = tsubn; + } + else + { //degenerate, make up a value + tangent[a].set(0,0,1,1); + } + } + + ll_aligned_free_16(tan1); } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ccc0671315..d53ca2a4b3 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1,25 +1,25 @@ -/** +/** * @file llvolume.h * @brief LLVolume base class. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -70,8 +70,8 @@ const S32 MAX_LOD = 3; // These are defined here but are not enforced at this level, // rather they are here for the convenience of code that uses // the LLVolume class. -const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f; -const F32 MIN_VOLUME_PATH_WIDTH = 0.05f; +const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f; +const F32 MIN_VOLUME_PATH_WIDTH = 0.05f; const F32 CUT_QUANTA = 0.00002f; const F32 SCALE_QUANTA = 0.01f; @@ -85,100 +85,100 @@ const S32 MAX_VOLUME_TRIANGLE_INDICES = 10000; //============================================================================ // useful masks -const LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // has a thickness -const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle) -const LLPCode LL_PCODE_PATCH_MASK = 0x20; // segmented segments (2 angles) -const LLPCode LL_PCODE_HEMI_MASK = 0x10; // half-primitives get their own type per PR's dictum -const LLPCode LL_PCODE_BASE_MASK = 0x0F; - - // primitive shapes -const LLPCode LL_PCODE_CUBE = 1; -const LLPCode LL_PCODE_PRISM = 2; -const LLPCode LL_PCODE_TETRAHEDRON = 3; -const LLPCode LL_PCODE_PYRAMID = 4; -const LLPCode LL_PCODE_CYLINDER = 5; -const LLPCode LL_PCODE_CONE = 6; -const LLPCode LL_PCODE_SPHERE = 7; -const LLPCode LL_PCODE_TORUS = 8; -const LLPCode LL_PCODE_VOLUME = 9; - - // surfaces -//const LLPCode LL_PCODE_SURFACE_TRIANGLE = 10; -//const LLPCode LL_PCODE_SURFACE_SQUARE = 11; -//const LLPCode LL_PCODE_SURFACE_DISC = 12; - -const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects) -const LLPCode LL_PCODE_LEGACY = 15; +const LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // has a thickness +const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle) +const LLPCode LL_PCODE_PATCH_MASK = 0x20; // segmented segments (2 angles) +const LLPCode LL_PCODE_HEMI_MASK = 0x10; // half-primitives get their own type per PR's dictum +const LLPCode LL_PCODE_BASE_MASK = 0x0F; + + // primitive shapes +const LLPCode LL_PCODE_CUBE = 1; +const LLPCode LL_PCODE_PRISM = 2; +const LLPCode LL_PCODE_TETRAHEDRON = 3; +const LLPCode LL_PCODE_PYRAMID = 4; +const LLPCode LL_PCODE_CYLINDER = 5; +const LLPCode LL_PCODE_CONE = 6; +const LLPCode LL_PCODE_SPHERE = 7; +const LLPCode LL_PCODE_TORUS = 8; +const LLPCode LL_PCODE_VOLUME = 9; + + // surfaces +//const LLPCode LL_PCODE_SURFACE_TRIANGLE = 10; +//const LLPCode LL_PCODE_SURFACE_SQUARE = 11; +//const LLPCode LL_PCODE_SURFACE_DISC = 12; + +const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects) +const LLPCode LL_PCODE_LEGACY = 15; // Pcodes for legacy objects -//const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR -const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER -//const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD -//const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON -const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS -const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees -//const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE -const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS -const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK -//const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT -//const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY; -//const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE -//const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK -const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE -const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE - - // hemis -const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK; -const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK; -const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK; -const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK; +//const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR +const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER +//const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD +//const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON +const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS +const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees +//const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE +const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS +const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK +//const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT +//const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY; +//const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE +//const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK +const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE +const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE + + // hemis +const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK; +const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK; +const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK; +const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK; // Volumes consist of a profile at the base that is swept around // a path to make a volume. // The profile code -const U8 LL_PCODE_PROFILE_MASK = 0x0f; -const U8 LL_PCODE_PROFILE_MIN = 0x00; -const U8 LL_PCODE_PROFILE_CIRCLE = 0x00; -const U8 LL_PCODE_PROFILE_SQUARE = 0x01; -const U8 LL_PCODE_PROFILE_ISOTRI = 0x02; -const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03; -const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04; -const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05; -const U8 LL_PCODE_PROFILE_MAX = 0x05; +const U8 LL_PCODE_PROFILE_MASK = 0x0f; +const U8 LL_PCODE_PROFILE_MIN = 0x00; +const U8 LL_PCODE_PROFILE_CIRCLE = 0x00; +const U8 LL_PCODE_PROFILE_SQUARE = 0x01; +const U8 LL_PCODE_PROFILE_ISOTRI = 0x02; +const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03; +const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04; +const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05; +const U8 LL_PCODE_PROFILE_MAX = 0x05; // Stored in the profile byte -const U8 LL_PCODE_HOLE_MASK = 0xf0; -const U8 LL_PCODE_HOLE_MIN = 0x00; -const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile -const U8 LL_PCODE_HOLE_CIRCLE = 0x10; -const U8 LL_PCODE_HOLE_SQUARE = 0x20; -const U8 LL_PCODE_HOLE_TRIANGLE = 0x30; -const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max +const U8 LL_PCODE_HOLE_MASK = 0xf0; +const U8 LL_PCODE_HOLE_MIN = 0x00; +const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile +const U8 LL_PCODE_HOLE_CIRCLE = 0x10; +const U8 LL_PCODE_HOLE_SQUARE = 0x20; +const U8 LL_PCODE_HOLE_TRIANGLE = 0x30; +const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max const U8 LL_PCODE_PATH_IGNORE = 0x00; -const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max +const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max const U8 LL_PCODE_PATH_LINE = 0x10; const U8 LL_PCODE_PATH_CIRCLE = 0x20; const U8 LL_PCODE_PATH_CIRCLE2 = 0x30; const U8 LL_PCODE_PATH_TEST = 0x40; const U8 LL_PCODE_PATH_FLEXIBLE = 0x80; -const U8 LL_PCODE_PATH_MAX = 0x08; +const U8 LL_PCODE_PATH_MAX = 0x08; //============================================================================ // face identifiers typedef U16 LLFaceID; -const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0; -const LLFaceID LL_FACE_PATH_END = 0x1 << 1; -const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2; -const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3; -const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4; -const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5; -const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6; -const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7; -const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8; +const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0; +const LLFaceID LL_FACE_PATH_END = 0x1 << 1; +const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2; +const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3; +const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4; +const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5; +const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6; +const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7; +const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8; //============================================================================ @@ -191,7 +191,7 @@ const U8 LL_SCULPT_TYPE_PLANE = 3; const U8 LL_SCULPT_TYPE_CYLINDER = 4; const U8 LL_SCULPT_TYPE_MESH = 5; const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | - LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH; + LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH; // for value checks, assign new value after adding new types const U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_MESH; @@ -207,125 +207,125 @@ extern BOOL gDebugGL; class LLProfileParams { public: - LLProfileParams() - : mCurveType(LL_PCODE_PROFILE_SQUARE), - mBegin(0.f), - mEnd(1.f), - mHollow(0.f), - mCRC(0) - { - } - - LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow) - : mCurveType(curve), - mBegin(begin), - mEnd(end), - mHollow(hollow), - mCRC(0) - { - } - - LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow) - { - mCurveType = curve; - F32 temp_f32 = begin * CUT_QUANTA; - if (temp_f32 > 1.f) - { - temp_f32 = 1.f; - } - mBegin = temp_f32; - temp_f32 = end * CUT_QUANTA; - if (temp_f32 > 1.f) - { - temp_f32 = 1.f; - } - mEnd = 1.f - temp_f32; - temp_f32 = hollow * HOLLOW_QUANTA; - if (temp_f32 > 1.f) - { - temp_f32 = 1.f; - } - mHollow = temp_f32; - mCRC = 0; - } - - bool operator==(const LLProfileParams ¶ms) const; - bool operator!=(const LLProfileParams ¶ms) const; - bool operator<(const LLProfileParams ¶ms) const; - - void copyParams(const LLProfileParams ¶ms); - - BOOL importFile(LLFILE *fp); - BOOL exportFile(LLFILE *fp) const; - - BOOL importLegacyStream(std::istream& input_stream); - BOOL exportLegacyStream(std::ostream& output_stream) const; - - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - const F32& getBegin () const { return mBegin; } - const F32& getEnd () const { return mEnd; } - const F32& getHollow() const { return mHollow; } - const U8& getCurveType () const { return mCurveType; } - - void setCurveType(const U32 type) { mCurveType = type;} - void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;} - void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;} - void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;} - - friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params); + LLProfileParams() + : mCurveType(LL_PCODE_PROFILE_SQUARE), + mBegin(0.f), + mEnd(1.f), + mHollow(0.f), + mCRC(0) + { + } + + LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow) + : mCurveType(curve), + mBegin(begin), + mEnd(end), + mHollow(hollow), + mCRC(0) + { + } + + LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow) + { + mCurveType = curve; + F32 temp_f32 = begin * CUT_QUANTA; + if (temp_f32 > 1.f) + { + temp_f32 = 1.f; + } + mBegin = temp_f32; + temp_f32 = end * CUT_QUANTA; + if (temp_f32 > 1.f) + { + temp_f32 = 1.f; + } + mEnd = 1.f - temp_f32; + temp_f32 = hollow * HOLLOW_QUANTA; + if (temp_f32 > 1.f) + { + temp_f32 = 1.f; + } + mHollow = temp_f32; + mCRC = 0; + } + + bool operator==(const LLProfileParams ¶ms) const; + bool operator!=(const LLProfileParams ¶ms) const; + bool operator<(const LLProfileParams ¶ms) const; + + void copyParams(const LLProfileParams ¶ms); + + BOOL importFile(LLFILE *fp); + BOOL exportFile(LLFILE *fp) const; + + BOOL importLegacyStream(std::istream& input_stream); + BOOL exportLegacyStream(std::ostream& output_stream) const; + + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + const F32& getBegin () const { return mBegin; } + const F32& getEnd () const { return mEnd; } + const F32& getHollow() const { return mHollow; } + const U8& getCurveType () const { return mCurveType; } + + void setCurveType(const U32 type) { mCurveType = type;} + void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;} + void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;} + void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;} + + friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params); protected: - // Profile params - U8 mCurveType; - F32 mBegin; - F32 mEnd; - F32 mHollow; + // Profile params + U8 mCurveType; + F32 mBegin; + F32 mEnd; + F32 mHollow; - U32 mCRC; + U32 mCRC; }; inline bool LLProfileParams::operator==(const LLProfileParams ¶ms) const { - return - (getCurveType() == params.getCurveType()) && - (getBegin() == params.getBegin()) && - (getEnd() == params.getEnd()) && - (getHollow() == params.getHollow()); + return + (getCurveType() == params.getCurveType()) && + (getBegin() == params.getBegin()) && + (getEnd() == params.getEnd()) && + (getHollow() == params.getHollow()); } inline bool LLProfileParams::operator!=(const LLProfileParams ¶ms) const { - return - (getCurveType() != params.getCurveType()) || - (getBegin() != params.getBegin()) || - (getEnd() != params.getEnd()) || - (getHollow() != params.getHollow()); + return + (getCurveType() != params.getCurveType()) || + (getBegin() != params.getBegin()) || + (getEnd() != params.getEnd()) || + (getHollow() != params.getHollow()); } inline bool LLProfileParams::operator<(const LLProfileParams ¶ms) const { - if (getCurveType() != params.getCurveType()) - { - return getCurveType() < params.getCurveType(); - } - else - if (getBegin() != params.getBegin()) - { - return getBegin() < params.getBegin(); - } - else - if (getEnd() != params.getEnd()) - { - return getEnd() < params.getEnd(); - } - else - { - return getHollow() < params.getHollow(); - } + if (getCurveType() != params.getCurveType()) + { + return getCurveType() < params.getCurveType(); + } + else + if (getBegin() != params.getBegin()) + { + return getBegin() < params.getBegin(); + } + else + if (getEnd() != params.getEnd()) + { + return getEnd() < params.getEnd(); + } + else + { + return getHollow() < params.getHollow(); + } } #define U8_TO_F32(x) (F32)(*((S8 *)&x)) @@ -333,225 +333,225 @@ inline bool LLProfileParams::operator<(const LLProfileParams ¶ms) const class LLPathParams { public: - LLPathParams() - : - mCurveType(LL_PCODE_PATH_LINE), - mBegin(0.f), - mEnd(1.f), - mScale(1.f,1.f), - mShear(0.f,0.f), - mTwistBegin(0.f), - mTwistEnd(0.f), - mRadiusOffset(0.f), - mTaper(0.f,0.f), - mRevolutions(1.f), - mSkew(0.f), - mCRC(0) - { - } - - LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew) - : mCurveType(curve), - mBegin(begin), - mEnd(end), - mScale(scx,scy), - mShear(shx,shy), - mTwistBegin(twistbegin), - mTwistEnd(twistend), - mRadiusOffset(radiusoffset), - mTaper(tx,ty), - mRevolutions(revolutions), - mSkew(skew), - mCRC(0) - { - } - - LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew) - { - mCurveType = curve; - mBegin = (F32)(begin * CUT_QUANTA); - mEnd = (F32)(100.f - end) * CUT_QUANTA; - if (mEnd > 1.f) - mEnd = 1.f; - mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA); - mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA); - mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA; - mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA; - mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA; - mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA); - mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f; - mSkew = U8_TO_F32(skew) * SCALE_QUANTA; - - mCRC = 0; - } - - bool operator==(const LLPathParams ¶ms) const; - bool operator!=(const LLPathParams ¶ms) const; - bool operator<(const LLPathParams ¶ms) const; - - void copyParams(const LLPathParams ¶ms); - - BOOL importFile(LLFILE *fp); - BOOL exportFile(LLFILE *fp) const; - - BOOL importLegacyStream(std::istream& input_stream); - BOOL exportLegacyStream(std::ostream& output_stream) const; - - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - const F32& getBegin() const { return mBegin; } - const F32& getEnd() const { return mEnd; } - const LLVector2 &getScale() const { return mScale; } - const F32& getScaleX() const { return mScale.mV[0]; } - const F32& getScaleY() const { return mScale.mV[1]; } - const LLVector2 getBeginScale() const; - const LLVector2 getEndScale() const; - const LLVector2 &getShear() const { return mShear; } - const F32& getShearX() const { return mShear.mV[0]; } - const F32& getShearY() const { return mShear.mV[1]; } - const U8& getCurveType () const { return mCurveType; } - - const F32& getTwistBegin() const { return mTwistBegin; } - const F32& getTwistEnd() const { return mTwistEnd; } - const F32& getTwist() const { return mTwistEnd; } // deprecated - const F32& getRadiusOffset() const { return mRadiusOffset; } - const LLVector2 &getTaper() const { return mTaper; } - const F32& getTaperX() const { return mTaper.mV[0]; } - const F32& getTaperY() const { return mTaper.mV[1]; } - const F32& getRevolutions() const { return mRevolutions; } - const F32& getSkew() const { return mSkew; } - - void setCurveType(const U8 type) { mCurveType = type; } - void setBegin(const F32 begin) { mBegin = begin; } - void setEnd(const F32 end) { mEnd = end; } - - void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); } - void setScaleX(const F32 v) { mScale.mV[VX] = v; } - void setScaleY(const F32 v) { mScale.mV[VY] = v; } - void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); } - void setShearX(const F32 v) { mShear.mV[VX] = v; } - void setShearY(const F32 v) { mShear.mV[VY] = v; } - - void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; } - void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; } - void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated - void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; } - void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); } - void setTaperX(const F32 v) { mTaper.mV[VX] = v; } - void setTaperY(const F32 v) { mTaper.mV[VY] = v; } - void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; } - void setSkew(const F32 skew) { mSkew = skew; } - - friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params); + LLPathParams() + : + mCurveType(LL_PCODE_PATH_LINE), + mBegin(0.f), + mEnd(1.f), + mScale(1.f,1.f), + mShear(0.f,0.f), + mTwistBegin(0.f), + mTwistEnd(0.f), + mRadiusOffset(0.f), + mTaper(0.f,0.f), + mRevolutions(1.f), + mSkew(0.f), + mCRC(0) + { + } + + LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew) + : mCurveType(curve), + mBegin(begin), + mEnd(end), + mScale(scx,scy), + mShear(shx,shy), + mTwistBegin(twistbegin), + mTwistEnd(twistend), + mRadiusOffset(radiusoffset), + mTaper(tx,ty), + mRevolutions(revolutions), + mSkew(skew), + mCRC(0) + { + } + + LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew) + { + mCurveType = curve; + mBegin = (F32)(begin * CUT_QUANTA); + mEnd = (F32)(100.f - end) * CUT_QUANTA; + if (mEnd > 1.f) + mEnd = 1.f; + mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA); + mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA); + mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA; + mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA; + mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA; + mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA); + mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f; + mSkew = U8_TO_F32(skew) * SCALE_QUANTA; + + mCRC = 0; + } + + bool operator==(const LLPathParams ¶ms) const; + bool operator!=(const LLPathParams ¶ms) const; + bool operator<(const LLPathParams ¶ms) const; + + void copyParams(const LLPathParams ¶ms); + + BOOL importFile(LLFILE *fp); + BOOL exportFile(LLFILE *fp) const; + + BOOL importLegacyStream(std::istream& input_stream); + BOOL exportLegacyStream(std::ostream& output_stream) const; + + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + const F32& getBegin() const { return mBegin; } + const F32& getEnd() const { return mEnd; } + const LLVector2 &getScale() const { return mScale; } + const F32& getScaleX() const { return mScale.mV[0]; } + const F32& getScaleY() const { return mScale.mV[1]; } + const LLVector2 getBeginScale() const; + const LLVector2 getEndScale() const; + const LLVector2 &getShear() const { return mShear; } + const F32& getShearX() const { return mShear.mV[0]; } + const F32& getShearY() const { return mShear.mV[1]; } + const U8& getCurveType () const { return mCurveType; } + + const F32& getTwistBegin() const { return mTwistBegin; } + const F32& getTwistEnd() const { return mTwistEnd; } + const F32& getTwist() const { return mTwistEnd; } // deprecated + const F32& getRadiusOffset() const { return mRadiusOffset; } + const LLVector2 &getTaper() const { return mTaper; } + const F32& getTaperX() const { return mTaper.mV[0]; } + const F32& getTaperY() const { return mTaper.mV[1]; } + const F32& getRevolutions() const { return mRevolutions; } + const F32& getSkew() const { return mSkew; } + + void setCurveType(const U8 type) { mCurveType = type; } + void setBegin(const F32 begin) { mBegin = begin; } + void setEnd(const F32 end) { mEnd = end; } + + void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); } + void setScaleX(const F32 v) { mScale.mV[VX] = v; } + void setScaleY(const F32 v) { mScale.mV[VY] = v; } + void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); } + void setShearX(const F32 v) { mShear.mV[VX] = v; } + void setShearY(const F32 v) { mShear.mV[VY] = v; } + + void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; } + void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; } + void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated + void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; } + void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); } + void setTaperX(const F32 v) { mTaper.mV[VX] = v; } + void setTaperY(const F32 v) { mTaper.mV[VY] = v; } + void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; } + void setSkew(const F32 skew) { mSkew = skew; } + + friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params); protected: - // Path params - U8 mCurveType; - F32 mBegin; - F32 mEnd; - LLVector2 mScale; - LLVector2 mShear; - - F32 mTwistBegin; - F32 mTwistEnd; - F32 mRadiusOffset; - LLVector2 mTaper; - F32 mRevolutions; - F32 mSkew; - - U32 mCRC; + // Path params + U8 mCurveType; + F32 mBegin; + F32 mEnd; + LLVector2 mScale; + LLVector2 mShear; + + F32 mTwistBegin; + F32 mTwistEnd; + F32 mRadiusOffset; + LLVector2 mTaper; + F32 mRevolutions; + F32 mSkew; + + U32 mCRC; }; inline bool LLPathParams::operator==(const LLPathParams ¶ms) const { - return - (getCurveType() == params.getCurveType()) && - (getScale() == params.getScale()) && - (getBegin() == params.getBegin()) && - (getEnd() == params.getEnd()) && - (getShear() == params.getShear()) && - (getTwist() == params.getTwist()) && - (getTwistBegin() == params.getTwistBegin()) && - (getRadiusOffset() == params.getRadiusOffset()) && - (getTaper() == params.getTaper()) && - (getRevolutions() == params.getRevolutions()) && - (getSkew() == params.getSkew()); + return + (getCurveType() == params.getCurveType()) && + (getScale() == params.getScale()) && + (getBegin() == params.getBegin()) && + (getEnd() == params.getEnd()) && + (getShear() == params.getShear()) && + (getTwist() == params.getTwist()) && + (getTwistBegin() == params.getTwistBegin()) && + (getRadiusOffset() == params.getRadiusOffset()) && + (getTaper() == params.getTaper()) && + (getRevolutions() == params.getRevolutions()) && + (getSkew() == params.getSkew()); } inline bool LLPathParams::operator!=(const LLPathParams ¶ms) const { - return - (getCurveType() != params.getCurveType()) || - (getScale() != params.getScale()) || - (getBegin() != params.getBegin()) || - (getEnd() != params.getEnd()) || - (getShear() != params.getShear()) || - (getTwist() != params.getTwist()) || - (getTwistBegin() !=params.getTwistBegin()) || - (getRadiusOffset() != params.getRadiusOffset()) || - (getTaper() != params.getTaper()) || - (getRevolutions() != params.getRevolutions()) || - (getSkew() != params.getSkew()); + return + (getCurveType() != params.getCurveType()) || + (getScale() != params.getScale()) || + (getBegin() != params.getBegin()) || + (getEnd() != params.getEnd()) || + (getShear() != params.getShear()) || + (getTwist() != params.getTwist()) || + (getTwistBegin() !=params.getTwistBegin()) || + (getRadiusOffset() != params.getRadiusOffset()) || + (getTaper() != params.getTaper()) || + (getRevolutions() != params.getRevolutions()) || + (getSkew() != params.getSkew()); } inline bool LLPathParams::operator<(const LLPathParams ¶ms) const { - if( getCurveType() != params.getCurveType()) - { - return getCurveType() < params.getCurveType(); - } - else - if( getScale() != params.getScale()) - { - return getScale() < params.getScale(); - } - else - if( getBegin() != params.getBegin()) - { - return getBegin() < params.getBegin(); - } - else - if( getEnd() != params.getEnd()) - { - return getEnd() < params.getEnd(); - } - else - if( getShear() != params.getShear()) - { - return getShear() < params.getShear(); - } - else - if( getTwist() != params.getTwist()) - { - return getTwist() < params.getTwist(); - } - else - if( getTwistBegin() != params.getTwistBegin()) - { - return getTwistBegin() < params.getTwistBegin(); - } - else - if( getRadiusOffset() != params.getRadiusOffset()) - { - return getRadiusOffset() < params.getRadiusOffset(); - } - else - if( getTaper() != params.getTaper()) - { - return getTaper() < params.getTaper(); - } - else - if( getRevolutions() != params.getRevolutions()) - { - return getRevolutions() < params.getRevolutions(); - } - else - { - return getSkew() < params.getSkew(); - } + if( getCurveType() != params.getCurveType()) + { + return getCurveType() < params.getCurveType(); + } + else + if( getScale() != params.getScale()) + { + return getScale() < params.getScale(); + } + else + if( getBegin() != params.getBegin()) + { + return getBegin() < params.getBegin(); + } + else + if( getEnd() != params.getEnd()) + { + return getEnd() < params.getEnd(); + } + else + if( getShear() != params.getShear()) + { + return getShear() < params.getShear(); + } + else + if( getTwist() != params.getTwist()) + { + return getTwist() < params.getTwist(); + } + else + if( getTwistBegin() != params.getTwistBegin()) + { + return getTwistBegin() < params.getTwistBegin(); + } + else + if( getRadiusOffset() != params.getRadiusOffset()) + { + return getRadiusOffset() < params.getRadiusOffset(); + } + else + if( getTaper() != params.getTaper()) + { + return getTaper() < params.getTaper(); + } + else + if( getRevolutions() != params.getRevolutions()) + { + return getRevolutions() < params.getRevolutions(); + } + else + { + return getSkew() < params.getSkew(); + } } typedef LLVolumeParams* LLVolumeParamsPtr; @@ -560,190 +560,190 @@ typedef const LLVolumeParams* const_LLVolumeParamsPtr; class LLVolumeParams { public: - LLVolumeParams() - : mSculptType(LL_SCULPT_TYPE_NONE) - { - } - - LLVolumeParams(LLProfileParams &profile, LLPathParams &path, - LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE) - : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type) - { - } - - bool operator==(const LLVolumeParams ¶ms) const; - bool operator!=(const LLVolumeParams ¶ms) const; - bool operator<(const LLVolumeParams ¶ms) const; - - - void copyParams(const LLVolumeParams ¶ms); - - const LLProfileParams &getProfileParams() const {return mProfileParams;} - LLProfileParams &getProfileParams() {return mProfileParams;} - const LLPathParams &getPathParams() const {return mPathParams;} - LLPathParams &getPathParams() {return mPathParams;} - - BOOL importFile(LLFILE *fp); - BOOL exportFile(LLFILE *fp) const; - - BOOL importLegacyStream(std::istream& input_stream); - BOOL exportLegacyStream(std::ostream& output_stream) const; - - LLSD sculptAsLLSD() const; - bool sculptFromLLSD(LLSD& sd); - - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - bool setType(U8 profile, U8 path); - - //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1 - //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1 - //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin - //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin - - bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end - bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end - - bool setHollow(const F32 hollow); // range 0 to 1 - bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base - bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement, - bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base - bool setShear(const F32 x, const F32 y); // 0 = no movement - - bool setTwistBegin(const F32 twist_begin); // range -1 to 1 - bool setTwistEnd(const F32 twist_end); // range -1 to 1 - bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated - bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; } - bool setTaperX(const F32 v); // -1 to 1 - bool setTaperY(const F32 v); // -1 to 1 - bool setRevolutions(const F32 revolutions); // 1 to 4 - bool setRadiusOffset(const F32 radius_offset); - bool setSkew(const F32 skew); - bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type); - - static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, - U8 path_curve, F32 path_begin, F32 path_end, - F32 scx, F32 scy, F32 shx, F32 shy, - F32 twistend, F32 twistbegin, F32 radiusoffset, - F32 tx, F32 ty, F32 revolutions, F32 skew); - - const F32& getBeginS() const { return mProfileParams.getBegin(); } - const F32& getBeginT() const { return mPathParams.getBegin(); } - const F32& getEndS() const { return mProfileParams.getEnd(); } - const F32& getEndT() const { return mPathParams.getEnd(); } - - const F32& getHollow() const { return mProfileParams.getHollow(); } - const F32& getTwist() const { return mPathParams.getTwist(); } - const F32& getRatio() const { return mPathParams.getScaleX(); } - const F32& getRatioX() const { return mPathParams.getScaleX(); } - const F32& getRatioY() const { return mPathParams.getScaleY(); } - const F32& getShearX() const { return mPathParams.getShearX(); } - const F32& getShearY() const { return mPathParams.getShearY(); } - - const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); } - const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); } - const F32& getTaper() const { return mPathParams.getTaperX(); } - const F32& getTaperX() const { return mPathParams.getTaperX(); } - const F32& getTaperY() const { return mPathParams.getTaperY(); } - const F32& getRevolutions() const { return mPathParams.getRevolutions(); } - const F32& getSkew() const { return mPathParams.getSkew(); } - const LLUUID& getSculptID() const { return mSculptID; } - const U8& getSculptType() const { return mSculptType; } - bool isSculpt() const; - bool isMeshSculpt() const; - BOOL isConvex() const; - - // 'begin' and 'end' should be in range [0, 1] (they will be clamped) - // (begin, end) = (0, 1) will not change the volume - // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T) - void reduceS(F32 begin, F32 end); - void reduceT(F32 begin, F32 end); - - struct compare - { - bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const - { - return (*first < *second); - } - }; - - friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); - - // debug helper functions - void setCube(); + LLVolumeParams() + : mSculptType(LL_SCULPT_TYPE_NONE) + { + } + + LLVolumeParams(LLProfileParams &profile, LLPathParams &path, + LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE) + : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type) + { + } + + bool operator==(const LLVolumeParams ¶ms) const; + bool operator!=(const LLVolumeParams ¶ms) const; + bool operator<(const LLVolumeParams ¶ms) const; + + + void copyParams(const LLVolumeParams ¶ms); + + const LLProfileParams &getProfileParams() const {return mProfileParams;} + LLProfileParams &getProfileParams() {return mProfileParams;} + const LLPathParams &getPathParams() const {return mPathParams;} + LLPathParams &getPathParams() {return mPathParams;} + + BOOL importFile(LLFILE *fp); + BOOL exportFile(LLFILE *fp) const; + + BOOL importLegacyStream(std::istream& input_stream); + BOOL exportLegacyStream(std::ostream& output_stream) const; + + LLSD sculptAsLLSD() const; + bool sculptFromLLSD(LLSD& sd); + + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + bool setType(U8 profile, U8 path); + + //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1 + //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1 + //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin + //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin + + bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end + bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end + + bool setHollow(const F32 hollow); // range 0 to 1 + bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base + bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement, + bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base + bool setShear(const F32 x, const F32 y); // 0 = no movement + + bool setTwistBegin(const F32 twist_begin); // range -1 to 1 + bool setTwistEnd(const F32 twist_end); // range -1 to 1 + bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated + bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; } + bool setTaperX(const F32 v); // -1 to 1 + bool setTaperY(const F32 v); // -1 to 1 + bool setRevolutions(const F32 revolutions); // 1 to 4 + bool setRadiusOffset(const F32 radius_offset); + bool setSkew(const F32 skew); + bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type); + + static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, + U8 path_curve, F32 path_begin, F32 path_end, + F32 scx, F32 scy, F32 shx, F32 shy, + F32 twistend, F32 twistbegin, F32 radiusoffset, + F32 tx, F32 ty, F32 revolutions, F32 skew); + + const F32& getBeginS() const { return mProfileParams.getBegin(); } + const F32& getBeginT() const { return mPathParams.getBegin(); } + const F32& getEndS() const { return mProfileParams.getEnd(); } + const F32& getEndT() const { return mPathParams.getEnd(); } + + const F32& getHollow() const { return mProfileParams.getHollow(); } + const F32& getTwist() const { return mPathParams.getTwist(); } + const F32& getRatio() const { return mPathParams.getScaleX(); } + const F32& getRatioX() const { return mPathParams.getScaleX(); } + const F32& getRatioY() const { return mPathParams.getScaleY(); } + const F32& getShearX() const { return mPathParams.getShearX(); } + const F32& getShearY() const { return mPathParams.getShearY(); } + + const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); } + const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); } + const F32& getTaper() const { return mPathParams.getTaperX(); } + const F32& getTaperX() const { return mPathParams.getTaperX(); } + const F32& getTaperY() const { return mPathParams.getTaperY(); } + const F32& getRevolutions() const { return mPathParams.getRevolutions(); } + const F32& getSkew() const { return mPathParams.getSkew(); } + const LLUUID& getSculptID() const { return mSculptID; } + const U8& getSculptType() const { return mSculptType; } + bool isSculpt() const; + bool isMeshSculpt() const; + BOOL isConvex() const; + + // 'begin' and 'end' should be in range [0, 1] (they will be clamped) + // (begin, end) = (0, 1) will not change the volume + // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T) + void reduceS(F32 begin, F32 end); + void reduceT(F32 begin, F32 end); + + struct compare + { + bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const + { + return (*first < *second); + } + }; + + friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); + + // debug helper functions + void setCube(); protected: - LLProfileParams mProfileParams; - LLPathParams mPathParams; - LLUUID mSculptID; - U8 mSculptType; + LLProfileParams mProfileParams; + LLPathParams mPathParams; + LLUUID mSculptID; + U8 mSculptType; }; class LLProfile { - friend class LLVolume; + friend class LLVolume; public: - LLProfile() - : mOpen(FALSE), - mConcave(FALSE), - mDirty(TRUE), - mTotalOut(0), - mTotal(2) - { - } - - S32 getTotal() const { return mTotal; } - S32 getTotalOut() const { return mTotalOut; } // Total number of outside points - BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); } - BOOL isOpen() const { return mOpen; } - void setDirty() { mDirty = TRUE; } - - static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, - BOOL is_sculpted = FALSE, S32 sculpt_size = 0); - BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, - BOOL is_sculpted = FALSE, S32 sculpt_size = 0); - BOOL isConcave() const { return mConcave; } + LLProfile() + : mOpen(FALSE), + mConcave(FALSE), + mDirty(TRUE), + mTotalOut(0), + mTotal(2) + { + } + + S32 getTotal() const { return mTotal; } + S32 getTotalOut() const { return mTotalOut; } // Total number of outside points + BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); } + BOOL isOpen() const { return mOpen; } + void setDirty() { mDirty = TRUE; } + + static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); + BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); + BOOL isConcave() const { return mConcave; } public: - struct Face - { - S32 mIndex; - S32 mCount; - F32 mScaleU; - BOOL mCap; - BOOL mFlat; - LLFaceID mFaceID; - }; - - LLAlignedArray mProfile; - //LLAlignedArray mNormals; - std::vector mFaces; - - //LLAlignedArray mEdgeNormals; - //LLAlignedArray mEdgeCenters; - - friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile); + struct Face + { + S32 mIndex; + S32 mCount; + F32 mScaleU; + BOOL mCap; + BOOL mFlat; + LLFaceID mFaceID; + }; + + LLAlignedArray mProfile; + //LLAlignedArray mNormals; + std::vector mFaces; + + //LLAlignedArray mEdgeNormals; + //LLAlignedArray mEdgeCenters; + + friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile); protected: - ~LLProfile(); + ~LLProfile(); - static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); - void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); + static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); + void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); - Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); - Face* addCap (S16 faceID); - Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat); + Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); + Face* addCap (S16 faceID); + Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat); protected: - BOOL mOpen; - BOOL mConcave; - BOOL mDirty; + BOOL mOpen; + BOOL mConcave; + BOOL mDirty; - S32 mTotalOut; - S32 mTotal; + S32 mTotalOut; + S32 mTotal; }; //------------------------------------------------------------------- @@ -753,220 +753,220 @@ protected: class LLPath { public: - class PathPt - { - public: - LLMatrix4a mRot; - LLVector4a mPos; - - LLVector4a mScale; - F32 mTexT; - F32 pad[3]; //for alignment - PathPt() - { - mPos.clear(); - mTexT = 0; - mScale.clear(); - mRot.setRows(LLVector4a(1,0,0,0), - LLVector4a(0,1,0,0), - LLVector4a(0,0,1,0)); - - //distinguished data in the pad for debugging - pad[0] = 3.14159f; - pad[1] = -3.14159f; - pad[2] = 0.585f; - } - }; + class PathPt + { + public: + LLMatrix4a mRot; + LLVector4a mPos; + + LLVector4a mScale; + F32 mTexT; + F32 pad[3]; //for alignment + PathPt() + { + mPos.clear(); + mTexT = 0; + mScale.clear(); + mRot.setRows(LLVector4a(1,0,0,0), + LLVector4a(0,1,0,0), + LLVector4a(0,0,1,0)); + + //distinguished data in the pad for debugging + pad[0] = 3.14159f; + pad[1] = -3.14159f; + pad[2] = 0.585f; + } + }; public: - LLPath() - : mOpen(FALSE), - mTotal(0), - mDirty(TRUE), - mStep(1) - { - } + LLPath() + : mOpen(FALSE), + mTotal(0), + mDirty(TRUE), + mStep(1) + { + } - virtual ~LLPath(); + virtual ~LLPath(); - static S32 getNumPoints(const LLPathParams& params, F32 detail); - static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); + static S32 getNumPoints(const LLPathParams& params, F32 detail); + static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); - void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); - virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, - BOOL is_sculpted = FALSE, S32 sculpt_size = 0); + void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); + virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); - BOOL isOpen() const { return mOpen; } - F32 getStep() const { return mStep; } - void setDirty() { mDirty = TRUE; } + BOOL isOpen() const { return mOpen; } + F32 getStep() const { return mStep; } + void setDirty() { mDirty = TRUE; } - S32 getPathLength() const { return (S32)mPath.size(); } + S32 getPathLength() const { return (S32)mPath.size(); } - void resizePath(S32 length) { mPath.resize(length); } + void resizePath(S32 length) { mPath.resize(length); } - friend std::ostream& operator<<(std::ostream &s, const LLPath &path); + friend std::ostream& operator<<(std::ostream &s, const LLPath &path); public: - LLAlignedArray mPath; + LLAlignedArray mPath; protected: - BOOL mOpen; - S32 mTotal; - BOOL mDirty; - F32 mStep; + BOOL mOpen; + S32 mTotal; + BOOL mDirty; + F32 mStep; }; class LLDynamicPath : public LLPath { public: - LLDynamicPath() : LLPath() { } - /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, - BOOL is_sculpted = FALSE, S32 sculpt_size = 0); + LLDynamicPath() : LLPath() { } + /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); }; // Yet another "face" class - caches volume-specific, but not instance-specific data for faces) class LLVolumeFace { public: - class VertexData - { - enum - { - POSITION = 0, - NORMAL = 1 - }; - - private: - void init(); - public: - VertexData(); - VertexData(const VertexData& rhs); - const VertexData& operator=(const VertexData& rhs); - - ~VertexData(); - LLVector4a& getPosition(); - LLVector4a& getNormal(); - const LLVector4a& getPosition() const; - const LLVector4a& getNormal() const; - void setPosition(const LLVector4a& pos); - void setNormal(const LLVector4a& norm); - - - LLVector2 mTexCoord; - - bool operator<(const VertexData& rhs) const; - bool operator==(const VertexData& rhs) const; - bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; - - private: - LLVector4a* mData; - }; - - LLVolumeFace(); - LLVolumeFace(const LLVolumeFace& src); - LLVolumeFace& operator=(const LLVolumeFace& rhs); - - ~LLVolumeFace(); + class VertexData + { + enum + { + POSITION = 0, + NORMAL = 1 + }; + + private: + void init(); + public: + VertexData(); + VertexData(const VertexData& rhs); + const VertexData& operator=(const VertexData& rhs); + + ~VertexData(); + LLVector4a& getPosition(); + LLVector4a& getNormal(); + const LLVector4a& getPosition() const; + const LLVector4a& getNormal() const; + void setPosition(const LLVector4a& pos); + void setNormal(const LLVector4a& norm); + + + LLVector2 mTexCoord; + + bool operator<(const VertexData& rhs) const; + bool operator==(const VertexData& rhs) const; + bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; + + private: + LLVector4a* mData; + }; + + LLVolumeFace(); + LLVolumeFace(const LLVolumeFace& src); + LLVolumeFace& operator=(const LLVolumeFace& rhs); + + ~LLVolumeFace(); private: - void freeData(); + void freeData(); public: - BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createTangents(); - - void resizeVertices(S32 num_verts); - void allocateTangents(S32 num_verts); - void allocateWeights(S32 num_verts); + BOOL create(LLVolume* volume, BOOL partial_build = FALSE); + void createTangents(); + + void resizeVertices(S32 num_verts); + void allocateTangents(S32 num_verts); + void allocateWeights(S32 num_verts); void allocateJointIndices(S32 num_verts); - void resizeIndices(S32 num_indices); - void fillFromLegacyData(std::vector& v, std::vector& idx); + void resizeIndices(S32 num_indices); + void fillFromLegacyData(std::vector& v, std::vector& idx); - void pushVertex(const VertexData& cv); - void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc); - void pushIndex(const U16& idx); + void pushVertex(const VertexData& cv); + void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc); + void pushIndex(const U16& idx); - void swapData(LLVolumeFace& rhs); + void swapData(LLVolumeFace& rhs); - void getVertexData(U16 indx, LLVolumeFace::VertexData& cv); + void getVertexData(U16 indx, LLVolumeFace::VertexData& cv); - class VertexMapData : public LLVolumeFace::VertexData - { - public: - U16 mIndex; + class VertexMapData : public LLVolumeFace::VertexData + { + public: + U16 mIndex; - bool operator==(const LLVolumeFace::VertexData& rhs) const; + bool operator==(const LLVolumeFace::VertexData& rhs) const; - struct ComparePosition - { - bool operator()(const LLVector3& a, const LLVector3& b) const; - }; + struct ComparePosition + { + bool operator()(const LLVector3& a, const LLVector3& b) const; + }; - typedef std::map, VertexMapData::ComparePosition > PointMap; - }; + typedef std::map, VertexMapData::ComparePosition > PointMap; + }; // Eliminates non unique triangles, takes positions, // normals and texture coordinates into account. void remap(); - void optimize(F32 angle_cutoff = 2.f); - bool cacheOptimize(bool gen_tangents = false); + void optimize(F32 angle_cutoff = 2.f); + bool cacheOptimize(bool gen_tangents = false); - void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); + void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); void destroyOctree(); // Get a reference to the octree, which may be null const LLVolumeOctree* getOctree() const; - enum - { - SINGLE_MASK = 0x0001, - CAP_MASK = 0x0002, - END_MASK = 0x0004, - SIDE_MASK = 0x0008, - INNER_MASK = 0x0010, - OUTER_MASK = 0x0020, - HOLLOW_MASK = 0x0040, - OPEN_MASK = 0x0080, - FLAT_MASK = 0x0100, - TOP_MASK = 0x0200, - BOTTOM_MASK = 0x0400 - }; - + enum + { + SINGLE_MASK = 0x0001, + CAP_MASK = 0x0002, + END_MASK = 0x0004, + SIDE_MASK = 0x0008, + INNER_MASK = 0x0010, + OUTER_MASK = 0x0020, + HOLLOW_MASK = 0x0040, + OPEN_MASK = 0x0080, + FLAT_MASK = 0x0100, + TOP_MASK = 0x0200, + BOTTOM_MASK = 0x0400 + }; + public: - S32 mID; - U32 mTypeMask; - - // Only used for INNER/OUTER faces - S32 mBeginS; - S32 mBeginT; - S32 mNumS; - S32 mNumT; - - LLVector4a* mExtents; //minimum and maximum point of face - LLVector4a* mCenter; - LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. - - S32 mNumVertices; // num vertices == num normals == num texcoords - S32 mNumAllocatedVertices; - S32 mNumIndices; - - LLVector4a* mPositions; // Contains vertices, nortmals and texcoords - LLVector4a* mNormals; // pointer into mPositions - LLVector4a* mTangents; - LLVector2* mTexCoords; // pointer into mPositions - - // mIndices contains mNumIndices amount of elements. - // It contains triangles, each 3 indices describe one triangle. + S32 mID; + U32 mTypeMask; + + // Only used for INNER/OUTER faces + S32 mBeginS; + S32 mBeginT; + S32 mNumS; + S32 mNumT; + + LLVector4a* mExtents; //minimum and maximum point of face + LLVector4a* mCenter; + LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. + + S32 mNumVertices; // num vertices == num normals == num texcoords + S32 mNumAllocatedVertices; + S32 mNumIndices; + + LLVector4a* mPositions; // Contains vertices, nortmals and texcoords + LLVector4a* mNormals; // pointer into mPositions + LLVector4a* mTangents; + LLVector2* mTexCoords; // pointer into mPositions + + // mIndices contains mNumIndices amount of elements. + // It contains triangles, each 3 indices describe one triangle. // If mIndices contains {0, 2, 3, 1, 2, 4}, it means there // are two triangles {0, 2, 3} and {1, 2, 4} with values being // indexes for mPositions/mNormals/mTexCoords - U16* mIndices; + U16* mIndices; - std::vector mEdge; + std::vector mEdge; - //list of skin weights for rigged volumes - // format is mWeights[vertex_index].mV[influence] = . - // mWeights.size() should be empty or match mVertices.size() - LLVector4a* mWeights; + //list of skin weights for rigged volumes + // format is mWeights[vertex_index].mV[influence] = . + // mWeights.size() should be empty or match mVertices.size() + LLVector4a* mWeights; #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS LLVector4a* mJustWeights; @@ -979,8 +979,8 @@ public: // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - //whether or not face has been cache optimized - BOOL mOptimized; + //whether or not face has been cache optimized + BOOL mOptimized; // if this is a mesh asset, scale and translation that were applied // when encoding the source mesh into a unit cube @@ -991,154 +991,154 @@ private: LLVolumeOctree* mOctree; LLVolumeTriangle* mOctreeTriangles; - BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); - BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); - BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); + BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); + BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); + BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); }; class LLVolume : public LLRefCount { - friend class LLVolumeLODGroup; + friend class LLVolumeLODGroup; protected: - virtual ~LLVolume(); // use unref + virtual ~LLVolume(); // use unref public: - typedef std::vector face_list_t; - - struct FaceParams - { - LLFaceID mFaceID; - S32 mBeginS; - S32 mCountS; - S32 mBeginT; - S32 mCountT; - }; - - LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE); - - U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); } - U8 getPathType() const { return mParams.getPathParams().getCurveType(); } - S32 getNumFaces() const; - S32 getNumVolumeFaces() const { return mVolumeFaces.size(); } - F32 getDetail() const { return mDetail; } - F32 getSurfaceArea() const { return mSurfaceArea; } - const LLVolumeParams& getParams() const { return mParams; } - LLVolumeParams getCopyOfParams() const { return mParams; } - const LLProfile& getProfile() const { return *mProfilep; } - LLPath& getPath() const { return *mPathp; } - void resizePath(S32 length); - const LLAlignedArray& getMesh() const { return mMesh; } - const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; } - - - void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } - - void regen(); + typedef std::vector face_list_t; + + struct FaceParams + { + LLFaceID mFaceID; + S32 mBeginS; + S32 mCountS; + S32 mBeginT; + S32 mCountT; + }; + + LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE); + + U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); } + U8 getPathType() const { return mParams.getPathParams().getCurveType(); } + S32 getNumFaces() const; + S32 getNumVolumeFaces() const { return mVolumeFaces.size(); } + F32 getDetail() const { return mDetail; } + F32 getSurfaceArea() const { return mSurfaceArea; } + const LLVolumeParams& getParams() const { return mParams; } + LLVolumeParams getCopyOfParams() const { return mParams; } + const LLProfile& getProfile() const { return *mProfilep; } + LLPath& getPath() const { return *mPathp; } + void resizePath(S32 length); + const LLAlignedArray& getMesh() const { return mMesh; } + const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; } + + + void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } + + void regen(); void genTangents(S32 face); - BOOL isConvex() const; - BOOL isCap(S32 face); - BOOL isFlat(S32 face); - BOOL isUnique() const { return mUnique; } - - S32 getSculptLevel() const { return mSculptLevel; } - void setSculptLevel(S32 level) { mSculptLevel = level; } - - - static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); - - S32 getNumTriangles(S32* vcount = NULL) const; - - void generateSilhouetteVertices(std::vector &vertices, - std::vector &normals, - const LLVector3& view_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat, - S32 face_index); - - //get the face index of the face that intersects with the given line segment at the point - //closest to start. Moves end to the point of intersection. Returns -1 if no intersection. - //Line segment must be in volume space. - S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face = -1, // which face to check, -1 = ALL_SIDES - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ); - - LLFaceID generateFaceMask(); - - BOOL isFaceMaskValid(LLFaceID face_mask); - static S32 sNumMeshPoints; - - friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume); - friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over - // conversion if *(LLVolume*) to LLVolume& - const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE - - LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE - - face_list_t& getVolumeFaces() { return mVolumeFaces; } - - U32 mFaceMask; // bit array of which faces exist in this volume - LLVector3 mLODScaleBias; // vector for biasing LOD based on scale - - void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder); - void copyVolumeFaces(const LLVolume* volume); - void copyFacesTo(std::vector &faces) const; - void copyFacesFrom(const std::vector &faces); + BOOL isConvex() const; + BOOL isCap(S32 face); + BOOL isFlat(S32 face); + BOOL isUnique() const { return mUnique; } + + S32 getSculptLevel() const { return mSculptLevel; } + void setSculptLevel(S32 level) { mSculptLevel = level; } + + + static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); + + S32 getNumTriangles(S32* vcount = NULL) const; + + void generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat, + S32 face_index); + + //get the face index of the face that intersects with the given line segment at the point + //closest to start. Moves end to the point of intersection. Returns -1 if no intersection. + //Line segment must be in volume space. + S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ); + + LLFaceID generateFaceMask(); + + BOOL isFaceMaskValid(LLFaceID face_mask); + static S32 sNumMeshPoints; + + friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume); + friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over + // conversion if *(LLVolume*) to LLVolume& + const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE + + LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE + + face_list_t& getVolumeFaces() { return mVolumeFaces; } + + U32 mFaceMask; // bit array of which faces exist in this volume + LLVector3 mLODScaleBias; // vector for biasing LOD based on scale + + void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder); + void copyVolumeFaces(const LLVolume* volume); + void copyFacesTo(std::vector &faces) const; + void copyFacesFrom(const std::vector &faces); // use meshoptimizer to optimize index buffer for vertex shader cache // gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer - bool cacheOptimize(bool gen_tangents = false); + bool cacheOptimize(bool gen_tangents = false); private: - void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); - F32 sculptGetSurfaceArea(); - void sculptGenerateEmptyPlaceholder(); - void sculptGenerateSpherePlaceholder(); - void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); + void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); + F32 sculptGetSurfaceArea(); + void sculptGenerateEmptyPlaceholder(); + void sculptGenerateSpherePlaceholder(); + void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); + - protected: - BOOL generate(); - void createVolumeFaces(); + BOOL generate(); + void createVolumeFaces(); public: - bool unpackVolumeFaces(std::istream& is, S32 size); - bool unpackVolumeFaces(U8* in_data, S32 size); + bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(U8* in_data, S32 size); private: - bool unpackVolumeFacesInternal(const LLSD& mdl); + bool unpackVolumeFacesInternal(const LLSD& mdl); public: - virtual void setMeshAssetLoaded(bool loaded); - virtual bool isMeshAssetLoaded(); + virtual void setMeshAssetLoaded(bool loaded); + virtual bool isMeshAssetLoaded(); virtual void setMeshAssetUnavaliable(bool unavaliable); virtual bool isMeshAssetUnavaliable(); protected: - BOOL mUnique; - F32 mDetail; - S32 mSculptLevel; - F32 mSurfaceArea; //unscaled surface area - bool mIsMeshAssetLoaded; + BOOL mUnique; + F32 mDetail; + S32 mSculptLevel; + F32 mSurfaceArea; //unscaled surface area + bool mIsMeshAssetLoaded; bool mIsMeshAssetUnavaliable; - - const LLVolumeParams mParams; - LLPath *mPathp; - LLProfile *mProfilep; - LLAlignedArray mMesh; - - - BOOL mGenerateSingleFace; - face_list_t mVolumeFaces; + + const LLVolumeParams mParams; + LLPath *mPathp; + LLProfile *mProfilep; + LLAlignedArray mMesh; + + + BOOL mGenerateSingleFace; + face_list_t mVolumeFaces; public: - LLVector4a* mHullPoints; - U16* mHullIndices; - S32 mNumHullPoints; - S32 mNumHullIndices; + LLVector4a* mHullPoints; + U16* mHullIndices; + S32 mNumHullPoints; + S32 mNumHullIndices; }; std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); @@ -1150,13 +1150,13 @@ BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, con BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); //BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, -// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); +// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t); + F32& intersection_a, F32& intersection_b, F32& intersection_t); BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t); - - + F32& intersection_a, F32& intersection_b, F32& intersection_t); + + #endif diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 95c7cb0b5c..341b9a6465 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvolumeoctree.cpp * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,190 +29,190 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size) { - LLVector4a fAWdU; - LLVector4a dir; - LLVector4a diff; + LLVector4a fAWdU; + LLVector4a dir; + LLVector4a diff; + + dir.setSub(end, start); + dir.mul(0.5f); + + diff.setAdd(end,start); + diff.mul(0.5f); + diff.sub(center); + fAWdU.setAbs(dir); - dir.setSub(end, start); - dir.mul(0.5f); + LLVector4a rhs; + rhs.setAdd(size, fAWdU); - diff.setAdd(end,start); - diff.mul(0.5f); - diff.sub(center); - fAWdU.setAbs(dir); + LLVector4a lhs; + lhs.setAbs(diff); - LLVector4a rhs; - rhs.setAdd(size, fAWdU); + U32 grt = lhs.greaterThan(rhs).getGatheredBits(); - LLVector4a lhs; - lhs.setAbs(diff); + if (grt & 0x7) + { + return false; + } - U32 grt = lhs.greaterThan(rhs).getGatheredBits(); + LLVector4a f; + f.setCross3(dir, diff); + f.setAbs(f); - if (grt & 0x7) - { - return false; - } - - LLVector4a f; - f.setCross3(dir, diff); - f.setAbs(f); + LLVector4a v0, v1; - LLVector4a v0, v1; + v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1)); + v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2)); + lhs.setMul(v0, v1); - v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1)); - v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2)); - lhs.setMul(v0, v1); + v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2)); + v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1)); + rhs.setMul(v0, v1); + rhs.add(lhs); - v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2)); - v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1)); - rhs.setMul(v0, v1); - rhs.add(lhs); - - grt = f.greaterThan(rhs).getGatheredBits(); + grt = f.greaterThan(rhs).getGatheredBits(); - return (grt & 0x7) ? false : true; + return (grt & 0x7) ? false : true; } LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) { - node->addListener(this); + node->addListener(this); } LLVolumeOctreeListener::~LLVolumeOctreeListener() { } - -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, + +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, LLOctreeNode* child) { - new LLVolumeOctreeListener(child); + new LLVolumeOctreeListener(child); } -LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, +LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, LLVolumeFace* face, F32* closest_t, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) : mStart(start), - mDir(dir), - mIntersection(intersection), - mTexCoord(tex_coord), - mNormal(normal), - mTangent(tangent), + mDir(dir), + mIntersection(intersection), + mTexCoord(tex_coord), + mNormal(normal), + mTangent(tangent), mFace(face), - mClosestT(closest_t), - mHitFace(false) + mClosestT(closest_t), + mHitFace(false) { - mEnd.setAdd(mStart, mDir); + mEnd.setAdd(mStart, mDir); } void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) { - LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); - - if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) - { - node->accept(this); - for (S32 i = 0; i < node->getChildCount(); ++i) - { - traverse(node->getChild(i)); - } - } + LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); + + if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) + { + node->accept(this); + for (S32 i = 0; i < node->getChildCount(); ++i) + { + traverse(node->getChild(i)); + } + } } void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) { for (typename LLOctreeNode::const_element_iter iter = - node->getDataBegin(); iter != node->getDataEnd(); ++iter) - { - const LLVolumeTriangle* tri = *iter; - - F32 a, b, t; - - if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], - mStart, mDir, a, b, t)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < *mClosestT)) // and this hit is closer - { - *mClosestT = t; - mHitFace = true; + node->getDataBegin(); iter != node->getDataEnd(); ++iter) + { + const LLVolumeTriangle* tri = *iter; + + F32 a, b, t; + + if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], + mStart, mDir, a, b, t)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < *mClosestT)) // and this hit is closer + { + *mClosestT = t; + mHitFace = true; mHitTriangle = tri; - if (mIntersection != NULL) - { - LLVector4a intersect = mDir; - intersect.mul(*mClosestT); - intersect.add(mStart); - *mIntersection = intersect; - } - - U32 idx0 = tri->mIndex[0]; - U32 idx1 = tri->mIndex[1]; - U32 idx2 = tri->mIndex[2]; - - if (mTexCoord != NULL) - { - LLVector2* tc = (LLVector2*) mFace->mTexCoords; - *mTexCoord = ((1.f - a - b) * tc[idx0] + - a * tc[idx1] + - b * tc[idx2]); - - } - - if (mNormal != NULL) - { - LLVector4a* norm = mFace->mNormals; - - LLVector4a n1,n2,n3; - n1 = norm[idx0]; - n1.mul(1.f-a-b); - - n2 = norm[idx1]; - n2.mul(a); - - n3 = norm[idx2]; - n3.mul(b); - - n1.add(n2); - n1.add(n3); - - *mNormal = n1; - } - - if (mTangent != NULL) - { - LLVector4a* tangents = mFace->mTangents; - - LLVector4a t1,t2,t3; - t1 = tangents[idx0]; - t1.mul(1.f-a-b); - - t2 = tangents[idx1]; - t2.mul(a); - - t3 = tangents[idx2]; - t3.mul(b); - - t1.add(t2); - t1.add(t3); - - *mTangent = t1; - } - } - } - } + if (mIntersection != NULL) + { + LLVector4a intersect = mDir; + intersect.mul(*mClosestT); + intersect.add(mStart); + *mIntersection = intersect; + } + + U32 idx0 = tri->mIndex[0]; + U32 idx1 = tri->mIndex[1]; + U32 idx2 = tri->mIndex[2]; + + if (mTexCoord != NULL) + { + LLVector2* tc = (LLVector2*) mFace->mTexCoords; + *mTexCoord = ((1.f - a - b) * tc[idx0] + + a * tc[idx1] + + b * tc[idx2]); + + } + + if (mNormal != NULL) + { + LLVector4a* norm = mFace->mNormals; + + LLVector4a n1,n2,n3; + n1 = norm[idx0]; + n1.mul(1.f-a-b); + + n2 = norm[idx1]; + n2.mul(a); + + n3 = norm[idx2]; + n3.mul(b); + + n1.add(n2); + n1.add(n3); + + *mNormal = n1; + } + + if (mTangent != NULL) + { + LLVector4a* tangents = mFace->mTangents; + + LLVector4a t1,t2,t3; + t1 = tangents[idx0]; + t1.mul(1.f-a-b); + + t2 = tangents[idx1]; + t2.mul(a); + + t3 = tangents[idx2]; + t3.mul(b); + + t1.add(t2); + t1.add(t3); + + *mTangent = t1; + } + } + } + } } const LLVector4a& LLVolumeTriangle::getPositionGroup() const { - return mPositionGroup; + return mPositionGroup; } const F32& LLVolumeTriangle::getBinRadius() const { - return mRadius; + return mRadius; } @@ -220,55 +220,55 @@ const F32& LLVolumeTriangle::getBinRadius() const void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) { - LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); + LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); - //make sure bounds matches extents - LLVector4a& min = node->mExtents[0]; - LLVector4a& max = node->mExtents[1]; + //make sure bounds matches extents + LLVector4a& min = node->mExtents[0]; + LLVector4a& max = node->mExtents[1]; - LLVector4a& center = node->mBounds[0]; - LLVector4a& size = node->mBounds[1]; + LLVector4a& center = node->mBounds[0]; + LLVector4a& size = node->mBounds[1]; - LLVector4a test_min, test_max; - test_min.setSub(center, size); - test_max.setAdd(center, size); + LLVector4a test_min, test_max; + test_min.setSub(center, size); + test_max.setAdd(center, size); - if (!test_min.equals3(min, 0.001f) || - !test_max.equals3(max, 0.001f)) - { - LL_ERRS() << "Bad bounding box data found." << LL_ENDL; - } + if (!test_min.equals3(min, 0.001f) || + !test_max.equals3(max, 0.001f)) + { + LL_ERRS() << "Bad bounding box data found." << LL_ENDL; + } - test_min.sub(LLVector4a(0.001f)); - test_max.add(LLVector4a(0.001f)); + test_min.sub(LLVector4a(0.001f)); + test_max.add(LLVector4a(0.001f)); - for (U32 i = 0; i < branch->getChildCount(); ++i) - { - LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); + for (U32 i = 0; i < branch->getChildCount(); ++i) + { + LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); - //make sure all children fit inside this node - if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) || - child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ)) - { - LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL; - } - } + //make sure all children fit inside this node + if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) || + child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ)) + { + LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL; + } + } - //children fit, check data + //children fit, check data for (typename LLOctreeNode::const_element_iter iter = branch->getDataBegin(); - iter != branch->getDataEnd(); ++iter) - { - const LLVolumeTriangle* tri = *iter; - - //validate triangle - for (U32 i = 0; i < 3; i++) - { - if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) || - tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ)) - { - LL_ERRS() << "Triangle protrudes from node." << LL_ENDL; - } - } - } + iter != branch->getDataEnd(); ++iter) + { + const LLVolumeTriangle* tri = *iter; + + //validate triangle + for (U32 i = 0; i < 3; i++) + { + if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) || + tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ)) + { + LL_ERRS() << "Triangle protrudes from node." << LL_ENDL; + } + } + } } diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 0bbb793896..cf176b5afe 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -1,25 +1,25 @@ -/** +/** * @file llvolumeoctree.h * @brief LLVolume octree classes. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,41 +38,41 @@ class alignas(16) LLVolumeTriangle : public LLRefCount { LL_ALIGN_NEW public: - LLVolumeTriangle() - { - mBinIndex = -1; - } + LLVolumeTriangle() + { + mBinIndex = -1; + } - LLVolumeTriangle(const LLVolumeTriangle& rhs) - { - *this = rhs; - } + LLVolumeTriangle(const LLVolumeTriangle& rhs) + { + *this = rhs; + } - const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs) - { - LL_ERRS() << "Illegal operation!" << LL_ENDL; - return *this; - } + const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } - ~LLVolumeTriangle() - { - - } + ~LLVolumeTriangle() + { - LL_ALIGN_16(LLVector4a mPositionGroup); + } - const LLVector4a* mV[3]; - U32 mIndex[3]; + LL_ALIGN_16(LLVector4a mPositionGroup); - F32 mRadius; - mutable S32 mBinIndex; + const LLVector4a* mV[3]; + U32 mIndex[3]; + F32 mRadius; + mutable S32 mBinIndex; - virtual const LLVector4a& getPositionGroup() const; - virtual const F32& getBinRadius() const; - - S32 getBinIndex() const { return mBinIndex; } - void setBinIndex(S32 idx) const { mBinIndex = idx; } + + virtual const LLVector4a& getPositionGroup() const; + virtual const F32& getBinRadius() const; + + S32 getBinIndex() const { return mBinIndex; } + void setBinIndex(S32 idx) const { mBinIndex = idx; } }; @@ -82,52 +82,52 @@ class alignas(16) LLVolumeOctreeListener : public LLOctreeListener* node); - ~LLVolumeOctreeListener(); - - LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) - { - *this = rhs; - } - - const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs) - { - LL_ERRS() << "Illegal operation!" << LL_ENDL; - return *this; - } - - //LISTENER FUNCTIONS + ~LLVolumeOctreeListener(); + + LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) + { + *this = rhs; + } + + const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } + + //LISTENER FUNCTIONS virtual void handleChildAddition(const LLOctreeNode* parent, LLOctreeNode* child); - virtual void handleStateChange(const LLTreeNode* node) { } + virtual void handleStateChange(const LLTreeNode* node) { } virtual void handleChildRemoval(const LLOctreeNode* parent, const LLOctreeNode* child) { } - virtual void handleInsertion(const LLTreeNode* node, LLVolumeTriangle* tri) { } - virtual void handleRemoval(const LLTreeNode* node, LLVolumeTriangle* tri) { } - virtual void handleDestruction(const LLTreeNode* node) { } - + virtual void handleInsertion(const LLTreeNode* node, LLVolumeTriangle* tri) { } + virtual void handleRemoval(const LLTreeNode* node, LLVolumeTriangle* tri) { } + virtual void handleDestruction(const LLTreeNode* node) { } + public: - LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) - LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; class LLOctreeTriangleRayIntersect : public LLOctreeTraveler { public: - LLVector4a mStart; - LLVector4a mDir; - LLVector4a mEnd; - LLVector4a* mIntersection; - LLVector2* mTexCoord; - LLVector4a* mNormal; - LLVector4a* mTangent; - F32* mClosestT; + LLVector4a mStart; + LLVector4a mDir; + LLVector4a mEnd; + LLVector4a* mIntersection; + LLVector2* mTexCoord; + LLVector4a* mNormal; + LLVector4a* mTangent; + F32* mClosestT; LLVolumeFace* mFace; - bool mHitFace; + bool mHitFace; const LLVolumeTriangle* mHitTriangle = nullptr; - LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, + LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, LLVolumeFace* face, - F32* closest_t, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); + F32* closest_t, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); void traverse(const LLOctreeNode* node); @@ -217,7 +217,7 @@ public: { new LLVolumeOctreeListener(this); } - + LLVolumeOctree() : LLOctreeRoot(LLVector4a::getZero(), LLVector4a(1.f,1.f,1.f), nullptr), LLRefCount() diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index f5966b71de..6537733ddf 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpluginprocessparent.cpp * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. * @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ * @endcond @@ -37,10 +37,10 @@ #include "llapr.h" -//virtual +//virtual LLPluginProcessParentOwner::~LLPluginProcessParentOwner() { - + } bool LLPluginProcessParent::sUseReadThread = false; @@ -54,29 +54,29 @@ LLThread *LLPluginProcessParent::sReadThread = NULL; class LLPluginProcessParentPollThread: public LLThread { public: - LLPluginProcessParentPollThread() : - LLThread("LLPluginProcessParentPollThread", gAPRPoolp) - { - } + LLPluginProcessParentPollThread() : + LLThread("LLPluginProcessParentPollThread", gAPRPoolp) + { + } protected: - // Inherited from LLThread - /*virtual*/ void run(void) - { - while(!isQuitting() && LLPluginProcessParent::getUseReadThread()) - { - LLPluginProcessParent::poll(0.1f); - checkPause(); - } - - // Final poll to clean up the pollset, etc. - LLPluginProcessParent::poll(0.0f); - } - - // Inherited from LLThread - /*virtual*/ bool runCondition(void) - { - return(LLPluginProcessParent::canPollThreadRun()); - } + // Inherited from LLThread + /*virtual*/ void run(void) + { + while(!isQuitting() && LLPluginProcessParent::getUseReadThread()) + { + LLPluginProcessParent::poll(0.1f); + checkPause(); + } + + // Final poll to clean up the pollset, etc. + LLPluginProcessParent::poll(0.0f); + } + + // Inherited from LLThread + /*virtual*/ bool runCondition(void) + { + return(LLPluginProcessParent::canPollThreadRun()); + } }; @@ -104,33 +104,33 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): mIncomingQueueMutex(), pProcessCreationThread(NULL) { - if(!sInstancesMutex) - { - sInstancesMutex = new LLMutex(); - } - - mOwner = owner; - mBoundPort = 0; - mState = STATE_UNINITIALIZED; - mSleepTime = 0.0; - mCPUUsage = 0.0; - mDisableTimeout = false; - mDebug = false; - mBlocked = false; - mPolledInput = false; - mPollFD.client_data = NULL; - - mPluginLaunchTimeout = 60.0f; - mPluginLockupTimeout = 15.0f; - - // Don't start the timer here -- start it when we actually launch the plugin process. - mHeartbeat.stop(); - + if(!sInstancesMutex) + { + sInstancesMutex = new LLMutex(); + } + + mOwner = owner; + mBoundPort = 0; + mState = STATE_UNINITIALIZED; + mSleepTime = 0.0; + mCPUUsage = 0.0; + mDisableTimeout = false; + mDebug = false; + mBlocked = false; + mPolledInput = false; + mPollFD.client_data = NULL; + + mPluginLaunchTimeout = 60.0f; + mPluginLockupTimeout = 15.0f; + + // Don't start the timer here -- start it when we actually launch the plugin process. + mHeartbeat.stop(); + } LLPluginProcessParent::~LLPluginProcessParent() { - LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; + LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; if (pProcessCreationThread) { if (!pProcessCreationThread->isStopped()) @@ -144,20 +144,20 @@ LLPluginProcessParent::~LLPluginProcessParent() pProcessCreationThread = NULL; } - // Destroy any remaining shared memory regions - sharedMemoryRegionsType::iterator iter; - while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end()) - { - // destroy the shared memory region - iter->second->destroy(); - delete iter->second; - iter->second = NULL; - - // and remove it from our map - mSharedMemoryRegions.erase(iter); - } - - LLProcess::kill(mProcess); + // Destroy any remaining shared memory regions + sharedMemoryRegionsType::iterator iter; + while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end()) + { + // destroy the shared memory region + iter->second->destroy(); + delete iter->second; + iter->second = NULL; + + // and remove it from our map + mSharedMemoryRegions.erase(iter); + } + + LLProcess::kill(mProcess); if (!LLApp::isQuitting()) { // If we are quitting, the network sockets will already have been destroyed. killSockets(); @@ -227,7 +227,7 @@ void LLPluginProcessParent::requestShutdown() namestream << "LLPluginProcessParentListener" << ++count; //*HACK!*// - // After requestShutdown has been called our previous owner will no longer call + // After requestShutdown has been called our previous owner will no longer call // our idle() method. Tie into the event loop here to do that until we are good // and finished. LL_DEBUGS("LLPluginProcessParent") << "listening on \"mainloop\"" << LL_ENDL; @@ -279,78 +279,78 @@ bool LLPluginProcessParent::wantsPolling() const void LLPluginProcessParent::killSockets(void) { - { - LLMutexLock lock(&mIncomingQueueMutex); - killMessagePipe(); - } + { + LLMutexLock lock(&mIncomingQueueMutex); + killMessagePipe(); + } - mListenSocket.reset(); - mSocket.reset(); + mListenSocket.reset(); + mSocket.reset(); } void LLPluginProcessParent::errorState(void) { - if(mState < STATE_RUNNING) - setState(STATE_LAUNCH_FAILURE); - else - setState(STATE_ERROR); + if(mState < STATE_RUNNING) + setState(STATE_LAUNCH_FAILURE); + else + setState(STATE_ERROR); } void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) -{ - mProcessParams.executable = launcher_filename; - mProcessParams.cwd = plugin_dir; - mPluginFile = plugin_filename; - mPluginDir = plugin_dir; - mCPUUsage = 0.0f; - mDebug = debug; - setState(STATE_INITIALIZED); +{ + mProcessParams.executable = launcher_filename; + mProcessParams.cwd = plugin_dir; + mPluginFile = plugin_filename; + mPluginDir = plugin_dir; + mCPUUsage = 0.0f; + mDebug = debug; + setState(STATE_INITIALIZED); } bool LLPluginProcessParent::accept() { - bool result = false; - - apr_status_t status = APR_EGENERAL; - apr_socket_t *new_socket = NULL; - - status = apr_socket_accept( - &new_socket, - mListenSocket->getSocket(), - gAPRPoolp); - - - if(status == APR_SUCCESS) - { -// LL_INFOS() << "SUCCESS" << LL_ENDL; - // Success. Create a message pipe on the new socket - - // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! - apr_pool_t* new_pool = NULL; - status = apr_pool_create(&new_pool, gAPRPoolp); - - mSocket = LLSocket::create(new_socket, new_pool); - new LLPluginMessagePipe(this, mSocket); - - result = true; - } - else if(APR_STATUS_IS_EAGAIN(status)) - { -// LL_INFOS() << "EAGAIN" << LL_ENDL; - - // No incoming connections. This is not an error. - status = APR_SUCCESS; - } - else - { -// LL_INFOS() << "Error:" << LL_ENDL; - ll_apr_warn_status(status); - - // Some other error. - errorState(); - } - - return result; + bool result = false; + + apr_status_t status = APR_EGENERAL; + apr_socket_t *new_socket = NULL; + + status = apr_socket_accept( + &new_socket, + mListenSocket->getSocket(), + gAPRPoolp); + + + if(status == APR_SUCCESS) + { +// LL_INFOS() << "SUCCESS" << LL_ENDL; + // Success. Create a message pipe on the new socket + + // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! + apr_pool_t* new_pool = NULL; + status = apr_pool_create(&new_pool, gAPRPoolp); + + mSocket = LLSocket::create(new_socket, new_pool); + new LLPluginMessagePipe(this, mSocket); + + result = true; + } + else if(APR_STATUS_IS_EAGAIN(status)) + { +// LL_INFOS() << "EAGAIN" << LL_ENDL; + + // No incoming connections. This is not an error. + status = APR_SUCCESS; + } + else + { +// LL_INFOS() << "Error:" << LL_ENDL; + ll_apr_warn_status(status); + + // Some other error. + errorState(); + } + + return result; } bool LLPluginProcessParent::createPluginProcess() @@ -384,166 +384,166 @@ void LLPluginProcessParent::clearProcessCreationThread() void LLPluginProcessParent::idle(void) { - bool idle_again; + bool idle_again; - do - { - // process queued messages + do + { + // process queued messages // Inside main thread, it is preferable not to block it on mutex. - bool locked = mIncomingQueueMutex.trylock(); - while(locked && !mIncomingQueue.empty()) - { - LLPluginMessage message = mIncomingQueue.front(); - mIncomingQueue.pop(); - mIncomingQueueMutex.unlock(); - - receiveMessage(message); - - locked = mIncomingQueueMutex.trylock(); - } + bool locked = mIncomingQueueMutex.trylock(); + while(locked && !mIncomingQueue.empty()) + { + LLPluginMessage message = mIncomingQueue.front(); + mIncomingQueue.pop(); + mIncomingQueueMutex.unlock(); + + receiveMessage(message); + + locked = mIncomingQueueMutex.trylock(); + } if (locked) { mIncomingQueueMutex.unlock(); } - - // Give time to network processing - if(mMessagePipe) - { - // Drain any queued outgoing messages - mMessagePipe->pumpOutput(); - - // Only do input processing here if this instance isn't in a pollset. - // If viewer and plugin are both shutting down, don't process further - // input, viewer won't be able to handle it. - if(!mPolledInput - && !(mState >= STATE_GOODBYE && LLApp::isExiting())) - { - mMessagePipe->pumpInput(); - } - } - - if(mState <= STATE_RUNNING) - { - if(APR_STATUS_IS_EOF(mSocketError)) - { - // Plugin socket was closed. This covers both normal plugin termination and plugin crashes. - errorState(); - } - else if(mSocketError != APR_SUCCESS) - { - // The socket is in an error state -- the plugin is gone. - LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; - errorState(); - } - } - - // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). - // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. - // When in doubt, don't do it. - idle_again = false; - switch(mState) - { - case STATE_UNINITIALIZED: - break; - - case STATE_INITIALIZED: - { - - apr_status_t status = APR_SUCCESS; - apr_sockaddr_t* addr = NULL; - mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); - mBoundPort = 0; - - // This code is based on parts of LLSocket::create() in lliosocket.cpp. - - status = apr_sockaddr_info_get( - &addr, - "127.0.0.1", - APR_INET, - 0, // port 0 = ephemeral ("find me a port") - 0, - gAPRPoolp); - - if(ll_apr_warn_status(status)) - { - killSockets(); - errorState(); - break; - } - - // This allows us to reuse the address on quick down/up. This is unlikely to create problems. - ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1)); - - status = apr_socket_bind(mListenSocket->getSocket(), addr); - if(ll_apr_warn_status(status)) - { - killSockets(); - errorState(); - break; - } - - // Get the actual port the socket was bound to - { - apr_sockaddr_t* bound_addr = NULL; - if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket()))) - { - killSockets(); - errorState(); - break; - } - mBoundPort = bound_addr->port; - - if(mBoundPort == 0) - { - LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; - - killSockets(); - errorState(); - break; - } - } - - LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; - - // Make the listen socket non-blocking - status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); - if(ll_apr_warn_status(status)) - { - killSockets(); - errorState(); - break; - } - - apr_socket_timeout_set(mListenSocket->getSocket(), 0); - if(ll_apr_warn_status(status)) - { - killSockets(); - errorState(); - break; - } - - // If it's a stream based socket, we need to tell the OS - // to keep a queue of incoming connections for ACCEPT. - status = apr_socket_listen( - mListenSocket->getSocket(), - 10); // FIXME: Magic number for queue size - - if(ll_apr_warn_status(status)) - { - killSockets(); - errorState(); - break; - } - - // If we got here, we're listening. - setState(STATE_LISTENING); - } - break; - - case STATE_LISTENING: - { - // Launch the plugin process. + + // Give time to network processing + if(mMessagePipe) + { + // Drain any queued outgoing messages + mMessagePipe->pumpOutput(); + + // Only do input processing here if this instance isn't in a pollset. + // If viewer and plugin are both shutting down, don't process further + // input, viewer won't be able to handle it. + if(!mPolledInput + && !(mState >= STATE_GOODBYE && LLApp::isExiting())) + { + mMessagePipe->pumpInput(); + } + } + + if(mState <= STATE_RUNNING) + { + if(APR_STATUS_IS_EOF(mSocketError)) + { + // Plugin socket was closed. This covers both normal plugin termination and plugin crashes. + errorState(); + } + else if(mSocketError != APR_SUCCESS) + { + // The socket is in an error state -- the plugin is gone. + LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; + errorState(); + } + } + + // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). + // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. + // When in doubt, don't do it. + idle_again = false; + switch(mState) + { + case STATE_UNINITIALIZED: + break; + + case STATE_INITIALIZED: + { + + apr_status_t status = APR_SUCCESS; + apr_sockaddr_t* addr = NULL; + mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mBoundPort = 0; + + // This code is based on parts of LLSocket::create() in lliosocket.cpp. + + status = apr_sockaddr_info_get( + &addr, + "127.0.0.1", + APR_INET, + 0, // port 0 = ephemeral ("find me a port") + 0, + gAPRPoolp); + + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // This allows us to reuse the address on quick down/up. This is unlikely to create problems. + ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1)); + + status = apr_socket_bind(mListenSocket->getSocket(), addr); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // Get the actual port the socket was bound to + { + apr_sockaddr_t* bound_addr = NULL; + if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket()))) + { + killSockets(); + errorState(); + break; + } + mBoundPort = bound_addr->port; + + if(mBoundPort == 0) + { + LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; + + killSockets(); + errorState(); + break; + } + } + + LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; + + // Make the listen socket non-blocking + status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + apr_socket_timeout_set(mListenSocket->getSocket(), 0); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // If it's a stream based socket, we need to tell the OS + // to keep a queue of incoming connections for ACCEPT. + status = apr_socket_listen( + mListenSocket->getSocket(), + 10); // FIXME: Magic number for queue size + + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // If we got here, we're listening. + setState(STATE_LISTENING); + } + break; + + case STATE_LISTENING: + { + // Launch the plugin process. if (mDebug && !pProcessCreationThread) { createPluginProcess(); @@ -566,36 +566,36 @@ void LLPluginProcessParent::idle(void) errorState(); } - - if (mProcess) - { - if(mDebug) - { + + if (mProcess) + { + if(mDebug) + { #if LL_DARWIN - // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue. - - // The command we're constructing would look like this on the command line: - // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell' - - LLProcess::Params params; - params.executable = "/usr/bin/osascript"; - params.args.add("-e"); - params.args.add("tell application \"Terminal\""); - params.args.add("-e"); - params.args.add(STRINGIZE("set win to do script \"lldb -pid " - << mProcess->getProcessID() << "\"")); - params.args.add("-e"); - params.args.add("do script \"continue\" in win"); - params.args.add("-e"); - params.args.add("end tell"); - mDebugger = LLProcess::create(params); + // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue. + + // The command we're constructing would look like this on the command line: + // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell' + + LLProcess::Params params; + params.executable = "/usr/bin/osascript"; + params.args.add("-e"); + params.args.add("tell application \"Terminal\""); + params.args.add("-e"); + params.args.add(STRINGIZE("set win to do script \"lldb -pid " + << mProcess->getProcessID() << "\"")); + params.args.add("-e"); + params.args.add("do script \"continue\" in win"); + params.args.add("-e"); + params.args.add("end tell"); + mDebugger = LLProcess::create(params); #endif - } - - // This will allow us to time out if the process never starts. - mHeartbeat.start(); - mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); + } + + // This will allow us to time out if the process never starts. + mHeartbeat.start(); + mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); // pProcessCreationThread should have stopped by this point, // but check just in case it paused on statistics sync @@ -605,67 +605,67 @@ void LLPluginProcessParent::idle(void) pProcessCreationThread = NULL; } - setState(STATE_LAUNCHED); - } - } - break; - - case STATE_LAUNCHED: - // waiting for the plugin to connect - if(pluginLockedUpOrQuit()) - { - errorState(); - } - else - { - // Check for the incoming connection. - if(accept()) - { - // Stop listening on the server port - mListenSocket.reset(); - setState(STATE_CONNECTED); - } - } - break; - - case STATE_CONNECTED: - // waiting for hello message from the plugin - - if(pluginLockedUpOrQuit()) - { - errorState(); - } - break; - - case STATE_HELLO: - LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; - - // Send the message to load the plugin - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); - message.setValue("file", mPluginFile); - message.setValue("dir", mPluginDir); - sendMessage(message); - } - - setState(STATE_LOADING); - break; - - case STATE_LOADING: - // The load_plugin_response message will kick us from here into STATE_RUNNING - if(pluginLockedUpOrQuit()) - { - errorState(); - } - break; - - case STATE_RUNNING: - if(pluginLockedUpOrQuit()) - { - errorState(); - } - break; - + setState(STATE_LAUNCHED); + } + } + break; + + case STATE_LAUNCHED: + // waiting for the plugin to connect + if(pluginLockedUpOrQuit()) + { + errorState(); + } + else + { + // Check for the incoming connection. + if(accept()) + { + // Stop listening on the server port + mListenSocket.reset(); + setState(STATE_CONNECTED); + } + } + break; + + case STATE_CONNECTED: + // waiting for hello message from the plugin + + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + + case STATE_HELLO: + LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; + + // Send the message to load the plugin + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); + message.setValue("file", mPluginFile); + message.setValue("dir", mPluginDir); + sendMessage(message); + } + + setState(STATE_LOADING); + break; + + case STATE_LOADING: + // The load_plugin_response message will kick us from here into STATE_RUNNING + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + + case STATE_RUNNING: + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + case STATE_GOODBYE: { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shutdown_plugin"); @@ -674,292 +674,292 @@ void LLPluginProcessParent::idle(void) setState(STATE_EXITING); break; - case STATE_EXITING: - if (! LLProcess::isRunning(mProcess)) - { - setState(STATE_CLEANUP); - } - else if(pluginLockedUp()) - { - LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; - errorState(); - } - break; - - case STATE_LAUNCH_FAILURE: - if(mOwner != NULL) - { - mOwner->pluginLaunchFailed(); - } - setState(STATE_CLEANUP); - break; - - case STATE_ERROR: - if(mOwner != NULL) - { - mOwner->pluginDied(); - } - setState(STATE_CLEANUP); - break; - - case STATE_CLEANUP: - LLProcess::kill(mProcess); - killSockets(); - setState(STATE_DONE); + case STATE_EXITING: + if (! LLProcess::isRunning(mProcess)) + { + setState(STATE_CLEANUP); + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; + errorState(); + } + break; + + case STATE_LAUNCH_FAILURE: + if(mOwner != NULL) + { + mOwner->pluginLaunchFailed(); + } + setState(STATE_CLEANUP); + break; + + case STATE_ERROR: + if(mOwner != NULL) + { + mOwner->pluginDied(); + } + setState(STATE_CLEANUP); + break; + + case STATE_CLEANUP: + LLProcess::kill(mProcess); + killSockets(); + setState(STATE_DONE); dirtyPollSet(); clearProcessCreationThread(); - break; - - case STATE_DONE: - // just sit here. - break; - } - - } while (idle_again); + break; + + case STATE_DONE: + // just sit here. + break; + } + + } while (idle_again); } bool LLPluginProcessParent::isLoading(void) { - bool result = false; - - if(mState <= STATE_LOADING) - result = true; - - return result; + bool result = false; + + if(mState <= STATE_LOADING) + result = true; + + return result; } bool LLPluginProcessParent::isRunning(void) { - bool result = false; - - if(mState == STATE_RUNNING) - result = true; - - return result; + bool result = false; + + if(mState == STATE_RUNNING) + result = true; + + return result; } bool LLPluginProcessParent::isDone(void) { - bool result = false; - - if(mState == STATE_DONE) - result = true; - - return result; + bool result = false; + + if(mState == STATE_DONE) + result = true; + + return result; } void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send) { - if(force_send || (sleep_time != mSleepTime)) - { - // Cache the time locally - mSleepTime = sleep_time; - - if(canSendMessage()) - { - // and send to the plugin. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time"); - message.setValueReal("time", mSleepTime); - sendMessage(message); - } - else - { - // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later. - } - } + if(force_send || (sleep_time != mSleepTime)) + { + // Cache the time locally + mSleepTime = sleep_time; + + if(canSendMessage()) + { + // and send to the plugin. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time"); + message.setValueReal("time", mSleepTime); + sendMessage(message); + } + else + { + // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later. + } + } } void LLPluginProcessParent::sendMessage(const LLPluginMessage &message) { - if(message.hasValue("blocking_response")) - { - mBlocked = false; - - // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. - mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); - } - - std::string buffer = message.generate(); - LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; - writeMessageRaw(buffer); - - // Try to send message immediately. - if(mMessagePipe) - { - mMessagePipe->pumpOutput(); - } + if(message.hasValue("blocking_response")) + { + mBlocked = false; + + // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. + mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); + } + + std::string buffer = message.generate(); + LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; + writeMessageRaw(buffer); + + // Try to send message immediately. + if(mMessagePipe) + { + mMessagePipe->pumpOutput(); + } } -//virtual +//virtual void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) { - bool update_pollset = false; - - if(mMessagePipe) - { - // Unsetting an existing message pipe -- remove from the pollset - mPollFD.client_data = NULL; - - // pollset needs an update - update_pollset = true; - } - if(message_pipe != NULL) - { - // Set up the apr_pollfd_t - mPollFD.p = gAPRPoolp; - mPollFD.desc_type = APR_POLL_SOCKET; - mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; - mPollFD.rtnevents = 0; - mPollFD.desc.s = mSocket->getSocket(); - mPollFD.client_data = (void*)this; - - // pollset needs an update - update_pollset = true; - } - - mMessagePipe = message_pipe; - - if(update_pollset) - { - dirtyPollSet(); - } + bool update_pollset = false; + + if(mMessagePipe) + { + // Unsetting an existing message pipe -- remove from the pollset + mPollFD.client_data = NULL; + + // pollset needs an update + update_pollset = true; + } + if(message_pipe != NULL) + { + // Set up the apr_pollfd_t + mPollFD.p = gAPRPoolp; + mPollFD.desc_type = APR_POLL_SOCKET; + mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; + mPollFD.rtnevents = 0; + mPollFD.desc.s = mSocket->getSocket(); + mPollFD.client_data = (void*)this; + + // pollset needs an update + update_pollset = true; + } + + mMessagePipe = message_pipe; + + if(update_pollset) + { + dirtyPollSet(); + } } -//static +//static void LLPluginProcessParent::dirtyPollSet() { - sPollsetNeedsRebuild = true; - - if(sReadThread) - { - LL_DEBUGS("PluginPoll") << "unpausing read thread " << LL_ENDL; - sReadThread->unpause(); - } + sPollsetNeedsRebuild = true; + + if(sReadThread) + { + LL_DEBUGS("PluginPoll") << "unpausing read thread " << LL_ENDL; + sReadThread->unpause(); + } } void LLPluginProcessParent::updatePollset() { - if(!sInstancesMutex) - { - // No instances have been created yet. There's no work to do. - return; - } - - LLMutexLock lock(sInstancesMutex); - - if(sPollSet) - { - LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL; - // delete the existing pollset. - apr_pollset_destroy(sPollSet); - sPollSet = NULL; - } - + if(!sInstancesMutex) + { + // No instances have been created yet. There's no work to do. + return; + } + + LLMutexLock lock(sInstancesMutex); + + if(sPollSet) + { + LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL; + // delete the existing pollset. + apr_pollset_destroy(sPollSet); + sPollSet = NULL; + } + mapInstances_t::iterator iter; - int count = 0; - - // Count the number of instances that want to be in the pollset - for(iter = sInstances.begin(); iter != sInstances.end(); iter++) - { - (*iter).second->mPolledInput = false; + int count = 0; + + // Count the number of instances that want to be in the pollset + for(iter = sInstances.begin(); iter != sInstances.end(); iter++) + { + (*iter).second->mPolledInput = false; if ((*iter).second->wantsPolling()) - { - // This instance has a socket that needs to be polled. - ++count; - } - } - - if(sUseReadThread && sReadThread && !sReadThread->isQuitting()) - { - if(!sPollSet && (count > 0)) - { + { + // This instance has a socket that needs to be polled. + ++count; + } + } + + if(sUseReadThread && sReadThread && !sReadThread->isQuitting()) + { + if(!sPollSet && (count > 0)) + { #ifdef APR_POLLSET_NOCOPY - // The pollset doesn't exist yet. Create it now. - apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); - if(status != APR_SUCCESS) - { + // The pollset doesn't exist yet. Create it now. + apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); + if(status != APR_SUCCESS) + { #endif // APR_POLLSET_NOCOPY - LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; - sPollSet = NULL; + LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; + sPollSet = NULL; #ifdef APR_POLLSET_NOCOPY - } - else - { - LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL; - - // Pollset was created, add all instances to it. - for(iter = sInstances.begin(); iter != sInstances.end(); iter++) - { + } + else + { + LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL; + + // Pollset was created, add all instances to it. + for(iter = sInstances.begin(); iter != sInstances.end(); iter++) + { if ((*iter).second->wantsPolling()) - { - status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD)); - if(status == APR_SUCCESS) - { - (*iter).second->mPolledInput = true; - } - else - { - LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL; - } - } - } - } + { + status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD)); + if(status == APR_SUCCESS) + { + (*iter).second->mPolledInput = true; + } + else + { + LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL; + } + } + } + } #endif // APR_POLLSET_NOCOPY - } - } + } + } } void LLPluginProcessParent::setUseReadThread(bool use_read_thread) { - if(sUseReadThread != use_read_thread) - { - sUseReadThread = use_read_thread; - - if(sUseReadThread) - { - if(!sReadThread) - { - // start up the read thread - LL_INFOS("PluginPoll") << "creating read thread " << LL_ENDL; - - // make sure the pollset gets rebuilt. - sPollsetNeedsRebuild = true; - - sReadThread = new LLPluginProcessParentPollThread; - sReadThread->start(); - } - } - else - { - if(sReadThread) - { - // shut down the read thread - LL_INFOS("PluginPoll") << "destroying read thread " << LL_ENDL; - delete sReadThread; - sReadThread = NULL; - } - } - - } + if(sUseReadThread != use_read_thread) + { + sUseReadThread = use_read_thread; + + if(sUseReadThread) + { + if(!sReadThread) + { + // start up the read thread + LL_INFOS("PluginPoll") << "creating read thread " << LL_ENDL; + + // make sure the pollset gets rebuilt. + sPollsetNeedsRebuild = true; + + sReadThread = new LLPluginProcessParentPollThread; + sReadThread->start(); + } + } + else + { + if(sReadThread) + { + // shut down the read thread + LL_INFOS("PluginPoll") << "destroying read thread " << LL_ENDL; + delete sReadThread; + sReadThread = NULL; + } + } + + } } void LLPluginProcessParent::poll(F64 timeout) { - if(sPollsetNeedsRebuild || !sUseReadThread) - { - sPollsetNeedsRebuild = false; - updatePollset(); - } - - if(sPollSet) - { - apr_status_t status; - apr_int32_t count; - const apr_pollfd_t *descriptors; - status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors); - if(status == APR_SUCCESS) - { - // One or more of the descriptors signalled. Call them. + if(sPollsetNeedsRebuild || !sUseReadThread) + { + sPollsetNeedsRebuild = false; + updatePollset(); + } + + if(sPollSet) + { + apr_status_t status; + apr_int32_t count; + const apr_pollfd_t *descriptors; + status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors); + if(status == APR_SUCCESS) + { + // One or more of the descriptors signalled. Call them. for (int i = 0; i < count; i++) { void *thatId = descriptors[i].client_data; @@ -981,23 +981,23 @@ void LLPluginProcessParent::poll(F64 timeout) that->mIncomingQueueMutex.unlock(); } - } - } - else if(APR_STATUS_IS_TIMEUP(status)) - { - // timed out with no incoming data. Just return. - } - else if(status == EBADF) - { - // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed. - // The pollset has been or will be recreated, so just return. - LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL; - } - else if(status != APR_SUCCESS) - { - LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL; - } - } + } + } + else if(APR_STATUS_IS_TIMEUP(status)) + { + // timed out with no incoming data. Just return. + } + else if(status == EBADF) + { + // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed. + // The pollset has been or will be recreated, so just return. + LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL; + } + else if(status != APR_SUCCESS) + { + LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL; + } + } // Remove instances in the done state from the sInstances map. mapInstances_t::iterator itClean = sInstances.begin(); @@ -1012,293 +1012,293 @@ void LLPluginProcessParent::poll(F64 timeout) void LLPluginProcessParent::servicePoll() { - bool result = true; - - // poll signalled on this object's socket. Try to process incoming messages. - if(mMessagePipe) - { - result = mMessagePipe->pumpInput(0.0f); - } - - if(!result) - { - // If we got a read error on input, remove this pipe from the pollset - apr_pollset_remove(sPollSet, &mPollFD); - - // and tell the code not to re-add it - mPollFD.client_data = NULL; - } + bool result = true; + + // poll signalled on this object's socket. Try to process incoming messages. + if(mMessagePipe) + { + result = mMessagePipe->pumpInput(0.0f); + } + + if(!result) + { + // If we got a read error on input, remove this pipe from the pollset + apr_pollset_remove(sPollSet, &mPollFD); + + // and tell the code not to re-add it + mPollFD.client_data = NULL; + } } void LLPluginProcessParent::receiveMessageRaw(const std::string &message) { - LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; - - LLPluginMessage parsed; - if(LLSDParser::PARSE_FAILURE != parsed.parse(message)) - { - if(parsed.hasValue("blocking_request")) - { - mBlocked = true; - } - - if(mPolledInput) - { - // This is being called on the polling thread -- only do minimal processing/queueing. - receiveMessageEarly(parsed); - } - else - { - // This is not being called on the polling thread -- do full message processing at this time. - receiveMessage(parsed); - } - } + LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; + + LLPluginMessage parsed; + if(LLSDParser::PARSE_FAILURE != parsed.parse(message)) + { + if(parsed.hasValue("blocking_request")) + { + mBlocked = true; + } + + if(mPolledInput) + { + // This is being called on the polling thread -- only do minimal processing/queueing. + receiveMessageEarly(parsed); + } + else + { + // This is not being called on the polling thread -- do full message processing at this time. + receiveMessage(parsed); + } + } } void LLPluginProcessParent::receiveMessageEarly(const LLPluginMessage &message) { - // NOTE: this function will be called from the polling thread. It will be called with mIncomingQueueMutex _already locked_. - - bool handled = false; - - std::string message_class = message.getClass(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) - { - // no internal messages need to be handled early. - } - else - { - // Call out to the owner and see if they to reply - // TODO: Should this only happen when blocked? - if(mOwner != NULL) - { - handled = mOwner->receivePluginMessageEarly(message); - } - } - - if(!handled) - { - // any message that wasn't handled early needs to be queued. - mIncomingQueue.push(message); - } + // NOTE: this function will be called from the polling thread. It will be called with mIncomingQueueMutex _already locked_. + + bool handled = false; + + std::string message_class = message.getClass(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) + { + // no internal messages need to be handled early. + } + else + { + // Call out to the owner and see if they to reply + // TODO: Should this only happen when blocked? + if(mOwner != NULL) + { + handled = mOwner->receivePluginMessageEarly(message); + } + } + + if(!handled) + { + // any message that wasn't handled early needs to be queued. + mIncomingQueue.push(message); + } } void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) { - std::string message_class = message.getClass(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) - { - // internal messages should be handled here - std::string message_name = message.getName(); - if(message_name == "hello") - { - if(mState == STATE_CONNECTED) - { - // Plugin host has launched. Tell it which plugin to load. - setState(STATE_HELLO); - } - else - { - LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; - errorState(); - } - - } - else if(message_name == "load_plugin_response") - { - if(mState == STATE_LOADING) - { - // Plugin has been loaded. - - mPluginVersionString = message.getValue("plugin_version"); - LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; - - // Check which message classes/versions the plugin supports. - // TODO: check against current versions - // TODO: kill plugin on major mismatches? - mMessageClassVersions = message.getValueLLSD("versions"); - LLSD::map_iterator iter; - for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) - { - LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; - } - - // Send initial sleep time - llassert_always(mSleepTime != 0.f); - setSleepTime(mSleepTime, true); - - setState(STATE_RUNNING); - } - else - { - LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; - errorState(); - } - } - else if(message_name == "heartbeat") - { - // this resets our timer. - mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); - - mCPUUsage = message.getValueReal("cpu_usage"); - - LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; - - } - else if(message_name == "shm_add_response") - { - // Nothing to do here. - } - else if(message_name == "shm_remove_response") - { - std::string name = message.getValue("name"); - sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); - - if(iter != mSharedMemoryRegions.end()) - { - // destroy the shared memory region - iter->second->destroy(); - delete iter->second; - iter->second = NULL; - - // and remove it from our map - mSharedMemoryRegions.erase(iter); - } - } - else - { - LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; - } - } - else - { - if(mOwner != NULL) - { - mOwner->receivePluginMessage(message); - } - } + std::string message_class = message.getClass(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) + { + // internal messages should be handled here + std::string message_name = message.getName(); + if(message_name == "hello") + { + if(mState == STATE_CONNECTED) + { + // Plugin host has launched. Tell it which plugin to load. + setState(STATE_HELLO); + } + else + { + LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; + errorState(); + } + + } + else if(message_name == "load_plugin_response") + { + if(mState == STATE_LOADING) + { + // Plugin has been loaded. + + mPluginVersionString = message.getValue("plugin_version"); + LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; + + // Check which message classes/versions the plugin supports. + // TODO: check against current versions + // TODO: kill plugin on major mismatches? + mMessageClassVersions = message.getValueLLSD("versions"); + LLSD::map_iterator iter; + for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) + { + LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; + } + + // Send initial sleep time + llassert_always(mSleepTime != 0.f); + setSleepTime(mSleepTime, true); + + setState(STATE_RUNNING); + } + else + { + LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; + errorState(); + } + } + else if(message_name == "heartbeat") + { + // this resets our timer. + mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); + + mCPUUsage = message.getValueReal("cpu_usage"); + + LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; + + } + else if(message_name == "shm_add_response") + { + // Nothing to do here. + } + else if(message_name == "shm_remove_response") + { + std::string name = message.getValue("name"); + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + + if(iter != mSharedMemoryRegions.end()) + { + // destroy the shared memory region + iter->second->destroy(); + delete iter->second; + iter->second = NULL; + + // and remove it from our map + mSharedMemoryRegions.erase(iter); + } + } + else + { + LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; + } + } + else + { + if(mOwner != NULL) + { + mOwner->receivePluginMessage(message); + } + } } std::string LLPluginProcessParent::addSharedMemory(size_t size) { - std::string name; - - LLPluginSharedMemory *region = new LLPluginSharedMemory; - - // This is a new region - if(region->create(size)) - { - name = region->getName(); - - mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region)); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add"); - message.setValue("name", name); - message.setValueS32("size", (S32)size); - sendMessage(message); - } - else - { - LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; - - // Don't leak - delete region; - } - - return name; + std::string name; + + LLPluginSharedMemory *region = new LLPluginSharedMemory; + + // This is a new region + if(region->create(size)) + { + name = region->getName(); + + mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region)); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add"); + message.setValue("name", name); + message.setValueS32("size", (S32)size); + sendMessage(message); + } + else + { + LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; + + // Don't leak + delete region; + } + + return name; } void LLPluginProcessParent::removeSharedMemory(const std::string &name) { - sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); - - if(iter != mSharedMemoryRegions.end()) - { - // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove"); - message.setValue("name", name); - sendMessage(message); - } - else - { - LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL; - } + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + + if(iter != mSharedMemoryRegions.end()) + { + // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove"); + message.setValue("name", name); + sendMessage(message); + } + else + { + LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL; + } } size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name) { - size_t result = 0; - - sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); - if(iter != mSharedMemoryRegions.end()) - { - result = iter->second->getSize(); - } - - return result; + size_t result = 0; + + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + result = iter->second->getSize(); + } + + return result; } void *LLPluginProcessParent::getSharedMemoryAddress(const std::string &name) { - void *result = NULL; - - sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); - if(iter != mSharedMemoryRegions.end()) - { - result = iter->second->getMappedAddress(); - } - - return result; + void *result = NULL; + + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + result = iter->second->getMappedAddress(); + } + + return result; } std::string LLPluginProcessParent::getMessageClassVersion(const std::string &message_class) { - std::string result; - - if(mMessageClassVersions.has(message_class)) - { - result = mMessageClassVersions[message_class].asString(); - } - - return result; + std::string result; + + if(mMessageClassVersions.has(message_class)) + { + result = mMessageClassVersions[message_class].asString(); + } + + return result; } std::string LLPluginProcessParent::getPluginVersion(void) { - return mPluginVersionString; + return mPluginVersionString; } void LLPluginProcessParent::setState(EState state) { - LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; - mState = state; + LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; + mState = state; }; bool LLPluginProcessParent::pluginLockedUpOrQuit() { - bool result = false; - - if (! LLProcess::isRunning(mProcess)) - { - LL_WARNS("Plugin") << "child exited" << LL_ENDL; - result = true; - } - else if(pluginLockedUp()) - { - LL_WARNS("Plugin") << "timeout" << LL_ENDL; - result = true; - } - - return result; + bool result = false; + + if (! LLProcess::isRunning(mProcess)) + { + LL_WARNS("Plugin") << "child exited" << LL_ENDL; + result = true; + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout" << LL_ENDL; + result = true; + } + + return result; } bool LLPluginProcessParent::pluginLockedUp() { - if(mDisableTimeout || mDebug || mBlocked) - { - // Never time out a plugin process in these cases. - return false; - } - - // If the timer is running and has expired, the plugin has locked up. - return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); + if(mDisableTimeout || mDebug || mBlocked) + { + // Never time out a plugin process in these cases. + return false; + } + + // If the timer is running and has expired, the plugin has locked up. + return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); } diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 53d09df618..088d3d1339 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llprimitive.cpp * @brief LLPrimitive base class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -57,9 +57,9 @@ const F32 OBJECT_TWIST_INC = 18.f; // This is used for linear paths, // since twist is used in a slightly different manner. -const F32 OBJECT_TWIST_LINEAR_MIN = -180.f; -const F32 OBJECT_TWIST_LINEAR_MAX = 180.f; -const F32 OBJECT_TWIST_LINEAR_INC = 9.f; +const F32 OBJECT_TWIST_LINEAR_MIN = -180.f; +const F32 OBJECT_TWIST_LINEAR_MAX = 180.f; +const F32 OBJECT_TWIST_LINEAR_INC = 9.f; const F32 OBJECT_MIN_HOLE_SIZE = 0.05f; const F32 OBJECT_MAX_HOLE_SIZE_X = 1.0f; @@ -94,7 +94,7 @@ const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f; // "Tension" => [0,10], increments of 0.1 const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f; const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f; -const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f; +const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f; // "Drag" => [0,10], increments of 0.1 const F32 FLEXIBLE_OBJECT_MIN_AIR_FRICTION = 0.0f; @@ -112,7 +112,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY = 0.0f; const F32 FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY = 10.0f; // I'll explain later... -const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f; +const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f; const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f; const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; @@ -121,9 +121,9 @@ const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; // Texture rotations are sent over the wire as a S16. This is used to scale the actual float -// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it +// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it // can't be divided by 2. See DEV-19108 -const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000); +const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000); struct material_id_type // originally from llrendermaterialtable { @@ -154,7 +154,7 @@ struct material_id_type // originally from llrendermaterialtable const U8 material_id_type::s_null_id[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -//static +//static // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global // TODO -- eliminate this global from the codebase! LLVolumeMgr* LLPrimitive::sVolumeManager = NULL; @@ -162,61 +162,61 @@ LLVolumeMgr* LLPrimitive::sVolumeManager = NULL; // static void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) { - if ( !volume_manager || sVolumeManager ) - { - LL_ERRS() << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << LL_ENDL; - } - sVolumeManager = volume_manager; + if ( !volume_manager || sVolumeManager ) + { + LL_ERRS() << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << LL_ENDL; + } + sVolumeManager = volume_manager; } // static bool LLPrimitive::cleanupVolumeManager() { - BOOL res = FALSE; - if (sVolumeManager) - { - res = sVolumeManager->cleanup(); - delete sVolumeManager; - sVolumeManager = NULL; - } - return res; + BOOL res = FALSE; + if (sVolumeManager) + { + res = sVolumeManager->cleanup(); + delete sVolumeManager; + sVolumeManager = NULL; + } + return res; } //=============================================================== LLPrimitive::LLPrimitive() -: mTextureList(), - mNumTEs(0), - mMiscFlags(0), - mNumBumpmapTEs(0) +: mTextureList(), + mNumTEs(0), + mMiscFlags(0), + mNumBumpmapTEs(0) { - mPrimitiveCode = 0; + mPrimitiveCode = 0; - mMaterial = LL_MCODE_STONE; - mVolumep = NULL; + mMaterial = LL_MCODE_STONE; + mVolumep = NULL; - mChanged = UNCHANGED; + mChanged = UNCHANGED; - mPosition.setVec(0.f,0.f,0.f); - mVelocity.setVec(0.f,0.f,0.f); - mAcceleration.setVec(0.f,0.f,0.f); + mPosition.setVec(0.f,0.f,0.f); + mVelocity.setVec(0.f,0.f,0.f); + mAcceleration.setVec(0.f,0.f,0.f); - mRotation.loadIdentity(); - mAngularVelocity.setVec(0.f,0.f,0.f); - - mScale.setVec(1.f,1.f,1.f); + mRotation.loadIdentity(); + mAngularVelocity.setVec(0.f,0.f,0.f); + + mScale.setVec(1.f,1.f,1.f); } //=============================================================== LLPrimitive::~LLPrimitive() { - clearTextureList(); - // Cleanup handled by volume manager - if (mVolumep && sVolumeManager) - { - sVolumeManager->unrefVolume(mVolumep); - } - mVolumep = NULL; + clearTextureList(); + // Cleanup handled by volume manager + if (mVolumep && sVolumeManager) + { + sVolumeManager->unrefVolume(mVolumep); + } + mVolumep = NULL; } void LLPrimitive::clearTextureList() @@ -227,83 +227,83 @@ void LLPrimitive::clearTextureList() // static LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) { - LLPrimitive *retval = new LLPrimitive(); - - if (retval) - { - retval->init_primitive(p_code); - } - else - { - LL_ERRS() << "primitive allocation failed" << LL_ENDL; - } + LLPrimitive *retval = new LLPrimitive(); - return retval; + if (retval) + { + retval->init_primitive(p_code); + } + else + { + LL_ERRS() << "primitive allocation failed" << LL_ENDL; + } + + return retval; } //=============================================================== void LLPrimitive::init_primitive(LLPCode p_code) { - clearTextureList(); - mPrimitiveCode = p_code; + clearTextureList(); + mPrimitiveCode = p_code; } void LLPrimitive::setPCode(const U8 p_code) { - mPrimitiveCode = p_code; + mPrimitiveCode = p_code; } //=============================================================== LLTextureEntry* LLPrimitive::getTE(const U8 index) const { - return mTextureList.getTexture(index); + return mTextureList.getTexture(index); } //=============================================================== void LLPrimitive::setNumTEs(const U8 num_tes) { - mTextureList.setSize(num_tes); + mTextureList.setSize(num_tes); } //=============================================================== void LLPrimitive::setAllTETextures(const LLUUID &tex_id) { - mTextureList.setAllIDs(tex_id); + mTextureList.setAllIDs(tex_id); } //=============================================================== void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) - { - mNumBumpmapTEs++; - } + if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) + { + mNumBumpmapTEs++; + } } S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) { - return mTextureList.setID(index, id); + return mTextureList.setID(index, id); } S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color) { - return mTextureList.setColor(index, color); + return mTextureList.setColor(index, color); } S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color) { - return mTextureList.setColor(index, color); + return mTextureList.setColor(index, color); } S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha) { - return mTextureList.setAlpha(index, alpha); + return mTextureList.setAlpha(index, alpha); } //=============================================================== S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t) { - return mTextureList.setScale(index, s, t); + return mTextureList.setScale(index, s, t); } @@ -311,7 +311,7 @@ S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t) // voodoo related to texture coords S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s) { - return mTextureList.setScaleS(index, s); + return mTextureList.setScaleS(index, s); } @@ -319,14 +319,14 @@ S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s) // voodoo related to texture coords S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t) { - return mTextureList.setScaleT(index, t); + return mTextureList.setScaleT(index, t); } //=============================================================== S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t) { - return mTextureList.setOffset(index, s, t); + return mTextureList.setOffset(index, s, t); } @@ -334,7 +334,7 @@ S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t) // voodoo related to texture coords S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s) { - return mTextureList.setOffsetS(index, s); + return mTextureList.setOffsetS(index, s); } @@ -342,289 +342,289 @@ S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s) // voodoo related to texture coords S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t) { - return mTextureList.setOffsetT(index, t); + return mTextureList.setOffsetT(index, t); } //=============================================================== S32 LLPrimitive::setTERotation(const U8 index, const F32 r) { - return mTextureList.setRotation(index, r); + return mTextureList.setRotation(index, r); } S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID) { - return mTextureList.setMaterialID(index, pMaterialID); + return mTextureList.setMaterialID(index, pMaterialID); } S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) { - return mTextureList.setMaterialParams(index, pMaterialParams); + return mTextureList.setMaterialParams(index, pMaterialParams); } LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index) { - return mTextureList.getMaterialParams(index); + return mTextureList.getMaterialParams(index); } //=============================================================== S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { - updateNumBumpmap(index, bump); - return mTextureList.setBumpShinyFullbright(index, bump); + updateNumBumpmap(index, bump); + return mTextureList.setBumpShinyFullbright(index, bump); } S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) { - return mTextureList.setMediaTexGen(index, media); + return mTextureList.setMediaTexGen(index, media); } S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { - updateNumBumpmap(index, bump); - return mTextureList.setBumpMap(index, bump); + updateNumBumpmap(index, bump); + return mTextureList.setBumpMap(index, bump); } S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { - updateNumBumpmap(index, bump_shiny); - return mTextureList.setBumpShiny(index, bump_shiny); + updateNumBumpmap(index, bump_shiny); + return mTextureList.setBumpShiny(index, bump_shiny); } S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen) { - return mTextureList.setTexGen(index, texgen); + return mTextureList.setTexGen(index, texgen); } S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny) { - return mTextureList.setShiny(index, shiny); + return mTextureList.setShiny(index, shiny); } S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) { - return mTextureList.setFullbright(index, fullbright); + return mTextureList.setFullbright(index, fullbright); } S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { - return mTextureList.setMediaFlags(index, media_flags); + return mTextureList.setMediaFlags(index, media_flags); } S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) { - return mTextureList.setGlow(index, glow); + return mTextureList.setGlow(index, glow); } void LLPrimitive::setAllTESelected(bool sel) { - for (int i = 0, cnt = getNumTEs(); i < cnt; i++) - { - setTESelected(i, sel); - } + for (int i = 0, cnt = getNumTEs(); i < cnt; i++) + { + setTESelected(i, sel); + } } - + void LLPrimitive::setTESelected(const U8 te, bool sel) { - LLTextureEntry* tep = getTE(te); - if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) ) - { - LLMaterialID material_id = tep->getMaterialID(); - setTEMaterialID(te, material_id); - } + LLTextureEntry* tep = getTE(te); + if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) ) + { + LLMaterialID material_id = tep->getMaterialID(); + setTEMaterialID(te, material_id); + } } LLPCode LLPrimitive::legacyToPCode(const U8 legacy) { - // TODO: Should this default to something valid? - // Maybe volume? - LLPCode pcode = 0; - - switch (legacy) - { - /* - case BOX: - pcode = LL_PCODE_CUBE; - break; - case CYLINDER: - pcode = LL_PCODE_CYLINDER; - break; - case CONE: - pcode = LL_PCODE_CONE; - break; - case HALF_CONE: - pcode = LL_PCODE_CONE_HEMI; - break; - case HALF_CYLINDER: - pcode = LL_PCODE_CYLINDER_HEMI; - break; - case HALF_SPHERE: - pcode = LL_PCODE_SPHERE_HEMI; - break; - case PRISM: - pcode = LL_PCODE_PRISM; - break; - case PYRAMID: - pcode = LL_PCODE_PYRAMID; - break; - case SPHERE: - pcode = LL_PCODE_SPHERE; - break; - case TETRAHEDRON: - pcode = LL_PCODE_TETRAHEDRON; - break; - case DEMON: - pcode = LL_PCODE_LEGACY_DEMON; - break; - case LSL_TEST: - pcode = LL_PCODE_LEGACY_LSL_TEST; - break; - case ORACLE: - pcode = LL_PCODE_LEGACY_ORACLE; - break; - case TEXTBUBBLE: - pcode = LL_PCODE_LEGACY_TEXT_BUBBLE; - break; - case ATOR: - pcode = LL_PCODE_LEGACY_ATOR; - break; - case BASIC_SHOT: - pcode = LL_PCODE_LEGACY_SHOT; - break; - case BIG_SHOT: - pcode = LL_PCODE_LEGACY_SHOT_BIG; - break; - case BIRD: - pcode = LL_PCODE_LEGACY_BIRD; - break; - case ROCK: - pcode = LL_PCODE_LEGACY_ROCK; - break; - case SMOKE: - pcode = LL_PCODE_LEGACY_SMOKE; - break; - case SPARK: - pcode = LL_PCODE_LEGACY_SPARK; - break; - */ - case PRIMITIVE_VOLUME: - pcode = LL_PCODE_VOLUME; - break; - case GRASS: - pcode = LL_PCODE_LEGACY_GRASS; - break; - case PART_SYS: - pcode = LL_PCODE_LEGACY_PART_SYS; - break; - case PLAYER: - pcode = LL_PCODE_LEGACY_AVATAR; - break; - case TREE: - pcode = LL_PCODE_LEGACY_TREE; - break; - case TREE_NEW: - pcode = LL_PCODE_TREE_NEW; - break; - default: - LL_WARNS() << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << LL_ENDL; - } - - return pcode; + // TODO: Should this default to something valid? + // Maybe volume? + LLPCode pcode = 0; + + switch (legacy) + { + /* + case BOX: + pcode = LL_PCODE_CUBE; + break; + case CYLINDER: + pcode = LL_PCODE_CYLINDER; + break; + case CONE: + pcode = LL_PCODE_CONE; + break; + case HALF_CONE: + pcode = LL_PCODE_CONE_HEMI; + break; + case HALF_CYLINDER: + pcode = LL_PCODE_CYLINDER_HEMI; + break; + case HALF_SPHERE: + pcode = LL_PCODE_SPHERE_HEMI; + break; + case PRISM: + pcode = LL_PCODE_PRISM; + break; + case PYRAMID: + pcode = LL_PCODE_PYRAMID; + break; + case SPHERE: + pcode = LL_PCODE_SPHERE; + break; + case TETRAHEDRON: + pcode = LL_PCODE_TETRAHEDRON; + break; + case DEMON: + pcode = LL_PCODE_LEGACY_DEMON; + break; + case LSL_TEST: + pcode = LL_PCODE_LEGACY_LSL_TEST; + break; + case ORACLE: + pcode = LL_PCODE_LEGACY_ORACLE; + break; + case TEXTBUBBLE: + pcode = LL_PCODE_LEGACY_TEXT_BUBBLE; + break; + case ATOR: + pcode = LL_PCODE_LEGACY_ATOR; + break; + case BASIC_SHOT: + pcode = LL_PCODE_LEGACY_SHOT; + break; + case BIG_SHOT: + pcode = LL_PCODE_LEGACY_SHOT_BIG; + break; + case BIRD: + pcode = LL_PCODE_LEGACY_BIRD; + break; + case ROCK: + pcode = LL_PCODE_LEGACY_ROCK; + break; + case SMOKE: + pcode = LL_PCODE_LEGACY_SMOKE; + break; + case SPARK: + pcode = LL_PCODE_LEGACY_SPARK; + break; + */ + case PRIMITIVE_VOLUME: + pcode = LL_PCODE_VOLUME; + break; + case GRASS: + pcode = LL_PCODE_LEGACY_GRASS; + break; + case PART_SYS: + pcode = LL_PCODE_LEGACY_PART_SYS; + break; + case PLAYER: + pcode = LL_PCODE_LEGACY_AVATAR; + break; + case TREE: + pcode = LL_PCODE_LEGACY_TREE; + break; + case TREE_NEW: + pcode = LL_PCODE_TREE_NEW; + break; + default: + LL_WARNS() << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << LL_ENDL; + } + + return pcode; } U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode) { - U8 legacy; - switch (pcode) - { + U8 legacy; + switch (pcode) + { /* - case LL_PCODE_CUBE: - legacy = BOX; - break; - case LL_PCODE_CYLINDER: - legacy = CYLINDER; - break; - case LL_PCODE_CONE: - legacy = CONE; - break; - case LL_PCODE_CONE_HEMI: - legacy = HALF_CONE; - break; - case LL_PCODE_CYLINDER_HEMI: - legacy = HALF_CYLINDER; - break; - case LL_PCODE_SPHERE_HEMI: - legacy = HALF_SPHERE; - break; - case LL_PCODE_PRISM: - legacy = PRISM; - break; - case LL_PCODE_PYRAMID: - legacy = PYRAMID; - break; - case LL_PCODE_SPHERE: - legacy = SPHERE; - break; - case LL_PCODE_TETRAHEDRON: - legacy = TETRAHEDRON; - break; - case LL_PCODE_LEGACY_ATOR: - legacy = ATOR; - break; - case LL_PCODE_LEGACY_SHOT: - legacy = BASIC_SHOT; - break; - case LL_PCODE_LEGACY_SHOT_BIG: - legacy = BIG_SHOT; - break; - case LL_PCODE_LEGACY_BIRD: - legacy = BIRD; - break; - case LL_PCODE_LEGACY_DEMON: - legacy = DEMON; - break; - case LL_PCODE_LEGACY_LSL_TEST: - legacy = LSL_TEST; - break; - case LL_PCODE_LEGACY_ORACLE: - legacy = ORACLE; - break; - case LL_PCODE_LEGACY_ROCK: - legacy = ROCK; - break; - case LL_PCODE_LEGACY_TEXT_BUBBLE: - legacy = TEXTBUBBLE; - break; - case LL_PCODE_LEGACY_SMOKE: - legacy = SMOKE; - break; - case LL_PCODE_LEGACY_SPARK: - legacy = SPARK; - break; + case LL_PCODE_CUBE: + legacy = BOX; + break; + case LL_PCODE_CYLINDER: + legacy = CYLINDER; + break; + case LL_PCODE_CONE: + legacy = CONE; + break; + case LL_PCODE_CONE_HEMI: + legacy = HALF_CONE; + break; + case LL_PCODE_CYLINDER_HEMI: + legacy = HALF_CYLINDER; + break; + case LL_PCODE_SPHERE_HEMI: + legacy = HALF_SPHERE; + break; + case LL_PCODE_PRISM: + legacy = PRISM; + break; + case LL_PCODE_PYRAMID: + legacy = PYRAMID; + break; + case LL_PCODE_SPHERE: + legacy = SPHERE; + break; + case LL_PCODE_TETRAHEDRON: + legacy = TETRAHEDRON; + break; + case LL_PCODE_LEGACY_ATOR: + legacy = ATOR; + break; + case LL_PCODE_LEGACY_SHOT: + legacy = BASIC_SHOT; + break; + case LL_PCODE_LEGACY_SHOT_BIG: + legacy = BIG_SHOT; + break; + case LL_PCODE_LEGACY_BIRD: + legacy = BIRD; + break; + case LL_PCODE_LEGACY_DEMON: + legacy = DEMON; + break; + case LL_PCODE_LEGACY_LSL_TEST: + legacy = LSL_TEST; + break; + case LL_PCODE_LEGACY_ORACLE: + legacy = ORACLE; + break; + case LL_PCODE_LEGACY_ROCK: + legacy = ROCK; + break; + case LL_PCODE_LEGACY_TEXT_BUBBLE: + legacy = TEXTBUBBLE; + break; + case LL_PCODE_LEGACY_SMOKE: + legacy = SMOKE; + break; + case LL_PCODE_LEGACY_SPARK: + legacy = SPARK; + break; */ - case LL_PCODE_VOLUME: - legacy = PRIMITIVE_VOLUME; - break; - case LL_PCODE_LEGACY_GRASS: - legacy = GRASS; - break; - case LL_PCODE_LEGACY_PART_SYS: - legacy = PART_SYS; - break; - case LL_PCODE_LEGACY_AVATAR: - legacy = PLAYER; - break; - case LL_PCODE_LEGACY_TREE: - legacy = TREE; - break; - case LL_PCODE_TREE_NEW: - legacy = TREE_NEW; - break; - default: - LL_WARNS() << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << LL_ENDL; - return 0; - } - return legacy; + case LL_PCODE_VOLUME: + legacy = PRIMITIVE_VOLUME; + break; + case LL_PCODE_LEGACY_GRASS: + legacy = GRASS; + break; + case LL_PCODE_LEGACY_PART_SYS: + legacy = PART_SYS; + break; + case LL_PCODE_LEGACY_AVATAR: + legacy = PLAYER; + break; + case LL_PCODE_LEGACY_TREE: + legacy = TREE; + break; + case LL_PCODE_TREE_NEW: + legacy = TREE_NEW; + break; + default: + LL_WARNS() << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << LL_ENDL; + return 0; + } + return legacy; } @@ -632,491 +632,491 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode) // Don't crash or LL_ERRS() here! This function is used for debug strings. std::string LLPrimitive::pCodeToString(const LLPCode pcode) { - std::string pcode_string; - - U8 base_code = pcode & LL_PCODE_BASE_MASK; - if (!pcode) - { - pcode_string = "null"; - } - else if ((base_code) == LL_PCODE_LEGACY) - { - // It's a legacy object - switch (pcode) - { - case LL_PCODE_LEGACY_GRASS: - pcode_string = "grass"; - break; - case LL_PCODE_LEGACY_PART_SYS: - pcode_string = "particle system"; - break; - case LL_PCODE_LEGACY_AVATAR: - pcode_string = "avatar"; - break; - case LL_PCODE_LEGACY_TEXT_BUBBLE: - pcode_string = "text bubble"; - break; - case LL_PCODE_LEGACY_TREE: - pcode_string = "tree"; - break; - case LL_PCODE_TREE_NEW: - pcode_string = "tree_new"; - break; - default: - pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode); - } - } - else - { - std::string shape; - std::string mask; - if (base_code == LL_PCODE_CUBE) - { - shape = "cube"; - } - else if (base_code == LL_PCODE_CYLINDER) - { - shape = "cylinder"; - } - else if (base_code == LL_PCODE_CONE) - { - shape = "cone"; - } - else if (base_code == LL_PCODE_PRISM) - { - shape = "prism"; - } - else if (base_code == LL_PCODE_PYRAMID) - { - shape = "pyramid"; - } - else if (base_code == LL_PCODE_SPHERE) - { - shape = "sphere"; - } - else if (base_code == LL_PCODE_TETRAHEDRON) - { - shape = "tetrahedron"; - } - else if (base_code == LL_PCODE_VOLUME) - { - shape = "volume"; - } - else if (base_code == LL_PCODE_APP) - { - shape = "app"; - } - else - { - LL_WARNS() << "Unknown base mask for pcode: " << base_code << LL_ENDL; - } - - U8 mask_code = pcode & (~LL_PCODE_BASE_MASK); - if (base_code == LL_PCODE_APP) - { - mask = llformat( "%x", mask_code); - } - else if (mask_code & LL_PCODE_HEMI_MASK) - { - mask = "hemi"; - } - else - { - mask = llformat( "%x", mask_code); - } - - if (mask[0]) - { - pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str()); - } - else - { - pcode_string = llformat( "%s", shape.c_str()); - } - } - - return pcode_string; + std::string pcode_string; + + U8 base_code = pcode & LL_PCODE_BASE_MASK; + if (!pcode) + { + pcode_string = "null"; + } + else if ((base_code) == LL_PCODE_LEGACY) + { + // It's a legacy object + switch (pcode) + { + case LL_PCODE_LEGACY_GRASS: + pcode_string = "grass"; + break; + case LL_PCODE_LEGACY_PART_SYS: + pcode_string = "particle system"; + break; + case LL_PCODE_LEGACY_AVATAR: + pcode_string = "avatar"; + break; + case LL_PCODE_LEGACY_TEXT_BUBBLE: + pcode_string = "text bubble"; + break; + case LL_PCODE_LEGACY_TREE: + pcode_string = "tree"; + break; + case LL_PCODE_TREE_NEW: + pcode_string = "tree_new"; + break; + default: + pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode); + } + } + else + { + std::string shape; + std::string mask; + if (base_code == LL_PCODE_CUBE) + { + shape = "cube"; + } + else if (base_code == LL_PCODE_CYLINDER) + { + shape = "cylinder"; + } + else if (base_code == LL_PCODE_CONE) + { + shape = "cone"; + } + else if (base_code == LL_PCODE_PRISM) + { + shape = "prism"; + } + else if (base_code == LL_PCODE_PYRAMID) + { + shape = "pyramid"; + } + else if (base_code == LL_PCODE_SPHERE) + { + shape = "sphere"; + } + else if (base_code == LL_PCODE_TETRAHEDRON) + { + shape = "tetrahedron"; + } + else if (base_code == LL_PCODE_VOLUME) + { + shape = "volume"; + } + else if (base_code == LL_PCODE_APP) + { + shape = "app"; + } + else + { + LL_WARNS() << "Unknown base mask for pcode: " << base_code << LL_ENDL; + } + + U8 mask_code = pcode & (~LL_PCODE_BASE_MASK); + if (base_code == LL_PCODE_APP) + { + mask = llformat( "%x", mask_code); + } + else if (mask_code & LL_PCODE_HEMI_MASK) + { + mask = "hemi"; + } + else + { + mask = llformat( "%x", mask_code); + } + + if (mask[0]) + { + pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str()); + } + else + { + pcode_string = llformat( "%s", shape.c_str()); + } + } + + return pcode_string; } void LLPrimitive::copyTEs(const LLPrimitive *primitivep) { - U32 i; - if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) - { - LL_WARNS() << "Primitives don't have same expected number of TE's" << LL_ENDL; - } - U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); - if (mTextureList.size() < getExpectedNumTEs()) - { - mTextureList.setSize(getExpectedNumTEs()); - } - for (i = 0; i < num_tes; i++) - { - mTextureList.copyTexture(i, *(primitivep->getTE(i))); - } -} - -S32 face_index_from_id(LLFaceID face_ID, const std::vector& faceArray) -{ - S32 i; - for (i = 0; i < (S32)faceArray.size(); i++) - { - if (faceArray[i].mFaceID == face_ID) - { - return i; - } - } - return -1; + U32 i; + if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) + { + LL_WARNS() << "Primitives don't have same expected number of TE's" << LL_ENDL; + } + U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); + if (mTextureList.size() < getExpectedNumTEs()) + { + mTextureList.setSize(getExpectedNumTEs()); + } + for (i = 0; i < num_tes; i++) + { + mTextureList.copyTexture(i, *(primitivep->getTE(i))); + } +} + +S32 face_index_from_id(LLFaceID face_ID, const std::vector& faceArray) +{ + S32 i; + for (i = 0; i < (S32)faceArray.size(); i++) + { + if (faceArray[i].mFaceID == face_ID) + { + return i; + } + } + return -1; } BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume) { - if (NO_LOD == detail) - { - // build the new object - setChanged(GEOMETRY); - sVolumeManager->unrefVolume(mVolumep); - mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE); - setNumTEs(mVolumep->getNumFaces()); - return FALSE; - } - - LLVolume *volumep; - if (unique_volume) - { - F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); - if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail())) - { - return FALSE; - } - volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE); - } - else - { - if (mVolumep.notNull()) - { - F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); - if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail())) - { - return FALSE; - } - } - - volumep = sVolumeManager->refVolume(volume_params, detail); - if (volumep == mVolumep) - { - sVolumeManager->unrefVolume( volumep ); // LLVolumeMgr::refVolume() creates a reference, but we don't need a second one. - return TRUE; - } - } - - setChanged(GEOMETRY); - - - if (!mVolumep) - { - mVolumep = volumep; - //mFaceMask = mVolumep->generateFaceMask(); - setNumTEs(mVolumep->getNumFaces()); - return TRUE; - } - -#if 0 - // #if 0'd out by davep - // this is a lot of cruft to set texture entry values that just stay the same for LOD switch - // or immediately get overridden by an object update message, also crashes occasionally - U32 old_face_mask = mVolumep->mFaceMask; - - S32 face_bit = 0; - S32 cur_mask = 0; - - // Grab copies of the old faces from the original shape, ordered by type. - // We will use these to figure out what old texture info gets mapped to new - // faces in the new shape. - std::vector old_faces; - for (S32 face = 0; face < mVolumep->getNumFaces(); face++) - { - old_faces.push_back(mVolumep->getProfile().mFaces[face]); - } - - // Copy the old texture info off to the side, but not in the order in which - // they live in the mTextureList, rather in order of ther "face id" which - // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. - // - // Hence, some elements of old_tes::mEntryList will be invalid. It is - // initialized to a size of 9 (max number of possible faces on a volume?) - // and only the ones with valid types are filled in. - LLPrimTextureList old_tes; - old_tes.setSize(9); - for (face_bit = 0; face_bit < 9; face_bit++) - { - cur_mask = 0x1 << face_bit; - if (old_face_mask & cur_mask) - { - S32 te_index = face_index_from_id(cur_mask, old_faces); - old_tes.copyTexture(face_bit, *(getTE(te_index))); - //LL_INFOS() << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << LL_ENDL; - } - } - - - // build the new object - sVolumeManager->unrefVolume(mVolumep); - mVolumep = volumep; - - U32 new_face_mask = mVolumep->mFaceMask; - S32 i; - - if (old_face_mask == new_face_mask) - { - // nothing to do - return TRUE; - } - - if (mVolumep->getNumFaces() == 0 && new_face_mask != 0) - { - LL_WARNS() << "Object with 0 faces found...INCORRECT!" << LL_ENDL; - setNumTEs(mVolumep->getNumFaces()); - return TRUE; - } - - // initialize face_mapping - S32 face_mapping[9]; - for (face_bit = 0; face_bit < 9; face_bit++) - { - face_mapping[face_bit] = face_bit; - } - - // The new shape may have more faces than the original, but we can't just - // add them to the end -- the ordering matters and it may be that we must - // insert the new faces in the middle of the list. When we add a face it - // will pick up the texture/color info of one of the old faces an so we - // now figure out which old face info gets mapped to each new face, and - // store in the face_mapping lookup table. - for (face_bit = 0; face_bit < 9; face_bit++) - { - cur_mask = 0x1 << face_bit; - if (!(new_face_mask & cur_mask)) - { - // Face doesn't exist in new map. - face_mapping[face_bit] = -1; - continue; - } - else if (old_face_mask & cur_mask) - { - // Face exists in new and old map. - face_mapping[face_bit] = face_bit; - continue; - } - - // OK, how we've got a mismatch, where we have to fill a new face with one from - // the old face. - if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) - { - // It's a top/bottom/hollow interior face. - if (old_face_mask & LL_FACE_PATH_END) - { - face_mapping[face_bit] = 1; - continue; - } - else - { - S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; - for (i = 0; i < 4; i++) - { - if (old_face_mask & cur_outer_mask) - { - face_mapping[face_bit] = 5 + i; - break; - } - cur_outer_mask <<= 1; - } - if (i == 4) - { - LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; - } - continue; - } - } - - if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) - { - // A cut slice. Use the hollow interior if we have it. - if (old_face_mask & LL_FACE_INNER_SIDE) - { - face_mapping[face_bit] = 2; - continue; - } - - // No interior, use the bottom face. - // Could figure out which of the outer faces was nearest, but that would be harder. - if (old_face_mask & LL_FACE_PATH_END) - { - face_mapping[face_bit] = 1; - continue; - } - else - { - S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; - for (i = 0; i < 4; i++) - { - if (old_face_mask & cur_outer_mask) - { - face_mapping[face_bit] = 5 + i; - break; - } - cur_outer_mask <<= 1; - } - if (i == 4) - { - LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; - } - continue; - } - } - - // OK, the face that's missing is an outer face... - // Pull from the nearest adjacent outer face (there's always guaranteed to be one... - S32 cur_outer = face_bit - 5; - S32 min_dist = 5; - S32 min_outer_bit = -1; - S32 i; - for (i = 0; i < 4; i++) - { - if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) - { - S32 dist = abs(i - cur_outer); - if (dist < min_dist) - { - min_dist = dist; - min_outer_bit = i + 5; - } - } - } - if (-1 == min_outer_bit) - { - LL_INFOS() << (LLVolume *)mVolumep << LL_ENDL; - LL_WARNS() << "Bad! No outer faces, impossible!" << LL_ENDL; - } - face_mapping[face_bit] = min_outer_bit; - } - - - setNumTEs(mVolumep->getNumFaces()); - for (face_bit = 0; face_bit < 9; face_bit++) - { - // For each possible face type on the new shape we check to see if that - // face exists and if it does we create a texture entry that is a copy - // of one of the originals. Since the originals might not have a - // matching face, we use the face_mapping lookup table to figure out - // which face information to copy. - cur_mask = 0x1 << face_bit; - if (new_face_mask & cur_mask) - { - if (-1 == face_mapping[face_bit]) - { - LL_WARNS() << "No mapping from old face to new face!" << LL_ENDL; - } - - S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); - setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); - } - } + if (NO_LOD == detail) + { + // build the new object + setChanged(GEOMETRY); + sVolumeManager->unrefVolume(mVolumep); + mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE); + setNumTEs(mVolumep->getNumFaces()); + return FALSE; + } + + LLVolume *volumep; + if (unique_volume) + { + F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); + if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail())) + { + return FALSE; + } + volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE); + } + else + { + if (mVolumep.notNull()) + { + F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); + if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail())) + { + return FALSE; + } + } + + volumep = sVolumeManager->refVolume(volume_params, detail); + if (volumep == mVolumep) + { + sVolumeManager->unrefVolume( volumep ); // LLVolumeMgr::refVolume() creates a reference, but we don't need a second one. + return TRUE; + } + } + + setChanged(GEOMETRY); + + + if (!mVolumep) + { + mVolumep = volumep; + //mFaceMask = mVolumep->generateFaceMask(); + setNumTEs(mVolumep->getNumFaces()); + return TRUE; + } + +#if 0 + // #if 0'd out by davep + // this is a lot of cruft to set texture entry values that just stay the same for LOD switch + // or immediately get overridden by an object update message, also crashes occasionally + U32 old_face_mask = mVolumep->mFaceMask; + + S32 face_bit = 0; + S32 cur_mask = 0; + + // Grab copies of the old faces from the original shape, ordered by type. + // We will use these to figure out what old texture info gets mapped to new + // faces in the new shape. + std::vector old_faces; + for (S32 face = 0; face < mVolumep->getNumFaces(); face++) + { + old_faces.push_back(mVolumep->getProfile().mFaces[face]); + } + + // Copy the old texture info off to the side, but not in the order in which + // they live in the mTextureList, rather in order of ther "face id" which + // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. + // + // Hence, some elements of old_tes::mEntryList will be invalid. It is + // initialized to a size of 9 (max number of possible faces on a volume?) + // and only the ones with valid types are filled in. + LLPrimTextureList old_tes; + old_tes.setSize(9); + for (face_bit = 0; face_bit < 9; face_bit++) + { + cur_mask = 0x1 << face_bit; + if (old_face_mask & cur_mask) + { + S32 te_index = face_index_from_id(cur_mask, old_faces); + old_tes.copyTexture(face_bit, *(getTE(te_index))); + //LL_INFOS() << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << LL_ENDL; + } + } + + + // build the new object + sVolumeManager->unrefVolume(mVolumep); + mVolumep = volumep; + + U32 new_face_mask = mVolumep->mFaceMask; + S32 i; + + if (old_face_mask == new_face_mask) + { + // nothing to do + return TRUE; + } + + if (mVolumep->getNumFaces() == 0 && new_face_mask != 0) + { + LL_WARNS() << "Object with 0 faces found...INCORRECT!" << LL_ENDL; + setNumTEs(mVolumep->getNumFaces()); + return TRUE; + } + + // initialize face_mapping + S32 face_mapping[9]; + for (face_bit = 0; face_bit < 9; face_bit++) + { + face_mapping[face_bit] = face_bit; + } + + // The new shape may have more faces than the original, but we can't just + // add them to the end -- the ordering matters and it may be that we must + // insert the new faces in the middle of the list. When we add a face it + // will pick up the texture/color info of one of the old faces an so we + // now figure out which old face info gets mapped to each new face, and + // store in the face_mapping lookup table. + for (face_bit = 0; face_bit < 9; face_bit++) + { + cur_mask = 0x1 << face_bit; + if (!(new_face_mask & cur_mask)) + { + // Face doesn't exist in new map. + face_mapping[face_bit] = -1; + continue; + } + else if (old_face_mask & cur_mask) + { + // Face exists in new and old map. + face_mapping[face_bit] = face_bit; + continue; + } + + // OK, how we've got a mismatch, where we have to fill a new face with one from + // the old face. + if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) + { + // It's a top/bottom/hollow interior face. + if (old_face_mask & LL_FACE_PATH_END) + { + face_mapping[face_bit] = 1; + continue; + } + else + { + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; + } + continue; + } + } + + if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) + { + // A cut slice. Use the hollow interior if we have it. + if (old_face_mask & LL_FACE_INNER_SIDE) + { + face_mapping[face_bit] = 2; + continue; + } + + // No interior, use the bottom face. + // Could figure out which of the outer faces was nearest, but that would be harder. + if (old_face_mask & LL_FACE_PATH_END) + { + face_mapping[face_bit] = 1; + continue; + } + else + { + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; + } + continue; + } + } + + // OK, the face that's missing is an outer face... + // Pull from the nearest adjacent outer face (there's always guaranteed to be one... + S32 cur_outer = face_bit - 5; + S32 min_dist = 5; + S32 min_outer_bit = -1; + S32 i; + for (i = 0; i < 4; i++) + { + if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) + { + S32 dist = abs(i - cur_outer); + if (dist < min_dist) + { + min_dist = dist; + min_outer_bit = i + 5; + } + } + } + if (-1 == min_outer_bit) + { + LL_INFOS() << (LLVolume *)mVolumep << LL_ENDL; + LL_WARNS() << "Bad! No outer faces, impossible!" << LL_ENDL; + } + face_mapping[face_bit] = min_outer_bit; + } + + + setNumTEs(mVolumep->getNumFaces()); + for (face_bit = 0; face_bit < 9; face_bit++) + { + // For each possible face type on the new shape we check to see if that + // face exists and if it does we create a texture entry that is a copy + // of one of the originals. Since the originals might not have a + // matching face, we use the face_mapping lookup table to figure out + // which face information to copy. + cur_mask = 0x1 << face_bit; + if (new_face_mask & cur_mask) + { + if (-1 == face_mapping[face_bit]) + { + LL_WARNS() << "No mapping from old face to new face!" << LL_ENDL; + } + + S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); + setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); + } + } #else - // build the new object - sVolumeManager->unrefVolume(mVolumep); - mVolumep = volumep; + // build the new object + sVolumeManager->unrefVolume(mVolumep); + mVolumep = volumep; - setNumTEs(mVolumep->getNumFaces()); + setNumTEs(mVolumep->getNumFaces()); #endif - return TRUE; + return TRUE; } BOOL LLPrimitive::setMaterial(U8 material) { - if (material != mMaterial) - { - mMaterial = material; - return TRUE; - } - else - { - return FALSE; - } + if (material != mMaterial) + { + mMaterial = material; + return TRUE; + } + else + { + return FALSE; + } } S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const { - S32 face_index; - S32 i; - U64 exception_faces; - U8 *start_loc = cur_ptr; - - htolememcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size); - cur_ptr += data_size; - - for (face_index = last_face_index-1; face_index >= 0; face_index--) - { - BOOL already_sent = FALSE; - for (i = face_index+1; i <= last_face_index; i++) - { - if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size)) - { - already_sent = TRUE; - break; - } - } - - if (!already_sent) - { - exception_faces = 0; - for (i = face_index; i >= 0; i--) - { - if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size)) - { - exception_faces |= ((U64)1 << i); - } - } - - //assign exception faces to cur_ptr - if (exception_faces >= ((U64)0x1 << 7)) - { - if (exception_faces >= ((U64)0x1 << 14)) - { - if (exception_faces >= ((U64)0x1 << 21)) - { - if (exception_faces >= ((U64)0x1 << 28)) - { - if (exception_faces >= ((U64)0x1 << 35)) - { - if (exception_faces >= ((U64)0x1 << 42)) - { - if (exception_faces >= ((U64)0x1 << 49)) - { - *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80); - } - *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80); - } - - - *cur_ptr++ = (U8)(exception_faces & 0x7F); - - htolememcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size); - cur_ptr += data_size; - } - } - return (S32)(cur_ptr - start_loc); + S32 face_index; + S32 i; + U64 exception_faces; + U8 *start_loc = cur_ptr; + + htolememcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size); + cur_ptr += data_size; + + for (face_index = last_face_index-1; face_index >= 0; face_index--) + { + BOOL already_sent = FALSE; + for (i = face_index+1; i <= last_face_index; i++) + { + if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size)) + { + already_sent = TRUE; + break; + } + } + + if (!already_sent) + { + exception_faces = 0; + for (i = face_index; i >= 0; i--) + { + if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size)) + { + exception_faces |= ((U64)1 << i); + } + } + + //assign exception faces to cur_ptr + if (exception_faces >= ((U64)0x1 << 7)) + { + if (exception_faces >= ((U64)0x1 << 14)) + { + if (exception_faces >= ((U64)0x1 << 21)) + { + if (exception_faces >= ((U64)0x1 << 28)) + { + if (exception_faces >= ((U64)0x1 << 35)) + { + if (exception_faces >= ((U64)0x1 << 42)) + { + if (exception_faces >= ((U64)0x1 << 49)) + { + *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80); + } + + + *cur_ptr++ = (U8)(exception_faces & 0x7F); + + htolememcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size); + cur_ptr += data_size; + } + } + return (S32)(cur_ptr - start_loc); } namespace @@ -1136,7 +1136,7 @@ namespace return false; } - // Extract the default value and fill the array. + // Extract the default value and fill the array. htolememcpy(dest, source, type, size); source += size; for (S32 idx = 1; idx < dest_count; ++idx) @@ -1149,7 +1149,7 @@ namespace U64 index_flags(0); U8 sbit(0); - // Unpack the variable length bitfield. Each bit represents whether the following + // Unpack the variable length bitfield. Each bit represents whether the following // value will be placed at the corresponding array index. do { @@ -1203,194 +1203,194 @@ namespace // Includes information about image ID, color, scale S,T, offset S,T and rotation BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const { - const U32 MAX_TES = 45; - - U8 image_ids[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; + const U32 MAX_TES = 45; + + U8 image_ids[MAX_TES*16]; + U8 colors[MAX_TES*4]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; - U8 material_data[MAX_TES*16]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - S32 last_face_index = llmin((U32) getNumTEs(), MAX_TES) - 1; - - if (last_face_index > -1) - { - // ...if we hit the front, send one image id - S8 face_index; - LLColor4U coloru; - for (face_index = 0; face_index <= last_face_index; face_index++) - { - // Directly sending image_ids is not safe! - memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ - - // Cast LLColor4 to LLColor4U - coloru.setVec( getTE(face_index)->getColor() ); - - // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) - // as all zeros. However, the subtraction and addition must be done in unsigned - // byte space, not in float space, otherwise off-by-one errors occur. JC - colors[4*face_index] = 255 - coloru.mV[0]; - colors[4*face_index + 1] = 255 - coloru.mV[1]; - colors[4*face_index + 2] = 255 - coloru.mV[2]; - colors[4*face_index + 3] = 255 - coloru.mV[3]; - - const LLTextureEntry* te = getTE(face_index); - scale_s[face_index] = (F32) te->mScaleS; - scale_t[face_index] = (F32) te->mScaleT; - offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; - offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; - image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); - bump[face_index] = te->getBumpShinyFullbright(); - media_flags[face_index] = te->getMediaTexGen(); - glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); - - // Directly sending material_ids is not safe! - memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ - } - - cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); - } - mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer)); - - return FALSE; + U8 material_data[MAX_TES*16]; + + const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; + U8 *cur_ptr = packed_buffer; + + S32 last_face_index = llmin((U32) getNumTEs(), MAX_TES) - 1; + + if (last_face_index > -1) + { + // ...if we hit the front, send one image id + S8 face_index; + LLColor4U coloru; + for (face_index = 0; face_index <= last_face_index; face_index++) + { + // Directly sending image_ids is not safe! + memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ + + // Cast LLColor4 to LLColor4U + coloru.setVec( getTE(face_index)->getColor() ); + + // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) + // as all zeros. However, the subtraction and addition must be done in unsigned + // byte space, not in float space, otherwise off-by-one errors occur. JC + colors[4*face_index] = 255 - coloru.mV[0]; + colors[4*face_index + 1] = 255 - coloru.mV[1]; + colors[4*face_index + 2] = 255 - coloru.mV[2]; + colors[4*face_index + 3] = 255 - coloru.mV[3]; + + const LLTextureEntry* te = getTE(face_index); + scale_s[face_index] = (F32) te->mScaleS; + scale_t[face_index] = (F32) te->mScaleT; + offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; + offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; + image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); + bump[face_index] = te->getBumpShinyFullbright(); + media_flags[face_index] = te->getMediaTexGen(); + glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ + } + + cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); + } + mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer)); + + return FALSE; } BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const { - const U32 MAX_TES = 45; - - U8 image_ids[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; + const U32 MAX_TES = 45; + + U8 image_ids[MAX_TES*16]; + U8 colors[MAX_TES*4]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; - U8 material_data[MAX_TES*16]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - S32 last_face_index = getNumTEs() - 1; - - if (last_face_index > -1) - { - // ...if we hit the front, send one image id - S8 face_index; - LLColor4U coloru; - for (face_index = 0; face_index <= last_face_index; face_index++) - { - // Directly sending image_ids is not safe! - memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ - - // Cast LLColor4 to LLColor4U - coloru.setVec( getTE(face_index)->getColor() ); - - // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) - // as all zeros. However, the subtraction and addition must be done in unsigned - // byte space, not in float space, otherwise off-by-one errors occur. JC - colors[4*face_index] = 255 - coloru.mV[0]; - colors[4*face_index + 1] = 255 - coloru.mV[1]; - colors[4*face_index + 2] = 255 - coloru.mV[2]; - colors[4*face_index + 3] = 255 - coloru.mV[3]; - - const LLTextureEntry* te = getTE(face_index); - scale_s[face_index] = (F32) te->mScaleS; - scale_t[face_index] = (F32) te->mScaleT; - offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; - offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; - image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); - bump[face_index] = te->getBumpShinyFullbright(); - media_flags[face_index] = te->getMediaTexGen(); + U8 material_data[MAX_TES*16]; + + const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; + U8 *cur_ptr = packed_buffer; + + S32 last_face_index = getNumTEs() - 1; + + if (last_face_index > -1) + { + // ...if we hit the front, send one image id + S8 face_index; + LLColor4U coloru; + for (face_index = 0; face_index <= last_face_index; face_index++) + { + // Directly sending image_ids is not safe! + memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ + + // Cast LLColor4 to LLColor4U + coloru.setVec( getTE(face_index)->getColor() ); + + // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) + // as all zeros. However, the subtraction and addition must be done in unsigned + // byte space, not in float space, otherwise off-by-one errors occur. JC + colors[4*face_index] = 255 - coloru.mV[0]; + colors[4*face_index + 1] = 255 - coloru.mV[1]; + colors[4*face_index + 2] = 255 - coloru.mV[2]; + colors[4*face_index + 3] = 255 - coloru.mV[3]; + + const LLTextureEntry* te = getTE(face_index); + scale_s[face_index] = (F32) te->mScaleS; + scale_t[face_index] = (F32) te->mScaleT; + offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; + offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; + image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); + bump[face_index] = te->getBumpShinyFullbright(); + media_flags[face_index] = te->getMediaTexGen(); glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); - // Directly sending material_ids is not safe! - memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ - } - - cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); - *cur_ptr++ = 0; - cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); - } - - dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry"); - return FALSE; + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ + } + + cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); + } + + dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry"); + return FALSE; } S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { - S32 retval = 0; + S32 retval = 0; // temp buffer for material ID processing - // data will end up in tec.material_id[] + // data will end up in tec.material_id[] material_id_type material_data[LLTEContents::MAX_TES]; - if (block_num < 0) - { - tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); - } - else - { - tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); - } - - if (tec.size == 0) - { - tec.face_count = 0; - return retval; - } + if (block_num < 0) + { + tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); + } + else + { + tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); + } + + if (tec.size == 0) + { + tec.face_count = 0; + return retval; + } else if (tec.size >= LLTEContents::MAX_TE_BUFFER) { LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL; @@ -1400,14 +1400,14 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name // if block_num < 0 ask for block 0 mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, std::max(block_num, 0), LLTEContents::MAX_TE_BUFFER - 1); - // The last field is not zero terminated. + // The last field is not zero terminated. // Rather than special case the upack functions. Just make it 0x00 terminated. tec.packed_buffer[tec.size] = 0x00; ++tec.size; - tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); + tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); - U8 *cur_ptr = tec.packed_buffer; + U8 *cur_ptr = tec.packed_buffer; LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffere sized: " << tec.size << LL_ENDL; U8 *buffer_end = tec.packed_buffer + tec.size; @@ -1426,68 +1426,68 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name return 0; } - if (cur_ptr >= buffer_end || !unpack_TEField(material_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID)) - { - memset((void*)material_data, 0, sizeof(material_data)); - } - - for (U32 i = 0; i < tec.face_count; i++) - { - tec.material_ids[i].set(&(material_data[i])); - } - - retval = 1; - return retval; - } - + if (cur_ptr >= buffer_end || !unpack_TEField(material_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID)) + { + memset((void*)material_data, 0, sizeof(material_data)); + } + + for (U32 i = 0; i < tec.face_count; i++) + { + tec.material_ids[i].set(&(material_data[i])); + } + + retval = 1; + return retval; + } + S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) { - S32 retval = 0; - - LLColor4 color; - for (U32 i = 0; i < tec.face_count; i++) - { - LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; - retval |= setTETexture(i, req_id); - retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); - retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); - retval |= setTEBumpShinyFullbright(i, tec.bump[i]); - retval |= setTEMediaTexGen(i, tec.media_flags[i]); - retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); - retval |= setTEMaterialID(i, tec.material_ids[i]); - - // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) - // as all zeros. However, the subtraction and addition must be done in unsigned - // byte space, not in float space, otherwise off-by-one errors occur. JC - color.mV[VRED] = F32(255 - tec.colors[i].mV[VRED]) / 255.f; - color.mV[VGREEN] = F32(255 - tec.colors[i].mV[VGREEN]) / 255.f; - color.mV[VBLUE] = F32(255 - tec.colors[i].mV[VBLUE]) / 255.f; - color.mV[VALPHA] = F32(255 - tec.colors[i].mV[VALPHA]) / 255.f; - - retval |= setTEColor(i, color); - } - - return retval; + S32 retval = 0; + + LLColor4 color; + for (U32 i = 0; i < tec.face_count; i++) + { + LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; + retval |= setTETexture(i, req_id); + retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); + retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, tec.bump[i]); + retval |= setTEMediaTexGen(i, tec.media_flags[i]); + retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + retval |= setTEMaterialID(i, tec.material_ids[i]); + + // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) + // as all zeros. However, the subtraction and addition must be done in unsigned + // byte space, not in float space, otherwise off-by-one errors occur. JC + color.mV[VRED] = F32(255 - tec.colors[i].mV[VRED]) / 255.f; + color.mV[VGREEN] = F32(255 - tec.colors[i].mV[VGREEN]) / 255.f; + color.mV[VBLUE] = F32(255 - tec.colors[i].mV[VBLUE]) / 255.f; + color.mV[VALPHA] = F32(255 - tec.colors[i].mV[VALPHA]) / 255.f; + + retval |= setTEColor(i, color); + } + + return retval; } S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) { - LLTEContents tec; - S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); - if (!retval) - return retval; - return applyParsedTEMessage(tec); + LLTEContents tec; + S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); + if (!retval) + return retval; + return applyParsedTEMessage(tec); } S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { - // use a negative block_num to indicate a single-block read (a non-variable block) - S32 retval = 0; - const U32 MAX_TES = 45; + // use a negative block_num to indicate a single-block read (a non-variable block) + S32 retval = 0; + const U32 MAX_TES = 45; - // Avoid construction of 32 UUIDs per call - static LLMaterialID material_ids[MAX_TES]; + // Avoid construction of 32 UUIDs per call + static LLMaterialID material_ids[MAX_TES]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1504,7 +1504,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; material_id_type material_data[MAX_TES]; - + memset((void*)scale_s, 0, sizeof(scale_s)); memset((void*)scale_t, 0, sizeof(scale_t)); memset((void*)offset_s, 0, sizeof(offset_s)); @@ -1514,32 +1514,32 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) memset((void*)media_flags, 0, sizeof(media_flags)); memset((void*)glow, 0, sizeof(glow)); - S32 size; - U32 face_count = 0; + S32 size; + U32 face_count = 0; - if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry")) - { - retval = TEM_INVALID; - LL_WARNS() << "Bad texture entry block! Abort!" << LL_ENDL; - return retval; - } + if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry")) + { + retval = TEM_INVALID; + LL_WARNS() << "Bad texture entry block! Abort!" << LL_ENDL; + return retval; + } - if (size == 0) - { - return retval; - } + if (size == 0) + { + return retval; + } else if (size >= MAX_TE_BUFFER) { LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL; size = MAX_TE_BUFFER - 1; } - // The last field is not zero terminated. + // The last field is not zero terminated. // Rather than special case the upack functions. Just make it 0x00 terminated. packed_buffer[size] = 0x00; ++size; - face_count = llmin((U32) getNumTEs(), MAX_TES); - U32 i; + face_count = llmin((U32) getNumTEs(), MAX_TES); + U32 i; U8 *cur_ptr = packed_buffer; LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffer sized: " << size << LL_ENDL; @@ -1560,81 +1560,81 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) return 0; } - if (cur_ptr >= buffer_end || !unpack_TEField(material_data, face_count, cur_ptr, buffer_end, MVT_LLUUID)) - { - memset((void*)material_data, 0, sizeof(material_data)); - } - - for (i = 0; i < face_count; i++) - { - material_ids[i].set(&(material_data[i])); - } - - LLColor4 color; - for (i = 0; i < face_count; i++) - { - retval |= setTETexture(i, ((LLUUID*)image_data)[i]); - retval |= setTEScale(i, scale_s[i], scale_t[i]); - retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); - retval |= setTEBumpShinyFullbright(i, bump[i]); - retval |= setTEMediaTexGen(i, media_flags[i]); - retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); - retval |= setTEMaterialID(i, material_ids[i]); + if (cur_ptr >= buffer_end || !unpack_TEField(material_data, face_count, cur_ptr, buffer_end, MVT_LLUUID)) + { + memset((void*)material_data, 0, sizeof(material_data)); + } - // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) - // as all zeros. However, the subtraction and addition must be done in unsigned - // byte space, not in float space, otherwise off-by-one errors occur. JC - color.mV[VRED] = F32(255 - colors[i].mV[VRED]) / 255.f; - color.mV[VGREEN] = F32(255 - colors[i].mV[VGREEN]) / 255.f; - color.mV[VBLUE] = F32(255 - colors[i].mV[VBLUE]) / 255.f; - color.mV[VALPHA] = F32(255 - colors[i].mV[VALPHA]) / 255.f; + for (i = 0; i < face_count; i++) + { + material_ids[i].set(&(material_data[i])); + } - retval |= setTEColor(i, color); - } + LLColor4 color; + for (i = 0; i < face_count; i++) + { + retval |= setTETexture(i, ((LLUUID*)image_data)[i]); + retval |= setTEScale(i, scale_s[i], scale_t[i]); + retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, bump[i]); + retval |= setTEMediaTexGen(i, media_flags[i]); + retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); + retval |= setTEMaterialID(i, material_ids[i]); + + // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) + // as all zeros. However, the subtraction and addition must be done in unsigned + // byte space, not in float space, otherwise off-by-one errors occur. JC + color.mV[VRED] = F32(255 - colors[i].mV[VRED]) / 255.f; + color.mV[VGREEN] = F32(255 - colors[i].mV[VGREEN]) / 255.f; + color.mV[VBLUE] = F32(255 - colors[i].mV[VBLUE]) / 255.f; + color.mV[VALPHA] = F32(255 - colors[i].mV[VALPHA]) / 255.f; + + retval |= setTEColor(i, color); + } - return retval; + return retval; } -U8 LLPrimitive::getExpectedNumTEs() const +U8 LLPrimitive::getExpectedNumTEs() const { - U8 expected_face_count = 0; - if (mVolumep) - { - expected_face_count = mVolumep->getNumFaces(); - } - return expected_face_count; + U8 expected_face_count = 0; + if (mVolumep) + { + expected_face_count = mVolumep->getNumFaces(); + } + return expected_face_count; } void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list) { - mTextureList.copy(other_list); + mTextureList.copy(other_list); } void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) { - mTextureList.take(other_list); + mTextureList.take(other_list); } void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump) { - LLTextureEntry* te = getTE(index); - if(!te) - { - return; - } + LLTextureEntry* te = getTE(index); + if(!te) + { + return; + } - U8 old_bump = te->getBumpmap(); - if(old_bump > 0) - { - mNumBumpmapTEs--; - } - if((bump & TEM_BUMP_MASK) > 0) - { - mNumBumpmapTEs++; - } + U8 old_bump = te->getBumpmap(); + if(old_bump > 0) + { + mNumBumpmapTEs--; + } + if((bump & TEM_BUMP_MASK) > 0) + { + mNumBumpmapTEs++; + } - return; + return; } //============================================================================ @@ -1645,180 +1645,180 @@ void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump) // static bool LLPrimitive::getTESTAxes(const U8 face, U32* s_axis, U32* t_axis) { - if (face == 0) - { - *s_axis = VX; *t_axis = VY; - return true; - } - else if (face == 1) - { - *s_axis = VX; *t_axis = VZ; - return true; - } - else if (face == 2) - { - *s_axis = VY; *t_axis = VZ; - return true; - } - else if (face == 3) - { - *s_axis = VX; *t_axis = VZ; - return true; - } - else if (face == 4) - { - *s_axis = VY; *t_axis = VZ; - return true; - } - else if (face >= 5) - { - *s_axis = VX; *t_axis = VY; - return true; - } - else - { - // unknown face - return false; - } + if (face == 0) + { + *s_axis = VX; *t_axis = VY; + return true; + } + else if (face == 1) + { + *s_axis = VX; *t_axis = VZ; + return true; + } + else if (face == 2) + { + *s_axis = VY; *t_axis = VZ; + return true; + } + else if (face == 3) + { + *s_axis = VX; *t_axis = VZ; + return true; + } + else if (face == 4) + { + *s_axis = VY; *t_axis = VZ; + return true; + } + else if (face >= 5) + { + *s_axis = VX; *t_axis = VY; + return true; + } + else + { + // unknown face + return false; + } } //============================================================================ -//static +//static BOOL LLNetworkData::isValid(U16 param_type, U32 size) { - // ew - better mechanism needed - - switch(param_type) - { - case PARAMS_FLEXIBLE: - return (size == 16); - case PARAMS_LIGHT: - return (size == 16); - case PARAMS_SCULPT: - return (size == 17); - case PARAMS_LIGHT_IMAGE: - return (size == 28); + // ew - better mechanism needed + + switch(param_type) + { + case PARAMS_FLEXIBLE: + return (size == 16); + case PARAMS_LIGHT: + return (size == 16); + case PARAMS_SCULPT: + return (size == 17); + case PARAMS_LIGHT_IMAGE: + return (size == 28); case PARAMS_EXTENDED_MESH: return (size == 4); case PARAMS_RENDER_MATERIAL: return (size > 1); case PARAMS_REFLECTION_PROBE: return (size == 9); - } - - return FALSE; + } + + return FALSE; } //============================================================================ LLLightParams::LLLightParams() { - mColor.setToWhite(); - mRadius = 10.f; - mCutoff = 0.0f; - mFalloff = 0.75f; + mColor.setToWhite(); + mRadius = 10.f; + mCutoff = 0.0f; + mFalloff = 0.75f; - mType = PARAMS_LIGHT; + mType = PARAMS_LIGHT; } BOOL LLLightParams::pack(LLDataPacker &dp) const { - LLColor4U color4u(mColor); - dp.packColor4U(color4u, "color"); - dp.packF32(mRadius, "radius"); - dp.packF32(mCutoff, "cutoff"); - dp.packF32(mFalloff, "falloff"); - return TRUE; + LLColor4U color4u(mColor); + dp.packColor4U(color4u, "color"); + dp.packF32(mRadius, "radius"); + dp.packF32(mCutoff, "cutoff"); + dp.packF32(mFalloff, "falloff"); + return TRUE; } BOOL LLLightParams::unpack(LLDataPacker &dp) { - LLColor4U color; - dp.unpackColor4U(color, "color"); - setLinearColor(LLColor4(color)); + LLColor4U color; + dp.unpackColor4U(color, "color"); + setLinearColor(LLColor4(color)); - F32 radius; - dp.unpackF32(radius, "radius"); - setRadius(radius); + F32 radius; + dp.unpackF32(radius, "radius"); + setRadius(radius); - F32 cutoff; - dp.unpackF32(cutoff, "cutoff"); - setCutoff(cutoff); + F32 cutoff; + dp.unpackF32(cutoff, "cutoff"); + setCutoff(cutoff); - F32 falloff; - dp.unpackF32(falloff, "falloff"); - setFalloff(falloff); - - return TRUE; + F32 falloff; + dp.unpackF32(falloff, "falloff"); + setFalloff(falloff); + + return TRUE; } bool LLLightParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_LIGHT) - { - return false; - } - const LLLightParams *param = (const LLLightParams*)&data; - if (param->mColor != mColor || - param->mRadius != mRadius || - param->mCutoff != mCutoff || - param->mFalloff != mFalloff) - { - return false; - } - return true; + if (data.mType != PARAMS_LIGHT) + { + return false; + } + const LLLightParams *param = (const LLLightParams*)&data; + if (param->mColor != mColor || + param->mRadius != mRadius || + param->mCutoff != mCutoff || + param->mFalloff != mFalloff) + { + return false; + } + return true; } void LLLightParams::copy(const LLNetworkData& data) { - const LLLightParams *param = (LLLightParams*)&data; - mType = param->mType; - mColor = param->mColor; - mRadius = param->mRadius; - mCutoff = param->mCutoff; - mFalloff = param->mFalloff; + const LLLightParams *param = (LLLightParams*)&data; + mType = param->mType; + mColor = param->mColor; + mRadius = param->mRadius; + mCutoff = param->mCutoff; + mFalloff = param->mFalloff; } LLSD LLLightParams::asLLSD() const { - LLSD sd; - - sd["color"] = ll_sd_from_color4(getLinearColor()); - sd["radius"] = getRadius(); - sd["falloff"] = getFalloff(); - sd["cutoff"] = getCutoff(); - - return sd; + LLSD sd; + + sd["color"] = ll_sd_from_color4(getLinearColor()); + sd["radius"] = getRadius(); + sd["falloff"] = getFalloff(); + sd["cutoff"] = getCutoff(); + + return sd; } bool LLLightParams::fromLLSD(LLSD& sd) { - const char *w; - w = "color"; - if (sd.has(w)) - { - setLinearColor( ll_color4_from_sd(sd["color"]) ); - } else goto fail; - w = "radius"; - if (sd.has(w)) - { - setRadius( (F32)sd[w].asReal() ); - } else goto fail; - w = "falloff"; - if (sd.has(w)) - { - setFalloff( (F32)sd[w].asReal() ); - } else goto fail; - w = "cutoff"; - if (sd.has(w)) - { - setCutoff( (F32)sd[w].asReal() ); - } else goto fail; - - return true; + const char *w; + w = "color"; + if (sd.has(w)) + { + setLinearColor( ll_color4_from_sd(sd["color"]) ); + } else goto fail; + w = "radius"; + if (sd.has(w)) + { + setRadius( (F32)sd[w].asReal() ); + } else goto fail; + w = "falloff"; + if (sd.has(w)) + { + setFalloff( (F32)sd[w].asReal() ); + } else goto fail; + w = "cutoff"; + if (sd.has(w)) + { + setCutoff( (F32)sd[w].asReal() ); + } else goto fail; + + return true; fail: - return false; + return false; } //============================================================================ @@ -1832,39 +1832,39 @@ LLReflectionProbeParams::LLReflectionProbeParams() BOOL LLReflectionProbeParams::pack(LLDataPacker &dp) const { - dp.packF32(mAmbiance, "ambiance"); + dp.packF32(mAmbiance, "ambiance"); dp.packF32(mClipDistance, "clip_distance"); dp.packU8(mFlags, "flags"); - return TRUE; + return TRUE; } BOOL LLReflectionProbeParams::unpack(LLDataPacker &dp) { - F32 ambiance; + F32 ambiance; F32 clip_distance; - dp.unpackF32(ambiance, "ambiance"); - setAmbiance(ambiance); - + dp.unpackF32(ambiance, "ambiance"); + setAmbiance(ambiance); + dp.unpackF32(clip_distance, "clip_distance"); - setClipDistance(clip_distance); - + setClipDistance(clip_distance); + dp.unpackU8(mFlags, "flags"); - - return TRUE; + + return TRUE; } bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_REFLECTION_PROBE) - { - return false; - } - const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data; - if (param->mAmbiance != mAmbiance) - { - return false; - } + if (data.mType != PARAMS_REFLECTION_PROBE) + { + return false; + } + const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data; + if (param->mAmbiance != mAmbiance) + { + return false; + } if (param->mClipDistance != mClipDistance) { return false; @@ -1873,25 +1873,25 @@ bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const { return false; } - return true; + return true; } void LLReflectionProbeParams::copy(const LLNetworkData& data) { - const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data; - mType = param->mType; - mAmbiance = param->mAmbiance; + const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data; + mType = param->mType; + mAmbiance = param->mAmbiance; mClipDistance = param->mClipDistance; mFlags = param->mFlags; } LLSD LLReflectionProbeParams::asLLSD() const { - LLSD sd; - sd["ambiance"] = getAmbiance(); + LLSD sd; + sd["ambiance"] = getAmbiance(); sd["clip_distance"] = getClipDistance(); sd["flags"] = mFlags; - return sd; + return sd; } bool LLReflectionProbeParams::fromLLSD(LLSD& sd) @@ -1903,10 +1903,10 @@ bool LLReflectionProbeParams::fromLLSD(LLSD& sd) return false; } - setAmbiance((F32)sd["ambiance"].asReal()); + setAmbiance((F32)sd["ambiance"].asReal()); setClipDistance((F32)sd["clip_distance"].asReal()); mFlags = (U8) sd["flags"].asInteger(); - + return true; } @@ -1950,312 +1950,312 @@ void LLReflectionProbeParams::setIsMirror(bool is_mirror) //============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { - mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS; - mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY; - mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION; - mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY; - mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION; - //mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE; - //mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE; - mUserForce = LLVector3(0.f, 0.f, 0.f); + mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS; + mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY; + mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION; + mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY; + mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION; + //mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE; + //mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE; + mUserForce = LLVector3(0.f, 0.f, 0.f); - mType = PARAMS_FLEXIBLE; + mType = PARAMS_FLEXIBLE; } BOOL LLFlexibleObjectData::pack(LLDataPacker &dp) const { - // Custom, uber-svelte pack "softness" in upper bits of tension & drag - U8 bit1 = (mSimulateLOD & 2) << 6; - U8 bit2 = (mSimulateLOD & 1) << 7; - dp.packU8((U8)(mTension*10.01f) + bit1, "tension"); - dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag"); - dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity"); - dp.packU8((U8)(mWindSensitivity*10.01f), "wind"); - dp.packVector3(mUserForce, "userforce"); - return TRUE; + // Custom, uber-svelte pack "softness" in upper bits of tension & drag + U8 bit1 = (mSimulateLOD & 2) << 6; + U8 bit2 = (mSimulateLOD & 1) << 7; + dp.packU8((U8)(mTension*10.01f) + bit1, "tension"); + dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag"); + dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity"); + dp.packU8((U8)(mWindSensitivity*10.01f), "wind"); + dp.packVector3(mUserForce, "userforce"); + return TRUE; } BOOL LLFlexibleObjectData::unpack(LLDataPacker &dp) { - U8 tension, friction, gravity, wind; - U8 bit1, bit2; - dp.unpackU8(tension, "tension"); bit1 = (tension >> 6) & 2; - mTension = ((F32)(tension&0x7f))/10.f; - dp.unpackU8(friction, "drag"); bit2 = (friction >> 7) & 1; - mAirFriction = ((F32)(friction&0x7f))/10.f; - mSimulateLOD = bit1 | bit2; - dp.unpackU8(gravity, "gravity"); mGravity = ((F32)gravity)/10.f - 10.f; - dp.unpackU8(wind, "wind"); mWindSensitivity = ((F32)wind)/10.f; - if (dp.hasNext()) - { - dp.unpackVector3(mUserForce, "userforce"); - } - else - { - mUserForce.setVec(0.f, 0.f, 0.f); - } - return TRUE; + U8 tension, friction, gravity, wind; + U8 bit1, bit2; + dp.unpackU8(tension, "tension"); bit1 = (tension >> 6) & 2; + mTension = ((F32)(tension&0x7f))/10.f; + dp.unpackU8(friction, "drag"); bit2 = (friction >> 7) & 1; + mAirFriction = ((F32)(friction&0x7f))/10.f; + mSimulateLOD = bit1 | bit2; + dp.unpackU8(gravity, "gravity"); mGravity = ((F32)gravity)/10.f - 10.f; + dp.unpackU8(wind, "wind"); mWindSensitivity = ((F32)wind)/10.f; + if (dp.hasNext()) + { + dp.unpackVector3(mUserForce, "userforce"); + } + else + { + mUserForce.setVec(0.f, 0.f, 0.f); + } + return TRUE; } bool LLFlexibleObjectData::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_FLEXIBLE) - { - return false; - } - LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data; - return (mSimulateLOD == flex_data->mSimulateLOD && - mGravity == flex_data->mGravity && - mAirFriction == flex_data->mAirFriction && - mWindSensitivity == flex_data->mWindSensitivity && - mTension == flex_data->mTension && - mUserForce == flex_data->mUserForce); - //mUsingCollisionSphere == flex_data->mUsingCollisionSphere && - //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere + if (data.mType != PARAMS_FLEXIBLE) + { + return false; + } + LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data; + return (mSimulateLOD == flex_data->mSimulateLOD && + mGravity == flex_data->mGravity && + mAirFriction == flex_data->mAirFriction && + mWindSensitivity == flex_data->mWindSensitivity && + mTension == flex_data->mTension && + mUserForce == flex_data->mUserForce); + //mUsingCollisionSphere == flex_data->mUsingCollisionSphere && + //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere } void LLFlexibleObjectData::copy(const LLNetworkData& data) { - const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data; - mSimulateLOD = flex_data->mSimulateLOD; - mGravity = flex_data->mGravity; - mAirFriction = flex_data->mAirFriction; - mWindSensitivity = flex_data->mWindSensitivity; - mTension = flex_data->mTension; - mUserForce = flex_data->mUserForce; - //mUsingCollisionSphere = flex_data->mUsingCollisionSphere; - //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere; + const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data; + mSimulateLOD = flex_data->mSimulateLOD; + mGravity = flex_data->mGravity; + mAirFriction = flex_data->mAirFriction; + mWindSensitivity = flex_data->mWindSensitivity; + mTension = flex_data->mTension; + mUserForce = flex_data->mUserForce; + //mUsingCollisionSphere = flex_data->mUsingCollisionSphere; + //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere; } LLSD LLFlexibleObjectData::asLLSD() const { - LLSD sd; + LLSD sd; - sd["air_friction"] = getAirFriction(); - sd["gravity"] = getGravity(); - sd["simulate_lod"] = getSimulateLOD(); - sd["tension"] = getTension(); - sd["user_force"] = getUserForce().getValue(); - sd["wind_sensitivity"] = getWindSensitivity(); - - return sd; + sd["air_friction"] = getAirFriction(); + sd["gravity"] = getGravity(); + sd["simulate_lod"] = getSimulateLOD(); + sd["tension"] = getTension(); + sd["user_force"] = getUserForce().getValue(); + sd["wind_sensitivity"] = getWindSensitivity(); + + return sd; } bool LLFlexibleObjectData::fromLLSD(LLSD& sd) { - const char *w; - w = "air_friction"; - if (sd.has(w)) - { - setAirFriction( (F32)sd[w].asReal() ); - } else goto fail; - w = "gravity"; - if (sd.has(w)) - { - setGravity( (F32)sd[w].asReal() ); - } else goto fail; - w = "simulate_lod"; - if (sd.has(w)) - { - setSimulateLOD( sd[w].asInteger() ); - } else goto fail; - w = "tension"; - if (sd.has(w)) - { - setTension( (F32)sd[w].asReal() ); - } else goto fail; - w = "user_force"; - if (sd.has(w)) - { - LLVector3 user_force = ll_vector3_from_sd(sd[w], 0); - setUserForce( user_force ); - } else goto fail; - w = "wind_sensitivity"; - if (sd.has(w)) - { - setWindSensitivity( (F32)sd[w].asReal() ); - } else goto fail; - - return true; + const char *w; + w = "air_friction"; + if (sd.has(w)) + { + setAirFriction( (F32)sd[w].asReal() ); + } else goto fail; + w = "gravity"; + if (sd.has(w)) + { + setGravity( (F32)sd[w].asReal() ); + } else goto fail; + w = "simulate_lod"; + if (sd.has(w)) + { + setSimulateLOD( sd[w].asInteger() ); + } else goto fail; + w = "tension"; + if (sd.has(w)) + { + setTension( (F32)sd[w].asReal() ); + } else goto fail; + w = "user_force"; + if (sd.has(w)) + { + LLVector3 user_force = ll_vector3_from_sd(sd[w], 0); + setUserForce( user_force ); + } else goto fail; + w = "wind_sensitivity"; + if (sd.has(w)) + { + setWindSensitivity( (F32)sd[w].asReal() ); + } else goto fail; + + return true; fail: - return false; + return false; } //============================================================================ LLSculptParams::LLSculptParams() { - mType = PARAMS_SCULPT; - mSculptTexture.set(SCULPT_DEFAULT_TEXTURE); - mSculptType = LL_SCULPT_TYPE_SPHERE; + mType = PARAMS_SCULPT; + mSculptTexture.set(SCULPT_DEFAULT_TEXTURE); + mSculptType = LL_SCULPT_TYPE_SPHERE; } BOOL LLSculptParams::pack(LLDataPacker &dp) const { - dp.packUUID(mSculptTexture, "texture"); - dp.packU8(mSculptType, "type"); - - return TRUE; + dp.packUUID(mSculptTexture, "texture"); + dp.packU8(mSculptType, "type"); + + return TRUE; } BOOL LLSculptParams::unpack(LLDataPacker &dp) { - U8 type; - LLUUID id; - dp.unpackUUID(id, "texture"); - dp.unpackU8(type, "type"); + U8 type; + LLUUID id; + dp.unpackUUID(id, "texture"); + dp.unpackU8(type, "type"); - setSculptTexture(id, type); - return TRUE; + setSculptTexture(id, type); + return TRUE; } bool LLSculptParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_SCULPT) - { - return false; - } - - const LLSculptParams *param = (const LLSculptParams*)&data; - if ( (param->mSculptTexture != mSculptTexture) || - (param->mSculptType != mSculptType) ) - - { - return false; - } - - return true; + if (data.mType != PARAMS_SCULPT) + { + return false; + } + + const LLSculptParams *param = (const LLSculptParams*)&data; + if ( (param->mSculptTexture != mSculptTexture) || + (param->mSculptType != mSculptType) ) + + { + return false; + } + + return true; } void LLSculptParams::copy(const LLNetworkData& data) { - const LLSculptParams *param = (LLSculptParams*)&data; - setSculptTexture(param->mSculptTexture, param->mSculptType); + const LLSculptParams *param = (LLSculptParams*)&data; + setSculptTexture(param->mSculptTexture, param->mSculptType); } LLSD LLSculptParams::asLLSD() const { - LLSD sd; - - sd["texture"] = mSculptTexture; - sd["type"] = mSculptType; - - return sd; + LLSD sd; + + sd["texture"] = mSculptTexture; + sd["type"] = mSculptType; + + return sd; } bool LLSculptParams::fromLLSD(LLSD& sd) { - const char *w; - U8 type; - w = "type"; - if (sd.has(w)) - { - type = sd[w].asInteger(); - } - else return false; + const char *w; + U8 type; + w = "type"; + if (sd.has(w)) + { + type = sd[w].asInteger(); + } + else return false; - w = "texture"; - if (sd.has(w)) - { - setSculptTexture(sd[w], type); - } - else return false; + w = "texture"; + if (sd.has(w)) + { + setSculptTexture(sd[w], type); + } + else return false; - return true; + return true; } void LLSculptParams::setSculptTexture(const LLUUID& texture_id, U8 sculpt_type) { - U8 type = sculpt_type & LL_SCULPT_TYPE_MASK; - U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK; - if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX) - { - mSculptTexture.set(SCULPT_DEFAULT_TEXTURE); - mSculptType = LL_SCULPT_TYPE_SPHERE; - } - else - { - mSculptTexture = texture_id; - mSculptType = sculpt_type; - } + U8 type = sculpt_type & LL_SCULPT_TYPE_MASK; + U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK; + if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX) + { + mSculptTexture.set(SCULPT_DEFAULT_TEXTURE); + mSculptType = LL_SCULPT_TYPE_SPHERE; + } + else + { + mSculptTexture = texture_id; + mSculptType = sculpt_type; + } } //============================================================================ LLLightImageParams::LLLightImageParams() { - mType = PARAMS_LIGHT_IMAGE; - mParams.setVec(F_PI*0.5f, 0.f, 0.f); + mType = PARAMS_LIGHT_IMAGE; + mParams.setVec(F_PI*0.5f, 0.f, 0.f); } BOOL LLLightImageParams::pack(LLDataPacker &dp) const { - dp.packUUID(mLightTexture, "texture"); - dp.packVector3(mParams, "params"); + dp.packUUID(mLightTexture, "texture"); + dp.packVector3(mParams, "params"); - return TRUE; + return TRUE; } BOOL LLLightImageParams::unpack(LLDataPacker &dp) { - dp.unpackUUID(mLightTexture, "texture"); - dp.unpackVector3(mParams, "params"); - - return TRUE; + dp.unpackUUID(mLightTexture, "texture"); + dp.unpackVector3(mParams, "params"); + + return TRUE; } bool LLLightImageParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_LIGHT_IMAGE) - { - return false; - } - - const LLLightImageParams *param = (const LLLightImageParams*)&data; - if ( (param->mLightTexture != mLightTexture) ) - { - return false; - } - - if ( (param->mParams != mParams ) ) - { - return false; - } - - return true; + if (data.mType != PARAMS_LIGHT_IMAGE) + { + return false; + } + + const LLLightImageParams *param = (const LLLightImageParams*)&data; + if ( (param->mLightTexture != mLightTexture) ) + { + return false; + } + + if ( (param->mParams != mParams ) ) + { + return false; + } + + return true; } void LLLightImageParams::copy(const LLNetworkData& data) { - const LLLightImageParams *param = (LLLightImageParams*)&data; - mLightTexture = param->mLightTexture; - mParams = param->mParams; + const LLLightImageParams *param = (LLLightImageParams*)&data; + mLightTexture = param->mLightTexture; + mParams = param->mParams; } LLSD LLLightImageParams::asLLSD() const { - LLSD sd; - - sd["texture"] = mLightTexture; - sd["params"] = mParams.getValue(); - - return sd; + LLSD sd; + + sd["texture"] = mLightTexture; + sd["params"] = mParams.getValue(); + + return sd; } bool LLLightImageParams::fromLLSD(LLSD& sd) { - if (sd.has("texture")) - { - setLightTexture( sd["texture"] ); - setParams( LLVector3( sd["params"] ) ); - return true; - } - - return false; + if (sd.has("texture")) + { + setLightTexture( sd["texture"] ); + setParams( LLVector3( sd["params"] ) ); + return true; + } + + return false; } //============================================================================ @@ -2263,63 +2263,63 @@ bool LLLightImageParams::fromLLSD(LLSD& sd) LLExtendedMeshParams::LLExtendedMeshParams() { mType = PARAMS_EXTENDED_MESH; - mFlags = 0; + mFlags = 0; } BOOL LLExtendedMeshParams::pack(LLDataPacker &dp) const { - dp.packU32(mFlags, "flags"); + dp.packU32(mFlags, "flags"); - return TRUE; + return TRUE; } BOOL LLExtendedMeshParams::unpack(LLDataPacker &dp) { - dp.unpackU32(mFlags, "flags"); - - return TRUE; + dp.unpackU32(mFlags, "flags"); + + return TRUE; } bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_EXTENDED_MESH) - { - return false; - } - - const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data; - if ( (param->mFlags != mFlags) ) - { - return false; - } + if (data.mType != PARAMS_EXTENDED_MESH) + { + return false; + } - return true; + const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data; + if ( (param->mFlags != mFlags) ) + { + return false; + } + + return true; } void LLExtendedMeshParams::copy(const LLNetworkData& data) { - const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data; - mFlags = param->mFlags; + const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data; + mFlags = param->mFlags; } LLSD LLExtendedMeshParams::asLLSD() const { - LLSD sd; - - sd["flags"] = LLSD::Integer(mFlags); - - return sd; + LLSD sd; + + sd["flags"] = LLSD::Integer(mFlags); + + return sd; } bool LLExtendedMeshParams::fromLLSD(LLSD& sd) { - if (sd.has("flags")) - { - setFlags( sd["flags"].asInteger()); - return true; - } - - return false; + if (sd.has("flags")) + { + setFlags( sd["flags"].asInteger()); + return true; + } + + return false; } //============================================================================ diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 5622483861..6078abf67e 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -1,25 +1,25 @@ -/** +/** * @file llprimitive.h * @brief LLPrimitive base class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,14 +49,14 @@ class LLVolumeMgr; enum LLGeomType // NOTE: same vals as GL Ids { - LLInvalid = 0, - LLLineLoop = 2, - LLLineStrip = 3, - LLTriangles = 4, - LLTriStrip = 5, - LLTriFan = 6, - LLQuads = 7, - LLQuadStrip = 8 + LLInvalid = 0, + LLLineLoop = 2, + LLLineStrip = 3, + LLTriangles = 4, + LLTriStrip = 5, + LLTriFan = 6, + LLQuads = 7, + LLQuadStrip = 8 }; class LLVolume; @@ -97,28 +97,28 @@ extern const char *SCULPT_DEFAULT_TEXTURE; class LLNetworkData { public: - // Extra parameter IDs - enum - { - PARAMS_FLEXIBLE = 0x10, - PARAMS_LIGHT = 0x20, - PARAMS_SCULPT = 0x30, - PARAMS_LIGHT_IMAGE = 0x40, - PARAMS_RESERVED = 0x50, // Used on server-side - PARAMS_MESH = 0x60, + // Extra parameter IDs + enum + { + PARAMS_FLEXIBLE = 0x10, + PARAMS_LIGHT = 0x20, + PARAMS_SCULPT = 0x30, + PARAMS_LIGHT_IMAGE = 0x40, + PARAMS_RESERVED = 0x50, // Used on server-side + PARAMS_MESH = 0x60, PARAMS_EXTENDED_MESH = 0x70, PARAMS_RENDER_MATERIAL = 0x80, PARAMS_REFLECTION_PROBE = 0x90, - }; - + }; + public: - U16 mType; - virtual ~LLNetworkData() {}; - virtual BOOL pack(LLDataPacker &dp) const = 0; - virtual BOOL unpack(LLDataPacker &dp) = 0; - virtual bool operator==(const LLNetworkData& data) const = 0; - virtual void copy(const LLNetworkData& data) = 0; - static BOOL isValid(U16 param_type, U32 size); + U16 mType; + virtual ~LLNetworkData() {}; + virtual BOOL pack(LLDataPacker &dp) const = 0; + virtual BOOL unpack(LLDataPacker &dp) = 0; + virtual bool operator==(const LLNetworkData& data) const = 0; + virtual void copy(const LLNetworkData& data) = 0; + static BOOL isValid(U16 param_type, U32 size); }; extern const F32 LIGHT_MIN_RADIUS; @@ -134,22 +134,22 @@ extern const F32 LIGHT_MAX_CUTOFF; class LLLightParams : public LLNetworkData { private: - LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity - F32 mRadius; - F32 mFalloff; - F32 mCutoff; + LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity + F32 mRadius; + F32 mFalloff; + F32 mCutoff; public: - LLLightParams(); - /*virtual*/ BOOL pack(LLDataPacker &dp) const; - /*virtual*/ BOOL unpack(LLDataPacker &dp); - /*virtual*/ bool operator==(const LLNetworkData& data) const; - /*virtual*/ void copy(const LLNetworkData& data); - // LLSD implementations here are provided by Eddy Stryker. - // NOTE: there are currently unused in protocols - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); + LLLightParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + // LLSD implementations here are provided by Eddy Stryker. + // NOTE: there are currently unused in protocols + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); // set the color by gamma corrected color value // color - gamma corrected color value (directly taken from an on-screen color swatch) @@ -157,19 +157,19 @@ public: // set the color by linear color value // color - linear color value (value as it appears in shaders) - void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); } - void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); } - void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); } - void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); } + void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); } + void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); } + void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); } + void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); } // get the linear space color of this light. This value can be fed directly to shaders - LLColor4 getLinearColor() const { return mColor; } + LLColor4 getLinearColor() const { return mColor; } // get the sRGB (gamma corrected) color of this light, this is the value that should be displayed in the UI - LLColor4 getSRGBColor() const { return srgbColor4(mColor); } - - F32 getRadius() const { return mRadius; } - F32 getFalloff() const { return mFalloff; } - F32 getCutoff() const { return mCutoff; } + LLColor4 getSRGBColor() const { return srgbColor4(mColor); } + + F32 getRadius() const { return mRadius; } + F32 getFalloff() const { return mFalloff; } + F32 getCutoff() const { return mCutoff; } }; extern const F32 REFLECTION_PROBE_MIN_AMBIANCE; @@ -186,7 +186,7 @@ public: { FLAG_BOX_VOLUME = 0x01, // use a box influence volume FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe - FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors. + FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors. }; protected: @@ -220,7 +220,7 @@ public: }; //------------------------------------------------- -// This structure is also used in the part of the +// This structure is also used in the part of the // code that creates new flexible objects. //------------------------------------------------- @@ -228,11 +228,11 @@ public: // array bounds. enum EFlexibleObjectConst { - // "Softness" => [0,3], increments of 1 - // Represents powers of 2: 0 -> 1, 3 -> 8 - FLEXIBLE_OBJECT_MIN_SECTIONS = 0, - FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS = 2, - FLEXIBLE_OBJECT_MAX_SECTIONS = 3 + // "Softness" => [0,3], increments of 1 + // Represents powers of 2: 0 -> 1, 3 -> 8 + FLEXIBLE_OBJECT_MIN_SECTIONS = 0, + FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS = 2, + FLEXIBLE_OBJECT_MAX_SECTIONS = 3 }; // "Tension" => [0,10], increments of 0.1 @@ -265,39 +265,39 @@ extern const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE; class LLFlexibleObjectData : public LLNetworkData { protected: - S32 mSimulateLOD; // 2^n = number of simulated sections - F32 mGravity; - F32 mAirFriction; // higher is more stable, but too much looks like it's underwater - F32 mWindSensitivity; // interacts with tension, air friction, and gravity - F32 mTension; //interacts in complex ways with other parameters - LLVector3 mUserForce; // custom user-defined force vector - //BOOL mUsingCollisionSphere; - //BOOL mRenderingCollisionSphere; + S32 mSimulateLOD; // 2^n = number of simulated sections + F32 mGravity; + F32 mAirFriction; // higher is more stable, but too much looks like it's underwater + F32 mWindSensitivity; // interacts with tension, air friction, and gravity + F32 mTension; //interacts in complex ways with other parameters + LLVector3 mUserForce; // custom user-defined force vector + //BOOL mUsingCollisionSphere; + //BOOL mRenderingCollisionSphere; public: - void setSimulateLOD(S32 lod) { mSimulateLOD = llclamp(lod, (S32)FLEXIBLE_OBJECT_MIN_SECTIONS, (S32)FLEXIBLE_OBJECT_MAX_SECTIONS); } - void setGravity(F32 gravity) { mGravity = llclamp(gravity, FLEXIBLE_OBJECT_MIN_GRAVITY, FLEXIBLE_OBJECT_MAX_GRAVITY); } - void setAirFriction(F32 friction) { mAirFriction = llclamp(friction, FLEXIBLE_OBJECT_MIN_AIR_FRICTION, FLEXIBLE_OBJECT_MAX_AIR_FRICTION); } - void setWindSensitivity(F32 wind) { mWindSensitivity = llclamp(wind, FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY, FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY); } - void setTension(F32 tension) { mTension = llclamp(tension, FLEXIBLE_OBJECT_MIN_TENSION, FLEXIBLE_OBJECT_MAX_TENSION); } - void setUserForce(LLVector3 &force) { mUserForce = force; } - - S32 getSimulateLOD() const { return mSimulateLOD; } - F32 getGravity() const { return mGravity; } - F32 getAirFriction() const { return mAirFriction; } - F32 getWindSensitivity() const { return mWindSensitivity; } - F32 getTension() const { return mTension; } - LLVector3 getUserForce() const { return mUserForce; } - - //------ the constructor for the structure ------------ - LLFlexibleObjectData(); - BOOL pack(LLDataPacker &dp) const; - BOOL unpack(LLDataPacker &dp); - bool operator==(const LLNetworkData& data) const; - void copy(const LLNetworkData& data); - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); + void setSimulateLOD(S32 lod) { mSimulateLOD = llclamp(lod, (S32)FLEXIBLE_OBJECT_MIN_SECTIONS, (S32)FLEXIBLE_OBJECT_MAX_SECTIONS); } + void setGravity(F32 gravity) { mGravity = llclamp(gravity, FLEXIBLE_OBJECT_MIN_GRAVITY, FLEXIBLE_OBJECT_MAX_GRAVITY); } + void setAirFriction(F32 friction) { mAirFriction = llclamp(friction, FLEXIBLE_OBJECT_MIN_AIR_FRICTION, FLEXIBLE_OBJECT_MAX_AIR_FRICTION); } + void setWindSensitivity(F32 wind) { mWindSensitivity = llclamp(wind, FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY, FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY); } + void setTension(F32 tension) { mTension = llclamp(tension, FLEXIBLE_OBJECT_MIN_TENSION, FLEXIBLE_OBJECT_MAX_TENSION); } + void setUserForce(LLVector3 &force) { mUserForce = force; } + + S32 getSimulateLOD() const { return mSimulateLOD; } + F32 getGravity() const { return mGravity; } + F32 getAirFriction() const { return mAirFriction; } + F32 getWindSensitivity() const { return mWindSensitivity; } + F32 getTension() const { return mTension; } + LLVector3 getUserForce() const { return mUserForce; } + + //------ the constructor for the structure ------------ + LLFlexibleObjectData(); + BOOL pack(LLDataPacker &dp) const; + BOOL unpack(LLDataPacker &dp); + bool operator==(const LLNetworkData& data) const; + void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); };// end of attributes structure @@ -305,68 +305,68 @@ public: class LLSculptParams : public LLNetworkData { protected: - LLUUID mSculptTexture; - U8 mSculptType; - + LLUUID mSculptTexture; + U8 mSculptType; + public: - LLSculptParams(); - /*virtual*/ BOOL pack(LLDataPacker &dp) const; - /*virtual*/ BOOL unpack(LLDataPacker &dp); - /*virtual*/ bool operator==(const LLNetworkData& data) const; - /*virtual*/ void copy(const LLNetworkData& data); - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type); - LLUUID getSculptTexture() const { return mSculptTexture; } - U8 getSculptType() const { return mSculptType; } + LLSculptParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type); + LLUUID getSculptTexture() const { return mSculptTexture; } + U8 getSculptType() const { return mSculptType; } }; class LLLightImageParams : public LLNetworkData { protected: - LLUUID mLightTexture; - LLVector3 mParams; - + LLUUID mLightTexture; + LLVector3 mParams; + public: - LLLightImageParams(); - /*virtual*/ BOOL pack(LLDataPacker &dp) const; - /*virtual*/ BOOL unpack(LLDataPacker &dp); - /*virtual*/ bool operator==(const LLNetworkData& data) const; - /*virtual*/ void copy(const LLNetworkData& data); - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - void setLightTexture(const LLUUID& id) { mLightTexture = id; } - LLUUID getLightTexture() const { return mLightTexture; } - bool isLightSpotlight() const { return mLightTexture.notNull(); } - void setParams(const LLVector3& params) { mParams = params; } - LLVector3 getParams() const { return mParams; } - + LLLightImageParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setLightTexture(const LLUUID& id) { mLightTexture = id; } + LLUUID getLightTexture() const { return mLightTexture; } + bool isLightSpotlight() const { return mLightTexture.notNull(); } + void setParams(const LLVector3& params) { mParams = params; } + LLVector3 getParams() const { return mParams; } + }; class LLExtendedMeshParams : public LLNetworkData { protected: - U32 mFlags; - + U32 mFlags; + public: - static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0; - - LLExtendedMeshParams(); - /*virtual*/ BOOL pack(LLDataPacker &dp) const; - /*virtual*/ BOOL unpack(LLDataPacker &dp); - /*virtual*/ bool operator==(const LLNetworkData& data) const; - /*virtual*/ void copy(const LLNetworkData& data); - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - - void setFlags(const U32& flags) { mFlags = flags; } + static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0; + + LLExtendedMeshParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setFlags(const U32& flags) { mFlags = flags; } U32 getFlags() const { return mFlags; } - + }; class LLRenderMaterialParams : public LLNetworkData @@ -385,7 +385,7 @@ public: BOOL unpack(LLDataPacker& dp) override; bool operator==(const LLNetworkData& data) const override; void copy(const LLNetworkData& data) override; - + void setMaterial(U8 te_idx, const LLUUID& id); const LLUUID& getMaterial(U8 te_idx) const; @@ -395,249 +395,249 @@ public: // This code is not naming-standards compliant. Leaving it like this for // now to make the connection to code in -// BOOL packTEMessage(LLDataPacker &dp) const; +// BOOL packTEMessage(LLDataPacker &dp) const; // more obvious. This should be refactored to remove the duplication, at which // point we can fix the names as well. // - Vir struct LLTEContents { - static const U32 MAX_TES = 45; + static const U32 MAX_TES = 45; LLUUID image_data[MAX_TES]; LLColor4U colors[MAX_TES]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; - LLMaterialID material_ids[MAX_TES]; + LLMaterialID material_ids[MAX_TES]; - static const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; + static const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; - U32 size; - U32 face_count; + U32 size; + U32 face_count; }; class LLPrimitive : public LLXform { public: - // HACK for removing LLPrimitive's dependency on gVolumeMgr global. - // If a different LLVolumeManager is instantiated and set early enough - // then the LLPrimitive class will use it instead of gVolumeMgr. - static LLVolumeMgr* getVolumeManager() { return sVolumeManager; } - static void setVolumeManager( LLVolumeMgr* volume_manager); - static bool cleanupVolumeManager(); - - // these flags influence how the RigidBody representation is built - static const U32 PRIM_FLAG_PHANTOM = 0x1 << 0; - static const U32 PRIM_FLAG_VOLUME_DETECT = 0x1 << 1; - static const U32 PRIM_FLAG_DYNAMIC = 0x1 << 2; - static const U32 PRIM_FLAG_AVATAR = 0x1 << 3; - static const U32 PRIM_FLAG_SCULPT = 0x1 << 4; - // not used yet, but soon - static const U32 PRIM_FLAG_COLLISION_CALLBACK = 0x1 << 5; - static const U32 PRIM_FLAG_CONVEX = 0x1 << 6; - static const U32 PRIM_FLAG_DEFAULT_VOLUME = 0x1 << 7; - static const U32 PRIM_FLAG_SITTING = 0x1 << 8; - static const U32 PRIM_FLAG_SITTING_ON_GROUND = 0x1 << 9; // Set along with PRIM_FLAG_SITTING - - LLPrimitive(); - virtual ~LLPrimitive(); - - void clearTextureList(); - - static LLPrimitive *createPrimitive(LLPCode p_code); - void init_primitive(LLPCode p_code); - - void setPCode(const LLPCode pcode); - const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume - LLVolume *getVolume() const { return mVolumep; } - virtual BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false); - - // Modify texture entry properties - inline BOOL validTE(const U8 te_num) const; - LLTextureEntry* getTE(const U8 te_num) const; - - virtual void setNumTEs(const U8 num_tes); - virtual void setAllTESelected(bool sel); - virtual void setAllTETextures(const LLUUID &tex_id); - virtual void setTE(const U8 index, const LLTextureEntry& te); - virtual S32 setTEColor(const U8 te, const LLColor4 &color); - virtual S32 setTEColor(const U8 te, const LLColor3 &color); - virtual S32 setTEAlpha(const U8 te, const F32 alpha); - virtual S32 setTETexture(const U8 te, const LLUUID &tex_id); - virtual S32 setTEScale (const U8 te, const F32 s, const F32 t); - virtual S32 setTEScaleS(const U8 te, const F32 s); - virtual S32 setTEScaleT(const U8 te, const F32 t); - virtual S32 setTEOffset (const U8 te, const F32 s, const F32 t); - virtual S32 setTEOffsetS(const U8 te, const F32 s); - virtual S32 setTEOffsetT(const U8 te, const F32 t); - virtual S32 setTERotation(const U8 te, const F32 r); - virtual S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); - virtual S32 setTEBumpShiny(const U8 te, const U8 bump); - virtual S32 setTEMediaTexGen(const U8 te, const U8 media); - virtual S32 setTEBumpmap(const U8 te, const U8 bump); - virtual S32 setTETexGen(const U8 te, const U8 texgen); - virtual S32 setTEShiny(const U8 te, const U8 shiny); - virtual S32 setTEFullbright(const U8 te, const U8 fullbright); - virtual S32 setTEMediaFlags(const U8 te, const U8 flags); - virtual S32 setTEGlow(const U8 te, const F32 glow); - virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); + // HACK for removing LLPrimitive's dependency on gVolumeMgr global. + // If a different LLVolumeManager is instantiated and set early enough + // then the LLPrimitive class will use it instead of gVolumeMgr. + static LLVolumeMgr* getVolumeManager() { return sVolumeManager; } + static void setVolumeManager( LLVolumeMgr* volume_manager); + static bool cleanupVolumeManager(); + + // these flags influence how the RigidBody representation is built + static const U32 PRIM_FLAG_PHANTOM = 0x1 << 0; + static const U32 PRIM_FLAG_VOLUME_DETECT = 0x1 << 1; + static const U32 PRIM_FLAG_DYNAMIC = 0x1 << 2; + static const U32 PRIM_FLAG_AVATAR = 0x1 << 3; + static const U32 PRIM_FLAG_SCULPT = 0x1 << 4; + // not used yet, but soon + static const U32 PRIM_FLAG_COLLISION_CALLBACK = 0x1 << 5; + static const U32 PRIM_FLAG_CONVEX = 0x1 << 6; + static const U32 PRIM_FLAG_DEFAULT_VOLUME = 0x1 << 7; + static const U32 PRIM_FLAG_SITTING = 0x1 << 8; + static const U32 PRIM_FLAG_SITTING_ON_GROUND = 0x1 << 9; // Set along with PRIM_FLAG_SITTING + + LLPrimitive(); + virtual ~LLPrimitive(); + + void clearTextureList(); + + static LLPrimitive *createPrimitive(LLPCode p_code); + void init_primitive(LLPCode p_code); + + void setPCode(const LLPCode pcode); + const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume + LLVolume *getVolume() const { return mVolumep; } + virtual BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false); + + // Modify texture entry properties + inline BOOL validTE(const U8 te_num) const; + LLTextureEntry* getTE(const U8 te_num) const; + + virtual void setNumTEs(const U8 num_tes); + virtual void setAllTESelected(bool sel); + virtual void setAllTETextures(const LLUUID &tex_id); + virtual void setTE(const U8 index, const LLTextureEntry& te); + virtual S32 setTEColor(const U8 te, const LLColor4 &color); + virtual S32 setTEColor(const U8 te, const LLColor3 &color); + virtual S32 setTEAlpha(const U8 te, const F32 alpha); + virtual S32 setTETexture(const U8 te, const LLUUID &tex_id); + virtual S32 setTEScale (const U8 te, const F32 s, const F32 t); + virtual S32 setTEScaleS(const U8 te, const F32 s); + virtual S32 setTEScaleT(const U8 te, const F32 t); + virtual S32 setTEOffset (const U8 te, const F32 s, const F32 t); + virtual S32 setTEOffsetS(const U8 te, const F32 s); + virtual S32 setTEOffsetT(const U8 te, const F32 t); + virtual S32 setTERotation(const U8 te, const F32 r); + virtual S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); + virtual S32 setTEBumpShiny(const U8 te, const U8 bump); + virtual S32 setTEMediaTexGen(const U8 te, const U8 media); + virtual S32 setTEBumpmap(const U8 te, const U8 bump); + virtual S32 setTETexGen(const U8 te, const U8 texgen); + virtual S32 setTEShiny(const U8 te, const U8 shiny); + virtual S32 setTEFullbright(const U8 te, const U8 fullbright); + virtual S32 setTEMediaFlags(const U8 te, const U8 flags); + virtual S32 setTEGlow(const U8 te, const F32 glow); + virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); - virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed - virtual void setTESelected(const U8 te, bool sel); - - LLMaterialPtr getTEMaterialParams(const U8 index); - - void copyTEs(const LLPrimitive *primitive); - S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; - BOOL packTEMessage(LLMessageSystem *mesgsys) const; - BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks - BOOL unpackTEMessage(LLDataPacker &dp); - S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec); - S32 applyParsedTEMessage(LLTEContents& tec); - + virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed + virtual void setTESelected(const U8 te, bool sel); + + LLMaterialPtr getTEMaterialParams(const U8 index); + + void copyTEs(const LLPrimitive *primitive); + S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; + BOOL packTEMessage(LLMessageSystem *mesgsys) const; + BOOL packTEMessage(LLDataPacker &dp) const; + S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks + BOOL unpackTEMessage(LLDataPacker &dp); + S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec); + S32 applyParsedTEMessage(LLTEContents& tec); + #ifdef CHECK_FOR_FINITE - inline void setPosition(const LLVector3& pos); - inline void setPosition(const F32 x, const F32 y, const F32 z); - inline void addPosition(const LLVector3& pos); - - inline void setAngularVelocity(const LLVector3& avel); - inline void setAngularVelocity(const F32 x, const F32 y, const F32 z); - inline void setVelocity(const LLVector3& vel); - inline void setVelocity(const F32 x, const F32 y, const F32 z); - inline void setVelocityX(const F32 x); - inline void setVelocityY(const F32 y); - inline void setVelocityZ(const F32 z); - inline void addVelocity(const LLVector3& vel); - inline void setAcceleration(const LLVector3& accel); - inline void setAcceleration(const F32 x, const F32 y, const F32 z); + inline void setPosition(const LLVector3& pos); + inline void setPosition(const F32 x, const F32 y, const F32 z); + inline void addPosition(const LLVector3& pos); + + inline void setAngularVelocity(const LLVector3& avel); + inline void setAngularVelocity(const F32 x, const F32 y, const F32 z); + inline void setVelocity(const LLVector3& vel); + inline void setVelocity(const F32 x, const F32 y, const F32 z); + inline void setVelocityX(const F32 x); + inline void setVelocityY(const F32 y); + inline void setVelocityZ(const F32 z); + inline void addVelocity(const LLVector3& vel); + inline void setAcceleration(const LLVector3& accel); + inline void setAcceleration(const F32 x, const F32 y, const F32 z); #else - // Don't override the base LLXForm operators. - // Special case for setPosition. If not check-for-finite, fall through to LLXform method. - // void setPosition(F32 x, F32 y, F32 z) - // void setPosition(LLVector3) - - void setAngularVelocity(const LLVector3& avel) { mAngularVelocity = avel; } - void setAngularVelocity(const F32 x, const F32 y, const F32 z) { mAngularVelocity.setVec(x,y,z); } - void setVelocity(const LLVector3& vel) { mVelocity = vel; } - void setVelocity(const F32 x, const F32 y, const F32 z) { mVelocity.setVec(x,y,z); } - void setVelocityX(const F32 x) { mVelocity.mV[VX] = x; } - void setVelocityY(const F32 y) { mVelocity.mV[VY] = y; } - void setVelocityZ(const F32 z) { mVelocity.mV[VZ] = z; } - void addVelocity(const LLVector3& vel) { mVelocity += vel; } - void setAcceleration(const LLVector3& accel) { mAcceleration = accel; } - void setAcceleration(const F32 x, const F32 y, const F32 z) { mAcceleration.setVec(x,y,z); } + // Don't override the base LLXForm operators. + // Special case for setPosition. If not check-for-finite, fall through to LLXform method. + // void setPosition(F32 x, F32 y, F32 z) + // void setPosition(LLVector3) + + void setAngularVelocity(const LLVector3& avel) { mAngularVelocity = avel; } + void setAngularVelocity(const F32 x, const F32 y, const F32 z) { mAngularVelocity.setVec(x,y,z); } + void setVelocity(const LLVector3& vel) { mVelocity = vel; } + void setVelocity(const F32 x, const F32 y, const F32 z) { mVelocity.setVec(x,y,z); } + void setVelocityX(const F32 x) { mVelocity.mV[VX] = x; } + void setVelocityY(const F32 y) { mVelocity.mV[VY] = y; } + void setVelocityZ(const F32 z) { mVelocity.mV[VZ] = z; } + void addVelocity(const LLVector3& vel) { mVelocity += vel; } + void setAcceleration(const LLVector3& accel) { mAcceleration = accel; } + void setAcceleration(const F32 x, const F32 y, const F32 z) { mAcceleration.setVec(x,y,z); } #endif - - LLPCode getPCode() const { return mPrimitiveCode; } - std::string getPCodeString() const { return pCodeToString(mPrimitiveCode); } - const LLVector3& getAngularVelocity() const { return mAngularVelocity; } - const LLVector3& getVelocity() const { return mVelocity; } - const LLVector3& getAcceleration() const { return mAcceleration; } - U8 getNumTEs() const { return mTextureList.size(); } - U8 getExpectedNumTEs() const; - - U8 getMaterial() const { return mMaterial; } - - void setVolumeType(const U8 code); - U8 getVolumeType(); - - // clears existing textures - // copies the contents of other_list into mEntryList - void copyTextureList(const LLPrimTextureList& other_list); - - // clears existing textures - // takes the contents of other_list and clears other_list - void takeTextureList(LLPrimTextureList& other_list); - - inline BOOL isAvatar() const; - inline BOOL isSittingAvatar() const; - inline BOOL isSittingAvatarOnGround() const; - inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;} - - void setFlags(U32 flags) { mMiscFlags = flags; } - void addFlags(U32 flags) { mMiscFlags |= flags; } - void removeFlags(U32 flags) { mMiscFlags &= ~flags; } - U32 getFlags() const { return mMiscFlags; } - - static std::string pCodeToString(const LLPCode pcode); - static LLPCode legacyToPCode(const U8 legacy); - static U8 pCodeToLegacy(const LLPCode pcode); - static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); + + LLPCode getPCode() const { return mPrimitiveCode; } + std::string getPCodeString() const { return pCodeToString(mPrimitiveCode); } + const LLVector3& getAngularVelocity() const { return mAngularVelocity; } + const LLVector3& getVelocity() const { return mVelocity; } + const LLVector3& getAcceleration() const { return mAcceleration; } + U8 getNumTEs() const { return mTextureList.size(); } + U8 getExpectedNumTEs() const; + + U8 getMaterial() const { return mMaterial; } + + void setVolumeType(const U8 code); + U8 getVolumeType(); + + // clears existing textures + // copies the contents of other_list into mEntryList + void copyTextureList(const LLPrimTextureList& other_list); + + // clears existing textures + // takes the contents of other_list and clears other_list + void takeTextureList(LLPrimTextureList& other_list); + + inline BOOL isAvatar() const; + inline BOOL isSittingAvatar() const; + inline BOOL isSittingAvatarOnGround() const; + inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;} + + void setFlags(U32 flags) { mMiscFlags = flags; } + void addFlags(U32 flags) { mMiscFlags |= flags; } + void removeFlags(U32 flags) { mMiscFlags &= ~flags; } + U32 getFlags() const { return mMiscFlags; } + + static std::string pCodeToString(const LLPCode pcode); + static LLPCode legacyToPCode(const U8 legacy); + static U8 pCodeToLegacy(const LLPCode pcode); + static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); BOOL hasRenderMaterialParams() const; - - inline static BOOL isPrimitive(const LLPCode pcode); - inline static BOOL isApp(const LLPCode pcode); + + inline static BOOL isPrimitive(const LLPCode pcode); + inline static BOOL isApp(const LLPCode pcode); private: - void updateNumBumpmap(const U8 index, const U8 bump); + void updateNumBumpmap(const U8 index, const U8 bump); protected: - LLPCode mPrimitiveCode; // Primitive code - LLVector3 mVelocity; // how fast are we moving? - LLVector3 mAcceleration; // are we under constant acceleration? - LLVector3 mAngularVelocity; // angular velocity - LLPointer mVolumep; - LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets - U8 mMaterial; // Material code - U8 mNumTEs; // # of faces on the primitve - U8 mNumBumpmapTEs; // number of bumpmap TEs. - U32 mMiscFlags; // home for misc bools + LLPCode mPrimitiveCode; // Primitive code + LLVector3 mVelocity; // how fast are we moving? + LLVector3 mAcceleration; // are we under constant acceleration? + LLVector3 mAngularVelocity; // angular velocity + LLPointer mVolumep; + LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets + U8 mMaterial; // Material code + U8 mNumTEs; // # of faces on the primitve + U8 mNumBumpmapTEs; // number of bumpmap TEs. + U32 mMiscFlags; // home for misc bools public: - static LLVolumeMgr* sVolumeManager; + static LLVolumeMgr* sVolumeManager; - enum - { - NO_LOD = -1 - }; + enum + { + NO_LOD = -1 + }; }; inline BOOL LLPrimitive::isAvatar() const { - return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode ) ? TRUE : FALSE; + return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode ) ? TRUE : FALSE; } inline BOOL LLPrimitive::isSittingAvatar() const { - // this is only used server-side - return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode - && ((getFlags() & (PRIM_FLAG_SITTING | PRIM_FLAG_SITTING_ON_GROUND)) != 0) ) ? TRUE : FALSE; + // this is only used server-side + return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode + && ((getFlags() & (PRIM_FLAG_SITTING | PRIM_FLAG_SITTING_ON_GROUND)) != 0) ) ? TRUE : FALSE; } inline BOOL LLPrimitive::isSittingAvatarOnGround() const { - // this is only used server-side - return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode - && ((getFlags() & PRIM_FLAG_SITTING_ON_GROUND) != 0) ) ? TRUE : FALSE; + // this is only used server-side + return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode + && ((getFlags() & PRIM_FLAG_SITTING_ON_GROUND) != 0) ) ? TRUE : FALSE; } // static inline BOOL LLPrimitive::isPrimitive(const LLPCode pcode) { - LLPCode base_type = pcode & LL_PCODE_BASE_MASK; + LLPCode base_type = pcode & LL_PCODE_BASE_MASK; - if (base_type && (base_type < LL_PCODE_APP)) - { - return TRUE; - } - return FALSE; + if (base_type && (base_type < LL_PCODE_APP)) + { + return TRUE; + } + return FALSE; } // static inline BOOL LLPrimitive::isApp(const LLPCode pcode) { - LLPCode base_type = pcode & LL_PCODE_BASE_MASK; + LLPCode base_type = pcode & LL_PCODE_BASE_MASK; - return (base_type == LL_PCODE_APP); + return (base_type == LL_PCODE_APP); } @@ -645,153 +645,153 @@ inline BOOL LLPrimitive::isApp(const LLPCode pcode) // Special case for setPosition. If not check-for-finite, fall through to LLXform method. void LLPrimitive::setPosition(const F32 x, const F32 y, const F32 z) { - if (llfinite(x) && llfinite(y) && llfinite(z)) - { - LLXform::setPosition(x, y, z); - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setPosition(x,y,z) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } + if (llfinite(x) && llfinite(y) && llfinite(z)) + { + LLXform::setPosition(x, y, z); + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setPosition(x,y,z) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } // Special case for setPosition. If not check-for-finite, fall through to LLXform method. void LLPrimitive::setPosition(const LLVector3& pos) { - if (pos.isFinite()) - { - LLXform::setPosition(pos); - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setPosition(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } + if (pos.isFinite()) + { + LLXform::setPosition(pos); + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setPosition(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } void LLPrimitive::setAngularVelocity(const LLVector3& avel) -{ - if (avel.isFinite()) - { - mAngularVelocity = avel; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL; - } +{ + if (avel.isFinite()) + { + mAngularVelocity = avel; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL; + } } -void LLPrimitive::setAngularVelocity(const F32 x, const F32 y, const F32 z) -{ - if (llfinite(x) && llfinite(y) && llfinite(z)) - { - mAngularVelocity.setVec(x,y,z); - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL; - } +void LLPrimitive::setAngularVelocity(const F32 x, const F32 y, const F32 z) +{ + if (llfinite(x) && llfinite(y) && llfinite(z)) + { + mAngularVelocity.setVec(x,y,z); + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL; + } } -void LLPrimitive::setVelocity(const LLVector3& vel) -{ - if (vel.isFinite()) - { - mVelocity = vel; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } +void LLPrimitive::setVelocity(const LLVector3& vel) +{ + if (vel.isFinite()) + { + mVelocity = vel; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } -void LLPrimitive::setVelocity(const F32 x, const F32 y, const F32 z) -{ - if (llfinite(x) && llfinite(y) && llfinite(z)) - { - mVelocity.setVec(x,y,z); - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } +void LLPrimitive::setVelocity(const F32 x, const F32 y, const F32 z) +{ + if (llfinite(x) && llfinite(y) && llfinite(z)) + { + mVelocity.setVec(x,y,z); + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } -void LLPrimitive::setVelocityX(const F32 x) -{ - if (llfinite(x)) - { - mVelocity.mV[VX] = x; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setVelocityX" << LL_ENDL; - } +void LLPrimitive::setVelocityX(const F32 x) +{ + if (llfinite(x)) + { + mVelocity.mV[VX] = x; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setVelocityX" << LL_ENDL; + } } -void LLPrimitive::setVelocityY(const F32 y) -{ - if (llfinite(y)) - { - mVelocity.mV[VY] = y; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setVelocityY" << LL_ENDL; - } +void LLPrimitive::setVelocityY(const F32 y) +{ + if (llfinite(y)) + { + mVelocity.mV[VY] = y; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setVelocityY" << LL_ENDL; + } } -void LLPrimitive::setVelocityZ(const F32 z) -{ - if (llfinite(z)) - { - mVelocity.mV[VZ] = z; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setVelocityZ" << LL_ENDL; - } +void LLPrimitive::setVelocityZ(const F32 z) +{ + if (llfinite(z)) + { + mVelocity.mV[VZ] = z; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setVelocityZ" << LL_ENDL; + } } -void LLPrimitive::addVelocity(const LLVector3& vel) -{ - if (vel.isFinite()) - { - mVelocity += vel; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::addVelocity" << LL_ENDL; - } +void LLPrimitive::addVelocity(const LLVector3& vel) +{ + if (vel.isFinite()) + { + mVelocity += vel; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::addVelocity" << LL_ENDL; + } } -void LLPrimitive::setAcceleration(const LLVector3& accel) -{ - if (accel.isFinite()) - { - mAcceleration = accel; - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } +void LLPrimitive::setAcceleration(const LLVector3& accel) +{ + if (accel.isFinite()) + { + mAcceleration = accel; + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } -void LLPrimitive::setAcceleration(const F32 x, const F32 y, const F32 z) -{ - if (llfinite(x) && llfinite(y) && llfinite(z)) - { - mAcceleration.setVec(x,y,z); - } - else - { - LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; - } +void LLPrimitive::setAcceleration(const F32 x, const F32 y, const F32 z) +{ + if (llfinite(x) && llfinite(y) && llfinite(z)) + { + mAcceleration.setVec(x,y,z); + } + else + { + LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL; + } } #endif // CHECK_FOR_FINITE inline BOOL LLPrimitive::validTE(const U8 te_num) const { - return (mNumTEs && te_num < mNumTEs); + return (mNumTEs && te_num < mNumTEs); } #endif diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index ee2a4c769a..2ed8f8c044 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltextureentry.cpp * @brief LLTextureEntry base class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,10 +52,10 @@ const LLTextureEntry LLTextureEntry::null; static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:"; -// static +// static LLTextureEntry* LLTextureEntry::newTextureEntry() { - return new LLTextureEntry(); + return new LLTextureEntry(); } //=============================================================== @@ -64,7 +64,7 @@ LLTextureEntry::LLTextureEntry() , mSelected(false) , mMaterialUpdatePending(false) { - init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); + init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) @@ -72,7 +72,7 @@ LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) , mSelected(false) , mMaterialUpdatePending(false) { - init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); + init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) @@ -85,30 +85,30 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) { - if (this != &rhs) - { - mID = rhs.mID; - mScaleS = rhs.mScaleS; - mScaleT = rhs.mScaleT; - mOffsetS = rhs.mOffsetS; - mOffsetT = rhs.mOffsetT; - mRotation = rhs.mRotation; - mColor = rhs.mColor; - mBump = rhs.mBump; - mMediaFlags = rhs.mMediaFlags; - mGlow = rhs.mGlow; - mMaterialID = rhs.mMaterialID; - mMaterial = rhs.mMaterial; - if (mMediaEntry != NULL) { - delete mMediaEntry; - } - if (rhs.mMediaEntry != NULL) { - // Make a copy - mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); - } - else { - mMediaEntry = NULL; - } + if (this != &rhs) + { + mID = rhs.mID; + mScaleS = rhs.mScaleS; + mScaleT = rhs.mScaleT; + mOffsetS = rhs.mOffsetS; + mOffsetT = rhs.mOffsetT; + mRotation = rhs.mRotation; + mColor = rhs.mColor; + mBump = rhs.mBump; + mMediaFlags = rhs.mMediaFlags; + mGlow = rhs.mGlow; + mMaterialID = rhs.mMaterialID; + mMaterial = rhs.mMaterial; + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + if (rhs.mMediaEntry != NULL) { + // Make a copy + mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); + } + else { + mMediaEntry = NULL; + } mMaterialID = rhs.mMaterialID; @@ -121,7 +121,7 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) { mGLTFMaterial->addTextureEntry(this); } - + if (rhs.mGLTFMaterialOverrides.notNull()) { mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides); @@ -130,39 +130,39 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) { mGLTFMaterialOverrides = nullptr; } - } + } - return *this; + return *this; } void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump) { - setID(tex_id); + setID(tex_id); - mScaleS = scale_s; - mScaleT = scale_t; - mOffsetS = offset_s; - mOffsetT = offset_t; - mRotation = rotation; - mBump = bump; - mMediaFlags = 0x0; + mScaleS = scale_s; + mScaleT = scale_t; + mOffsetS = offset_s; + mOffsetT = offset_t; + mRotation = rotation; + mBump = bump; + mMediaFlags = 0x0; mGlow = 0; - mMaterialID.clear(); - - setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); - if (mMediaEntry != NULL) { - delete mMediaEntry; - } - mMediaEntry = NULL; + mMaterialID.clear(); + + setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + mMediaEntry = NULL; } LLTextureEntry::~LLTextureEntry() { - if(mMediaEntry) - { - delete mMediaEntry; - mMediaEntry = NULL; - } + if(mMediaEntry) + { + delete mMediaEntry; + mMediaEntry = NULL; + } if (mGLTFMaterial) { @@ -173,64 +173,64 @@ LLTextureEntry::~LLTextureEntry() bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const { - if (mID != rhs.mID) return(true); - if (mScaleS != rhs.mScaleS) return(true); - if (mScaleT != rhs.mScaleT) return(true); - if (mOffsetS != rhs.mOffsetS) return(true); - if (mOffsetT != rhs.mOffsetT) return(true); - if (mRotation != rhs.mRotation) return(true); - if (mColor != rhs.mColor) return (true); - if (mBump != rhs.mBump) return (true); - if (mMediaFlags != rhs.mMediaFlags) return (true); - if (mGlow != rhs.mGlow) return (true); - if (mMaterialID != rhs.mMaterialID) return (true); - return(false); + if (mID != rhs.mID) return(true); + if (mScaleS != rhs.mScaleS) return(true); + if (mScaleT != rhs.mScaleT) return(true); + if (mOffsetS != rhs.mOffsetS) return(true); + if (mOffsetT != rhs.mOffsetT) return(true); + if (mRotation != rhs.mRotation) return(true); + if (mColor != rhs.mColor) return (true); + if (mBump != rhs.mBump) return (true); + if (mMediaFlags != rhs.mMediaFlags) return (true); + if (mGlow != rhs.mGlow) return (true); + if (mMaterialID != rhs.mMaterialID) return (true); + return(false); } bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const { - if (mID != rhs.mID) return(false); - if (mScaleS != rhs.mScaleS) return(false); - if (mScaleT != rhs.mScaleT) return(false); - if (mOffsetS != rhs.mOffsetS) return(false); - if (mOffsetT != rhs.mOffsetT) return(false); - if (mRotation != rhs.mRotation) return(false); - if (mColor != rhs.mColor) return (false); - if (mBump != rhs.mBump) return (false); - if (mMediaFlags != rhs.mMediaFlags) return false; - if (mGlow != rhs.mGlow) return false; - if (mMaterialID != rhs.mMaterialID) return (false); - return(true); + if (mID != rhs.mID) return(false); + if (mScaleS != rhs.mScaleS) return(false); + if (mScaleT != rhs.mScaleT) return(false); + if (mOffsetS != rhs.mOffsetS) return(false); + if (mOffsetT != rhs.mOffsetT) return(false); + if (mRotation != rhs.mRotation) return(false); + if (mColor != rhs.mColor) return (false); + if (mBump != rhs.mBump) return (false); + if (mMediaFlags != rhs.mMediaFlags) return false; + if (mGlow != rhs.mGlow) return false; + if (mMaterialID != rhs.mMaterialID) return (false); + return(true); } LLSD LLTextureEntry::asLLSD() const { - LLSD sd; - asLLSD(sd); - return sd; + LLSD sd; + asLLSD(sd); + return sd; } void LLTextureEntry::asLLSD(LLSD& sd) const { LL_PROFILE_ZONE_SCOPED; - sd["imageid"] = mID; - sd["colors"] = ll_sd_from_color4(mColor); - sd["scales"] = mScaleS; - sd["scalet"] = mScaleT; - sd["offsets"] = mOffsetS; - sd["offsett"] = mOffsetT; - sd["imagerot"] = mRotation; - sd["bump"] = getBumpShiny(); - sd["fullbright"] = getFullbright(); - sd["media_flags"] = mMediaFlags; - if (hasMedia()) { - LLSD mediaData; + sd["imageid"] = mID; + sd["colors"] = ll_sd_from_color4(mColor); + sd["scales"] = mScaleS; + sd["scalet"] = mScaleT; + sd["offsets"] = mOffsetS; + sd["offsett"] = mOffsetT; + sd["imagerot"] = mRotation; + sd["bump"] = getBumpShiny(); + sd["fullbright"] = getFullbright(); + sd["media_flags"] = mMediaFlags; + if (hasMedia()) { + LLSD mediaData; if (NULL != getMediaData()) { getMediaData()->asLLSD(mediaData); } - sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; - } - sd["glow"] = mGlow; + sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; + } + sd["glow"] = mGlow; if (mGLTFMaterialOverrides.notNull()) { @@ -241,65 +241,65 @@ void LLTextureEntry::asLLSD(LLSD& sd) const bool LLTextureEntry::fromLLSD(const LLSD& sd) { LL_PROFILE_ZONE_SCOPED; - const char *w, *x; - w = "imageid"; - if (sd.has(w)) - { - setID( sd[w] ); - } else goto fail; - w = "colors"; - if (sd.has(w)) - { - setColor( ll_color4_from_sd(sd["colors"]) ); - } else goto fail; - w = "scales"; - x = "scalet"; - if (sd.has(w) && sd.has(x)) - { - setScale( (F32)sd[w].asReal(), (F32)sd[x].asReal() ); - } else goto fail; - w = "offsets"; - x = "offsett"; - if (sd.has(w) && sd.has(x)) - { - setOffset( (F32)sd[w].asReal(), (F32)sd[x].asReal() ); - } else goto fail; - w = "imagerot"; - if (sd.has(w)) - { - setRotation( (F32)sd[w].asReal() ); - } else goto fail; - w = "bump"; - if (sd.has(w)) - { - setBumpShiny( sd[w].asInteger() ); - } else goto fail; - w = "fullbright"; - if (sd.has(w)) - { - setFullbright( sd[w].asInteger() ); - } else goto fail; - w = "media_flags"; - if (sd.has(w)) - { - setMediaTexGen( sd[w].asInteger() ); - } else goto fail; - // If the "has media" flag doesn't match the fact that - // media data exists, updateMediaData will "fix" it - // by either clearing or setting the flag - w = TEXTURE_MEDIA_DATA_KEY; - if (hasMedia() != sd.has(w)) - { - LL_WARNS() << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() << - ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << LL_ENDL; - } - updateMediaData(sd[w]); - - w = "glow"; - if (sd.has(w)) - { - setGlow((F32)sd[w].asReal() ); - } + const char *w, *x; + w = "imageid"; + if (sd.has(w)) + { + setID( sd[w] ); + } else goto fail; + w = "colors"; + if (sd.has(w)) + { + setColor( ll_color4_from_sd(sd["colors"]) ); + } else goto fail; + w = "scales"; + x = "scalet"; + if (sd.has(w) && sd.has(x)) + { + setScale( (F32)sd[w].asReal(), (F32)sd[x].asReal() ); + } else goto fail; + w = "offsets"; + x = "offsett"; + if (sd.has(w) && sd.has(x)) + { + setOffset( (F32)sd[w].asReal(), (F32)sd[x].asReal() ); + } else goto fail; + w = "imagerot"; + if (sd.has(w)) + { + setRotation( (F32)sd[w].asReal() ); + } else goto fail; + w = "bump"; + if (sd.has(w)) + { + setBumpShiny( sd[w].asInteger() ); + } else goto fail; + w = "fullbright"; + if (sd.has(w)) + { + setFullbright( sd[w].asInteger() ); + } else goto fail; + w = "media_flags"; + if (sd.has(w)) + { + setMediaTexGen( sd[w].asInteger() ); + } else goto fail; + // If the "has media" flag doesn't match the fact that + // media data exists, updateMediaData will "fix" it + // by either clearing or setting the flag + w = TEXTURE_MEDIA_DATA_KEY; + if (hasMedia() != sd.has(w)) + { + LL_WARNS() << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() << + ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << LL_ENDL; + } + updateMediaData(sd[w]); + + w = "glow"; + if (sd.has(w)) + { + setGlow((F32)sd[w].asReal() ); + } w = "gltf_override"; if (sd.has(w)) @@ -319,217 +319,217 @@ bool LLTextureEntry::fromLLSD(const LLSD& sd) } } - return true; + return true; fail: - return false; + return false; } -// virtual +// virtual // override this method for each derived class LLTextureEntry* LLTextureEntry::newBlank() const { - return new LLTextureEntry(); + return new LLTextureEntry(); } -// virtual +// virtual LLTextureEntry* LLTextureEntry::newCopy() const { - return new LLTextureEntry(*this); + return new LLTextureEntry(*this); } S32 LLTextureEntry::setID(const LLUUID &tex_id) { - if (mID != tex_id) - { - mID = tex_id; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + if (mID != tex_id) + { + mID = tex_id; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setScale(F32 s, F32 t) { - S32 retval = 0; + S32 retval = 0; - if ( (mScaleS != s) - ||(mScaleT != t)) - { - mScaleS = s; - mScaleT = t; + if ( (mScaleS != s) + ||(mScaleT != t)) + { + mScaleS = s; + mScaleT = t; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setScaleS(F32 s) { - S32 retval = TEM_CHANGE_NONE; - if (mScaleS != s) - { - mScaleS = s; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + S32 retval = TEM_CHANGE_NONE; + if (mScaleS != s) + { + mScaleS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setScaleT(F32 t) { - S32 retval = TEM_CHANGE_NONE; - if (mScaleT != t) - { - mScaleT = t; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + S32 retval = TEM_CHANGE_NONE; + if (mScaleT != t) + { + mScaleT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setColor(const LLColor4 &color) { - if (mColor != color) - { - mColor = color; - return TEM_CHANGE_COLOR; - } - return TEM_CHANGE_NONE; + if (mColor != color) + { + mColor = color; + return TEM_CHANGE_COLOR; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setColor(const LLColor3 &color) { - if (mColor != color) - { - // This preserves alpha. - mColor.setVec(color); - return TEM_CHANGE_COLOR; - } - return TEM_CHANGE_NONE; + if (mColor != color) + { + // This preserves alpha. + mColor.setVec(color); + return TEM_CHANGE_COLOR; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setAlpha(const F32 alpha) { - if (mColor.mV[VW] != alpha) - { - mColor.mV[VW] = alpha; - return TEM_CHANGE_COLOR; - } - return TEM_CHANGE_NONE; + if (mColor.mV[VW] != alpha) + { + mColor.mV[VW] = alpha; + return TEM_CHANGE_COLOR; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setOffset(F32 s, F32 t) { - S32 retval = 0; + S32 retval = 0; - if ( (mOffsetS != s) - ||(mOffsetT != t)) - { - mOffsetS = s; - mOffsetT = t; + if ( (mOffsetS != s) + ||(mOffsetT != t)) + { + mOffsetS = s; + mOffsetT = t; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setOffsetS(F32 s) { - S32 retval = 0; - if (mOffsetS != s) - { - mOffsetS = s; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + S32 retval = 0; + if (mOffsetS != s) + { + mOffsetS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setOffsetT(F32 t) { - S32 retval = 0; - if (mOffsetT != t) - { - mOffsetT = t; - retval = TEM_CHANGE_TEXTURE; - } - return retval; + S32 retval = 0; + if (mOffsetT != t) + { + mOffsetT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; } S32 LLTextureEntry::setRotation(F32 theta) { - if (mRotation != theta && llfinite(theta)) - { - mRotation = theta; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + if (mRotation != theta && llfinite(theta)) + { + mRotation = theta; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) { - if (mBump != bump) - { - mBump = bump; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + if (mBump != bump) + { + mBump = bump; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaTexGen(U8 media) { - S32 result = TEM_CHANGE_NONE; - result |= setTexGen(media & TEM_TEX_GEN_MASK); - result |= setMediaFlags(media & TEM_MEDIA_MASK); - return result; + S32 result = TEM_CHANGE_NONE; + result |= setTexGen(media & TEM_TEX_GEN_MASK); + result |= setMediaFlags(media & TEM_MEDIA_MASK); + return result; } S32 LLTextureEntry::setBumpmap(U8 bump) { - bump &= TEM_BUMP_MASK; - if (getBumpmap() != bump) - { - mBump &= ~TEM_BUMP_MASK; - mBump |= bump; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + bump &= TEM_BUMP_MASK; + if (getBumpmap() != bump) + { + mBump &= ~TEM_BUMP_MASK; + mBump |= bump; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setFullbright(U8 fullbright) { - fullbright &= TEM_FULLBRIGHT_MASK; - if (getFullbright() != fullbright) - { - mBump &= ~(TEM_FULLBRIGHT_MASK<isClearedForBaseMaterial()); return getGLTFMaterial(); } @@ -616,77 +616,77 @@ S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat) S32 LLTextureEntry::setMediaFlags(U8 media_flags) { - media_flags &= TEM_MEDIA_MASK; - if (getMediaFlags() != media_flags) - { - mMediaFlags &= ~TEM_MEDIA_MASK; - mMediaFlags |= media_flags; - - // Special code for media handling - if( hasMedia() && mMediaEntry == NULL) - { - mMediaEntry = new LLMediaEntry; - } + media_flags &= TEM_MEDIA_MASK; + if (getMediaFlags() != media_flags) + { + mMediaFlags &= ~TEM_MEDIA_MASK; + mMediaFlags |= media_flags; + + // Special code for media handling + if( hasMedia() && mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } else if ( ! hasMedia() && mMediaEntry != NULL) { delete mMediaEntry; mMediaEntry = NULL; } - - return TEM_CHANGE_MEDIA; - } - return TEM_CHANGE_NONE; + + return TEM_CHANGE_MEDIA; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setTexGen(U8 tex_gen) { - tex_gen &= TEM_TEX_GEN_MASK; - if (getTexGen() != tex_gen) - { - mMediaFlags &= ~TEM_TEX_GEN_MASK; - mMediaFlags |= tex_gen; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + tex_gen &= TEM_TEX_GEN_MASK; + if (getTexGen() != tex_gen) + { + mMediaFlags &= ~TEM_TEX_GEN_MASK; + mMediaFlags |= tex_gen; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setGlow(F32 glow) { - if (mGlow != glow) - { - mGlow = glow; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + if (mGlow != glow) + { + mGlow = glow; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID) { - if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) ) - { - if (mSelected) - { - mMaterialUpdatePending = true; - mMaterialID = pMaterialID; - return TEM_CHANGE_TEXTURE; - } + if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) ) + { + if (mSelected) + { + mMaterialUpdatePending = true; + mMaterialID = pMaterialID; + return TEM_CHANGE_TEXTURE; + } - mMaterialUpdatePending = false; - mMaterialID = pMaterialID; - return TEM_CHANGE_TEXTURE; - } - return TEM_CHANGE_NONE; + mMaterialUpdatePending = false; + mMaterialID = pMaterialID; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) { - if (mSelected) - { - mMaterialUpdatePending = true; - } - mMaterial = pMaterialParams; - - return TEM_CHANGE_TEXTURE; + if (mSelected) + { + mMaterialUpdatePending = true; + } + mMaterial = pMaterialParams; + + return TEM_CHANGE_TEXTURE; } void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry) @@ -701,23 +701,23 @@ void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry) bool LLTextureEntry::updateMediaData(const LLSD& media_data) { - if (media_data.isUndefined()) - { - // clear the media data + if (media_data.isUndefined()) + { + // clear the media data clearMediaData(); - return false; - } - else { - mMediaFlags |= MF_HAS_MEDIA; - if (mMediaEntry == NULL) - { - mMediaEntry = new LLMediaEntry; - } - // *NOTE: this will *clobber* all of the fields in mMediaEntry + return false; + } + else { + mMediaFlags |= MF_HAS_MEDIA; + if (mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + // *NOTE: this will *clobber* all of the fields in mMediaEntry // with whatever fields are present (or not present) in media_data! - mMediaEntry->fromLLSD(media_data); - return true; - } + mMediaEntry->fromLLSD(media_data); + return true; + } } void LLTextureEntry::clearMediaData() @@ -727,7 +727,7 @@ void LLTextureEntry::clearMediaData() delete mMediaEntry; } mMediaEntry = NULL; -} +} void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields) { @@ -760,10 +760,10 @@ std::string LLTextureEntry::touchMediaVersionString(const std::string &in_versio U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string) { U32 version = 0; - if (!version_string.empty()) + if (!version_string.empty()) { size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); - if (found != std::string::npos) + if (found != std::string::npos) { found = version_string.find_first_of("/", found); std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found); @@ -777,13 +777,13 @@ U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_ LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string) { LLUUID id; - if (!version_string.empty()) + if (!version_string.empty()) { size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); - if (found != std::string::npos) + if (found != std::string::npos) { found = version_string.find_first_of("/", found); - if (found != std::string::npos) + if (found != std::string::npos) { std::string v = version_string.substr(found + 1); id.set(v); @@ -796,5 +796,5 @@ LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &versi //static bool LLTextureEntry::isMediaVersionString(const std::string &version_string) { - return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX); + return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX); } diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index be5ad08fbe..28b5bc7495 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -422,27 +422,27 @@ BOOL LLGLSLShader::createShader(std::vector* attributes, mUsingBinaryProgram = LLShaderMgr::instance()->loadCachedProgramBinary(this); - if (!mUsingBinaryProgram) - { + if (!mUsingBinaryProgram) + { #if DEBUG_SHADER_INCLUDES - fprintf(stderr, "--- %s ---\n", mName.c_str()); + fprintf(stderr, "--- %s ---\n", mName.c_str()); #endif // DEBUG_SHADER_INCLUDES //compile new source - vector< pair >::iterator fileIter = mShaderFiles.begin(); - for (; fileIter != mShaderFiles.end(); fileIter++) - { - GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); - LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; - if (shaderhandle) - { - attachObject(shaderhandle); - } - else - { - success = FALSE; - } - } + vector< pair >::iterator fileIter = mShaderFiles.begin(); + for (; fileIter != mShaderFiles.end(); fileIter++) + { + GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); + LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; + if (shaderhandle) + { + attachObject(shaderhandle); + } + else + { + success = FALSE; + } + } } // Attach existing objects @@ -606,19 +606,19 @@ BOOL LLGLSLShader::mapAttributes(const std::vector* attrib { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; - BOOL res = TRUE; - if (!mUsingBinaryProgram) - { - //before linking, make sure reserved attributes always have consistent locations - for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) - { - const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); - glBindAttribLocation(mProgramObject, i, (const GLchar*)name); - } + BOOL res = TRUE; + if (!mUsingBinaryProgram) + { + //before linking, make sure reserved attributes always have consistent locations + for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) + { + const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); + glBindAttribLocation(mProgramObject, i, (const GLchar*)name); + } - //link the program - res = link(); - } + //link the program + res = link(); + } mAttribute.clear(); U32 numAttributes = (attributes == NULL) ? 0 : attributes->size(); @@ -1184,14 +1184,14 @@ S32 LLGLSLShader::getTextureChannel(S32 uniform) const S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; - + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; return -1; } - + S32 index = mTexture[uniform]; if (index != -1) { diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index ed0f27d143..d7741c51bb 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -234,7 +234,7 @@ public: void addConstant(const LLGLSLShader::eShaderConsts shader_const); //enable/disable texture channel for specified uniform - //if given texture uniform is active in the shader, + //if given texture uniform is active in the shader, //the corresponding channel will be active upon return //returns channel texture is enabled in from [0-MAX) S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR); @@ -256,7 +256,7 @@ public: void bind(); //helper to conditionally bind mRiggedVariant instead of this void bind(bool rigged); - + bool isComplete() const { return mProgramObject != 0; } LLUUID hash(); @@ -330,11 +330,11 @@ private: }; //UI shader (declared here so llui_libtest will link properly) -extern LLGLSLShader gUIProgram; +extern LLGLSLShader gUIProgram; //output vec4(color.rgb,color.a*tex0[tc0].a) -extern LLGLSLShader gSolidColorProgram; +extern LLGLSLShader gSolidColorProgram; //Alpha mask shader (declared here so llappearance can access properly) -extern LLGLSLShader gAlphaMaskProgram; +extern LLGLSLShader gAlphaMaskProgram; #ifdef LL_PROFILER_ENABLE_RENDER_DOC #define LL_SET_SHADER_LABEL(shader) shader.setLabel(#shader) diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index a590a8e745..be4fc85985 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llgltexture.cpp * @brief Opengl texture implementation * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,366 +29,366 @@ LLGLTexture::LLGLTexture(BOOL usemipmaps) { - init(); - mUseMipMaps = usemipmaps; + init(); + mUseMipMaps = usemipmaps; } LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) { - init(); - mFullWidth = width ; - mFullHeight = height ; - mUseMipMaps = usemipmaps; - mComponents = components ; - setTexelsPerImage(); + init(); + mFullWidth = width ; + mFullHeight = height ; + mUseMipMaps = usemipmaps; + mComponents = components ; + setTexelsPerImage(); } LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) { - init(); - mUseMipMaps = usemipmaps ; - // Create an empty image of the specified size and width - mGLTexturep = new LLImageGL(raw, usemipmaps) ; + init(); + mUseMipMaps = usemipmaps ; + // Create an empty image of the specified size and width + mGLTexturep = new LLImageGL(raw, usemipmaps) ; } LLGLTexture::~LLGLTexture() { - cleanup(); + cleanup(); } void LLGLTexture::init() { - mBoostLevel = LLGLTexture::BOOST_NONE; + mBoostLevel = LLGLTexture::BOOST_NONE; - mFullWidth = 0; - mFullHeight = 0; - mTexelsPerImage = 0 ; - mUseMipMaps = FALSE ; - mComponents = 0 ; + mFullWidth = 0; + mFullHeight = 0; + mTexelsPerImage = 0 ; + mUseMipMaps = FALSE ; + mComponents = 0 ; - mTextureState = NO_DELETE ; - mDontDiscard = FALSE; - mNeedsGLTexture = FALSE ; + mTextureState = NO_DELETE ; + mDontDiscard = FALSE; + mNeedsGLTexture = FALSE ; } void LLGLTexture::cleanup() { - if(mGLTexturep) - { - mGLTexturep->cleanup(); - } + if(mGLTexturep) + { + mGLTexturep->cleanup(); + } } // virtual void LLGLTexture::dump() { - if(mGLTexturep) - { - mGLTexturep->dump(); - } + if(mGLTexturep) + { + mGLTexturep->dump(); + } } void LLGLTexture::setBoostLevel(S32 level) { - if(mBoostLevel != level) - { - mBoostLevel = level ; - if(mBoostLevel != LLGLTexture::BOOST_NONE - && mBoostLevel != LLGLTexture::BOOST_ICON + if(mBoostLevel != level) + { + mBoostLevel = level ; + if(mBoostLevel != LLGLTexture::BOOST_NONE + && mBoostLevel != LLGLTexture::BOOST_ICON && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL && mBoostLevel != LLGLTexture::BOOST_TERRAIN) - { - setNoDelete() ; - } - } + { + setNoDelete() ; + } + } } void LLGLTexture::forceActive() { - mTextureState = ACTIVE ; + mTextureState = ACTIVE ; } -void LLGLTexture::setActive() -{ - if(mTextureState != NO_DELETE) - { - mTextureState = ACTIVE ; - } +void LLGLTexture::setActive() +{ + if(mTextureState != NO_DELETE) + { + mTextureState = ACTIVE ; + } } //set the texture to stay in memory -void LLGLTexture::setNoDelete() -{ - mTextureState = NO_DELETE ; +void LLGLTexture::setNoDelete() +{ + mTextureState = NO_DELETE ; } -void LLGLTexture::generateGLTexture() -{ - if(mGLTexturep.isNull()) - { - mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; - } +void LLGLTexture::generateGLTexture() +{ + if(mGLTexturep.isNull()) + { + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; + } } LLImageGL* LLGLTexture::getGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep ; + return mGLTexturep ; } -BOOL LLGLTexture::createGLTexture() +BOOL LLGLTexture::createGLTexture() { - if(mGLTexturep.isNull()) - { - generateGLTexture() ; - } + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } - return mGLTexturep->createGLTexture() ; + return mGLTexturep->createGLTexture() ; } BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()); - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ; + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ; - if(ret) - { - mFullWidth = mGLTexturep->getCurrentWidth() ; - mFullHeight = mGLTexturep->getCurrentHeight() ; - mComponents = mGLTexturep->getComponents() ; - setTexelsPerImage(); - } + if(ret) + { + mFullWidth = mGLTexturep->getCurrentWidth() ; + mFullHeight = mGLTexturep->getCurrentHeight() ; + mComponents = mGLTexturep->getComponents() ; + setTexelsPerImage(); + } - return ret ; + return ret ; } void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { - llassert(mGLTexturep.notNull()) ; - - mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; + llassert(mGLTexturep.notNull()) ; + + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; } void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setAddressMode(mode) ; + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setAddressMode(mode) ; } void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setFilteringOption(option) ; + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setFilteringOption(option) ; } //virtual -S32 LLGLTexture::getWidth(S32 discard_level) const +S32 LLGLTexture::getWidth(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getWidth(discard_level) ; + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getWidth(discard_level) ; } //virtual -S32 LLGLTexture::getHeight(S32 discard_level) const +S32 LLGLTexture::getHeight(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getHeight(discard_level) ; + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getHeight(discard_level) ; } S32 LLGLTexture::getMaxDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMaxDiscardLevel() ; + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getMaxDiscardLevel() ; } S32 LLGLTexture::getDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevel() ; + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getDiscardLevel() ; } -S8 LLGLTexture::getComponents() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getComponents() ; +S8 LLGLTexture::getComponents() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getComponents() ; } -LLGLuint LLGLTexture::getTexName() const -{ - llassert(mGLTexturep.notNull()) ; +LLGLuint LLGLTexture::getTexName() const +{ + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexName() ; + return mGLTexturep->getTexName() ; } -BOOL LLGLTexture::hasGLTexture() const +BOOL LLGLTexture::hasGLTexture() const { - if(mGLTexturep.notNull()) - { - return mGLTexturep->getHasGLTexture() ; - } - return FALSE ; + if(mGLTexturep.notNull()) + { + return mGLTexturep->getHasGLTexture() ; + } + return FALSE ; } BOOL LLGLTexture::getBoundRecently() const { - if(mGLTexturep.notNull()) - { - return mGLTexturep->getBoundRecently() ; - } - return FALSE ; + if(mGLTexturep.notNull()) + { + return mGLTexturep->getBoundRecently() ; + } + return FALSE ; } LLTexUnit::eTextureType LLGLTexture::getTarget(void) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTarget() ; + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getTarget() ; } BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ; + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ; } BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ; + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ; } void LLGLTexture::setGLTextureCreated (bool initialized) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - mGLTexturep->setGLTextureCreated (initialized) ; + mGLTexturep->setGLTextureCreated (initialized) ; } -void LLGLTexture::setCategory(S32 category) +void LLGLTexture::setCategory(S32 category) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - mGLTexturep->setCategory(category) ; + mGLTexturep->setCategory(category) ; } void LLGLTexture::setTexName(LLGLuint texName) { llassert(mGLTexturep.notNull()); - return mGLTexturep->setTexName(texName); + return mGLTexturep->setTexName(texName); } void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target) { llassert(mGLTexturep.notNull()); - return mGLTexturep->setTarget(target, bind_target); + return mGLTexturep->setTarget(target, bind_target); } LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getAddressMode() ; + return mGLTexturep->getAddressMode() ; } S32Bytes LLGLTexture::getTextureMemory() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->mTextureMemory ; + return mGLTexturep->mTextureMemory ; } LLGLenum LLGLTexture::getPrimaryFormat() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getPrimaryFormat() ; + return mGLTexturep->getPrimaryFormat() ; } BOOL LLGLTexture::getIsAlphaMask() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getIsAlphaMask() ; + return mGLTexturep->getIsAlphaMask() ; } BOOL LLGLTexture::getMask(const LLVector2 &tc) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMask(tc) ; + return mGLTexturep->getMask(tc) ; } F32 LLGLTexture::getTimePassedSinceLastBound() { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTimePassedSinceLastBound() ; + return mGLTexturep->getTimePassedSinceLastBound() ; } -BOOL LLGLTexture::getMissed() const +BOOL LLGLTexture::getMissed() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMissed() ; + return mGLTexturep->getMissed() ; } BOOL LLGLTexture::isJustBound() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->isJustBound() ; + return mGLTexturep->isJustBound() ; } void LLGLTexture::forceUpdateBindStats(void) const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->forceUpdateBindStats() ; + return mGLTexturep->forceUpdateBindStats() ; } U32 LLGLTexture::getTexelsInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexelsInAtlas() ; + return mGLTexturep->getTexelsInAtlas() ; } U32 LLGLTexture::getTexelsInGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexelsInGLTexture() ; + return mGLTexturep->getTexelsInGLTexture() ; } BOOL LLGLTexture::isGLTextureCreated() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->isGLTextureCreated() ; + return mGLTexturep->isGLTextureCreated() ; } S32 LLGLTexture::getDiscardLevelInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevelInAtlas() ; + return mGLTexturep->getDiscardLevelInAtlas() ; } -void LLGLTexture::destroyGLTexture() +void LLGLTexture::destroyGLTexture() { - if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) - { - mGLTexturep->destroyGLTexture() ; - mTextureState = DELETED ; - } + if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) + { + mGLTexturep->destroyGLTexture() ; + mTextureState = DELETED ; + } } void LLGLTexture::setTexelsPerImage() { - U32 fullwidth = llmin(mFullWidth,U32(MAX_IMAGE_SIZE_DEFAULT)); - U32 fullheight = llmin(mFullHeight,U32(MAX_IMAGE_SIZE_DEFAULT)); - mTexelsPerImage = (U32)fullwidth * fullheight; + U32 fullwidth = llmin(mFullWidth,U32(MAX_IMAGE_SIZE_DEFAULT)); + U32 fullheight = llmin(mFullHeight,U32(MAX_IMAGE_SIZE_DEFAULT)); + mTexelsPerImage = (U32)fullwidth * fullheight; } static LLUUID sStubUUID; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index fa6faa2583..f5bef0e291 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -1,25 +1,25 @@ -/** +/** * @file llgltexture.h * @brief Object for managing opengl textures * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,87 +40,87 @@ class LLImageRaw; class LLGLTexture : public LLTexture { public: - enum - { - MAX_IMAGE_SIZE_DEFAULT = 2048, - INVALID_DISCARD_LEVEL = 0x7fff - }; - - enum EBoostLevel - { - BOOST_NONE = 0, - BOOST_AVATAR , + enum + { + MAX_IMAGE_SIZE_DEFAULT = 2048, + INVALID_DISCARD_LEVEL = 0x7fff + }; + + enum EBoostLevel + { + BOOST_NONE = 0, + BOOST_AVATAR , BOOST_AVATAR_BAKED , - BOOST_SCULPTED , + BOOST_SCULPTED , BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead. - - BOOST_HIGH = 10, - BOOST_BUMP , + + BOOST_HIGH = 10, + BOOST_BUMP , BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug - BOOST_SELECTED , - BOOST_AVATAR_BAKED_SELF , - BOOST_AVATAR_SELF , // needed for baking avatar - BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay. - BOOST_HUD , - BOOST_ICON , - BOOST_THUMBNAIL , - BOOST_UI , - BOOST_PREVIEW , - BOOST_MAP , - BOOST_MAP_VISIBLE , - BOOST_MAX_LEVEL, - - //other texture Categories - LOCAL = BOOST_MAX_LEVEL, - AVATAR_SCRATCH_TEX, - DYNAMIC_TEX, - MEDIA, - ATLAS, - OTHER, - MAX_GL_IMAGE_CATEGORY - }; - - typedef enum - { - DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). - ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). - NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTextureState; + BOOST_SELECTED , + BOOST_AVATAR_BAKED_SELF , + BOOST_AVATAR_SELF , // needed for baking avatar + BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay. + BOOST_HUD , + BOOST_ICON , + BOOST_THUMBNAIL , + BOOST_UI , + BOOST_PREVIEW , + BOOST_MAP , + BOOST_MAP_VISIBLE , + BOOST_MAX_LEVEL, + + //other texture Categories + LOCAL = BOOST_MAX_LEVEL, + AVATAR_SCRATCH_TEX, + DYNAMIC_TEX, + MEDIA, + ATLAS, + OTHER, + MAX_GL_IMAGE_CATEGORY + }; + + typedef enum + { + DELETED = 0, //removed from memory + DELETION_CANDIDATE, //ready to be removed from memory + INACTIVE, //not be used for the last certain period (i.e., 30 seconds). + ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). + NO_DELETE = 99 //stay in memory, can not be removed. + } LLGLTextureState; protected: - virtual ~LLGLTexture(); - LOG_CLASS(LLGLTexture); + virtual ~LLGLTexture(); + LOG_CLASS(LLGLTexture); public: - LLGLTexture(BOOL usemipmaps = TRUE); - LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ; - LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + LLGLTexture(BOOL usemipmaps = TRUE); + LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual void dump(); // debug info to LL_INFOS() - virtual void dump(); // debug info to LL_INFOS() + virtual const LLUUID& getID() const; - virtual const LLUUID& getID() const; + void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } - void setBoostLevel(S32 level); - S32 getBoostLevel() { return mBoostLevel; } + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } - S32 getFullWidth() const { return mFullWidth; } - S32 getFullHeight() const { return mFullHeight; } + void generateGLTexture() ; + void destroyGLTexture() ; - void generateGLTexture() ; - void destroyGLTexture() ; + //--------------------------------------------------------------------------------------------- + //functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + /*virtual*/S32 getWidth(S32 discard_level = -1) const; + /*virtual*/S32 getHeight(S32 discard_level = -1) const; - //--------------------------------------------------------------------------------------------- - //functions to access LLImageGL - //--------------------------------------------------------------------------------------------- - /*virtual*/S32 getWidth(S32 discard_level = -1) const; - /*virtual*/S32 getHeight(S32 discard_level = -1) const; + BOOL hasGLTexture() const ; + LLGLuint getTexName() const ; + BOOL createGLTexture() ; - BOOL hasGLTexture() const ; - LLGLuint getTexName() const ; - BOOL createGLTexture() ; - // Create a GL Texture from an image raw // discard_level - mip level, 0 for highest resultion mip // imageraw - the image to copy from @@ -131,74 +131,74 @@ public: // tex_name - if not null, will be set to the GL name of the texture created BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr); - void setFilteringOption(LLTexUnit::eTextureFilterOptions option); - void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); - void setAddressMode(LLTexUnit::eTextureAddressMode mode); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); - void setGLTextureCreated (bool initialized); - void setCategory(S32 category) ; + void setFilteringOption(LLTexUnit::eTextureFilterOptions option); + void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); + void setAddressMode(LLTexUnit::eTextureAddressMode mode); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); + void setGLTextureCreated (bool initialized); + void setCategory(S32 category) ; void setTexName(LLGLuint); // for forcing w/ externally created textures only void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target); - LLTexUnit::eTextureAddressMode getAddressMode(void) const ; - S32 getMaxDiscardLevel() const; - S32 getDiscardLevel() const; - S8 getComponents() const; - BOOL getBoundRecently() const; - S32Bytes getTextureMemory() const ; - LLGLenum getPrimaryFormat() const; - BOOL getIsAlphaMask() const ; - LLTexUnit::eTextureType getTarget(void) const ; - BOOL getMask(const LLVector2 &tc); - F32 getTimePassedSinceLastBound(); - BOOL getMissed() const ; - BOOL isJustBound()const ; - void forceUpdateBindStats(void) const; - - U32 getTexelsInAtlas() const ; - U32 getTexelsInGLTexture() const ; - BOOL isGLTextureCreated() const ; - S32 getDiscardLevelInAtlas() const ; - LLGLTextureState getTextureState() const { return mTextureState; } - - //--------------------------------------------------------------------------------------------- - //end of functions to access LLImageGL - //--------------------------------------------------------------------------------------------- - - //----------------- - /*virtual*/ void setActive() ; - void forceActive() ; - void setNoDelete() ; - void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } - BOOL getDontDiscard() const { return mDontDiscard; } - //----------------- + LLTexUnit::eTextureAddressMode getAddressMode(void) const ; + S32 getMaxDiscardLevel() const; + S32 getDiscardLevel() const; + S8 getComponents() const; + BOOL getBoundRecently() const; + S32Bytes getTextureMemory() const ; + LLGLenum getPrimaryFormat() const; + BOOL getIsAlphaMask() const ; + LLTexUnit::eTextureType getTarget(void) const ; + BOOL getMask(const LLVector2 &tc); + F32 getTimePassedSinceLastBound(); + BOOL getMissed() const ; + BOOL isJustBound()const ; + void forceUpdateBindStats(void) const; + + U32 getTexelsInAtlas() const ; + U32 getTexelsInGLTexture() const ; + BOOL isGLTextureCreated() const ; + S32 getDiscardLevelInAtlas() const ; + LLGLTextureState getTextureState() const { return mTextureState; } + + //--------------------------------------------------------------------------------------------- + //end of functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + + //----------------- + /*virtual*/ void setActive() ; + void forceActive() ; + void setNoDelete() ; + void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } + BOOL getDontDiscard() const { return mDontDiscard; } + //----------------- private: - void cleanup(); - void init(); + void cleanup(); + void init(); protected: - void setTexelsPerImage(); + void setTexelsPerImage(); public: - /*virtual*/ LLImageGL* getGLTexture() const ; + /*virtual*/ LLImageGL* getGLTexture() const ; protected: - S32 mBoostLevel; // enum describing priority level - U32 mFullWidth; - U32 mFullHeight; - BOOL mUseMipMaps; - S8 mComponents; - U32 mTexelsPerImage; // Texels per image. - mutable S8 mNeedsGLTexture; - - //GL texture - LLPointer mGLTexturep ; - S8 mDontDiscard; // Keep full res version of this image (for UI, etc) + S32 mBoostLevel; // enum describing priority level + U32 mFullWidth; + U32 mFullHeight; + BOOL mUseMipMaps; + S8 mComponents; + U32 mTexelsPerImage; // Texels per image. + mutable S8 mNeedsGLTexture; + + //GL texture + LLPointer mGLTexturep ; + S8 mDontDiscard; // Keep full res version of this image (for UI, etc) protected: - LLGLTextureState mTextureState ; + LLGLTextureState mTextureState ; }; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 358b35f36b..b92c9363fc 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1,25 +1,25 @@ - /** + /** * @file llrender.cpp * @brief LLRender implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,8 +51,8 @@ extern void APIENTRY gl_debug_callback(GLenum source, thread_local LLRender gGL; // Handy copies of last good GL matrices -F32 gGLModelView[16]; -F32 gGLLastModelView[16]; +F32 gGLModelView[16]; +F32 gGLLastModelView[16]; F32 gGLLastProjection[16]; F32 gGLProjection[16]; @@ -60,7 +60,7 @@ F32 gGLProjection[16]; F32 gGLDeltaModelView[16]; F32 gGLInverseDeltaModelView[16]; -S32 gGLViewport[4]; +S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; @@ -80,113 +80,113 @@ static std::unordered_map sVBCache; static const GLenum sGLTextureType[] = { - GL_TEXTURE_2D, - GL_TEXTURE_RECTANGLE, - GL_TEXTURE_CUBE_MAP, + GL_TEXTURE_2D, + GL_TEXTURE_RECTANGLE, + GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, - GL_TEXTURE_2D_MULTISAMPLE, + GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_3D }; static const GLint sGLAddressMode[] = -{ - GL_REPEAT, - GL_MIRRORED_REPEAT, - GL_CLAMP_TO_EDGE +{ + GL_REPEAT, + GL_MIRRORED_REPEAT, + GL_CLAMP_TO_EDGE }; const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; static const GLenum sGLBlendFactor[] = { - GL_ONE, - GL_ZERO, - GL_DST_COLOR, - GL_SRC_COLOR, - GL_ONE_MINUS_DST_COLOR, - GL_ONE_MINUS_SRC_COLOR, - GL_DST_ALPHA, - GL_SRC_ALPHA, - GL_ONE_MINUS_DST_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, - - GL_ZERO // 'BF_UNDEF' + GL_ONE, + GL_ZERO, + GL_DST_COLOR, + GL_SRC_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_DST_ALPHA, + GL_SRC_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + + GL_ZERO // 'BF_UNDEF' }; LLTexUnit::LLTexUnit(S32 index) - : mCurrTexType(TT_NONE), + : mCurrTexType(TT_NONE), mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR), - mHasMipMaps(false), - mIndex(index) + mHasMipMaps(false), + mIndex(index) { - llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS); + llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS); } //static U32 LLTexUnit::getInternalType(eTextureType type) { - return sGLTextureType[type]; + return sGLTextureType[type]; } void LLTexUnit::refreshState(void) { - // We set dirty to true so that the tex unit knows to ignore caching - // and we reset the cached tex unit state + // We set dirty to true so that the tex unit knows to ignore caching + // and we reset the cached tex unit state - gGL.flush(); - - glActiveTexture(GL_TEXTURE0 + mIndex); + gGL.flush(); - if (mCurrTexType != TT_NONE) - { - glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); - } - else - { - glBindTexture(GL_TEXTURE_2D, 0); - } + glActiveTexture(GL_TEXTURE0 + mIndex); + + if (mCurrTexType != TT_NONE) + { + glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); + } + else + { + glBindTexture(GL_TEXTURE_2D, 0); + } setTextureColorSpace(mTexColorSpace); } void LLTexUnit::activate(void) { - if (mIndex < 0) return; + if (mIndex < 0) return; - if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) - { - gGL.flush(); - glActiveTexture(GL_TEXTURE0 + mIndex); - gGL.mCurrTextureUnitIndex = mIndex; - } + if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) + { + gGL.flush(); + glActiveTexture(GL_TEXTURE0 + mIndex); + gGL.mCurrTextureUnitIndex = mIndex; + } } void LLTexUnit::enable(eTextureType type) { - if (mIndex < 0) return; + if (mIndex < 0) return; - if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) ) - { - activate(); - if (mCurrTexType != TT_NONE && !gGL.mDirty) - { - disable(); // Force a disable of a previous texture type if it's enabled. - } - mCurrTexType = type; + if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) ) + { + activate(); + if (mCurrTexType != TT_NONE && !gGL.mDirty) + { + disable(); // Force a disable of a previous texture type if it's enabled. + } + mCurrTexType = type; - gGL.flush(); - } + gGL.flush(); + } } void LLTexUnit::disable(void) { - if (mIndex < 0) return; + if (mIndex < 0) return; - if (mCurrTexType != TT_NONE) - { - unbind(mCurrTexType); - mCurrTexType = TT_NONE; - } + if (mCurrTexType != TT_NONE) + { + unbind(mCurrTexType); + mCurrTexType = TT_NONE; + } } void LLTexUnit::bindFast(LLTexture* texture) @@ -211,231 +211,231 @@ void LLTexUnit::bindFast(LLTexture* texture) bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - stop_glerror(); - if (mIndex >= 0) - { - gGL.flush(); - - LLImageGL* gl_tex = NULL ; - - if (texture != NULL && (gl_tex = texture->getGLTexture())) - { - if (gl_tex->getTexName()) //if texture exists - { - //in audit, replace the selected texture by the default one. - if ((mCurrTexture != gl_tex->getTexName()) || forceBind) - { - activate(); - enable(gl_tex->getTarget()); - mCurrTexture = gl_tex->getTexName(); - glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); - if(gl_tex->updateBindStats()) - { - texture->setActive() ; - texture->updateBindStatsForTester() ; - } - mHasMipMaps = gl_tex->mHasMipMaps; - if (gl_tex->mTexOptionsDirty) - { - gl_tex->mTexOptionsDirty = false; - setTextureAddressMode(gl_tex->mAddressMode); - setTextureFilteringOption(gl_tex->mFilterOption); + stop_glerror(); + if (mIndex >= 0) + { + gGL.flush(); + + LLImageGL* gl_tex = NULL ; + + if (texture != NULL && (gl_tex = texture->getGLTexture())) + { + if (gl_tex->getTexName()) //if texture exists + { + //in audit, replace the selected texture by the default one. + if ((mCurrTexture != gl_tex->getTexName()) || forceBind) + { + activate(); + enable(gl_tex->getTarget()); + mCurrTexture = gl_tex->getTexName(); + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + if(gl_tex->updateBindStats()) + { + texture->setActive() ; + texture->updateBindStatsForTester() ; + } + mHasMipMaps = gl_tex->mHasMipMaps; + if (gl_tex->mTexOptionsDirty) + { + gl_tex->mTexOptionsDirty = false; + setTextureAddressMode(gl_tex->mAddressMode); + setTextureFilteringOption(gl_tex->mFilterOption); } setTextureColorSpace(mTexColorSpace); - } - } - else - { - //if deleted, will re-generate it immediately - texture->forceImmediateUpdate() ; - - gl_tex->forceUpdateBindStats() ; - return texture->bindDefaultImage(mIndex); - } - } - else - { - if (texture) - { - LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL; - } - else - { - LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; - } - return false; - } - } - else - { // mIndex < 0 - return false; - } - - return true; + } + } + else + { + //if deleted, will re-generate it immediately + texture->forceImmediateUpdate() ; + + gl_tex->forceUpdateBindStats() ; + return texture->bindDefaultImage(mIndex); + } + } + else + { + if (texture) + { + LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL; + } + else + { + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + } + return false; + } + } + else + { // mIndex < 0 + return false; + } + + return true; } bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename) { - stop_glerror(); - if (mIndex < 0) return false; + stop_glerror(); + if (mIndex < 0) return false; U32 texname = usename ? usename : texture->getTexName(); - if(!texture) - { - LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; - return false; - } - - if(!texname) - { - if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) - { - return bind(LLImageGL::sDefaultGLTexture) ; - } - stop_glerror(); - return false ; - } - - if ((mCurrTexture != texname) || forceBind) - { - gGL.flush(); - stop_glerror(); - activate(); - stop_glerror(); - enable(texture->getTarget()); - stop_glerror(); - mCurrTexture = texname; - glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); - stop_glerror(); + if(!texture) + { + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + return false; + } + + if(!texname) + { + if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) + { + return bind(LLImageGL::sDefaultGLTexture) ; + } + stop_glerror(); + return false ; + } + + if ((mCurrTexture != texname) || forceBind) + { + gGL.flush(); + stop_glerror(); + activate(); + stop_glerror(); + enable(texture->getTarget()); + stop_glerror(); + mCurrTexture = texname; + glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); + stop_glerror(); texture->updateBindStats(); - mHasMipMaps = texture->mHasMipMaps; - if (texture->mTexOptionsDirty) - { - stop_glerror(); - texture->mTexOptionsDirty = false; - setTextureAddressMode(texture->mAddressMode); - setTextureFilteringOption(texture->mFilterOption); - stop_glerror(); - } + mHasMipMaps = texture->mHasMipMaps; + if (texture->mTexOptionsDirty) + { + stop_glerror(); + texture->mTexOptionsDirty = false; + setTextureAddressMode(texture->mAddressMode); + setTextureFilteringOption(texture->mFilterOption); + stop_glerror(); + } setTextureColorSpace(mTexColorSpace); - } + } - stop_glerror(); + stop_glerror(); - return true; + return true; } bool LLTexUnit::bind(LLCubeMap* cubeMap) { - if (mIndex < 0) return false; + if (mIndex < 0) return false; - gGL.flush(); + gGL.flush(); - if (cubeMap == NULL) - { - LL_WARNS() << "NULL LLTexUnit::bind cubemap" << LL_ENDL; - return false; - } + if (cubeMap == NULL) + { + LL_WARNS() << "NULL LLTexUnit::bind cubemap" << LL_ENDL; + return false; + } - if (mCurrTexture != cubeMap->mImages[0]->getTexName()) - { - if (LLCubeMap::sUseCubeMaps) - { - activate(); - enable(LLTexUnit::TT_CUBE_MAP); + if (mCurrTexture != cubeMap->mImages[0]->getTexName()) + { + if (LLCubeMap::sUseCubeMaps) + { + activate(); + enable(LLTexUnit::TT_CUBE_MAP); mCurrTexture = cubeMap->mImages[0]->getTexName(); - glBindTexture(GL_TEXTURE_CUBE_MAP, mCurrTexture); - mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; - cubeMap->mImages[0]->updateBindStats(); - if (cubeMap->mImages[0]->mTexOptionsDirty) - { - cubeMap->mImages[0]->mTexOptionsDirty = false; - setTextureAddressMode(cubeMap->mImages[0]->mAddressMode); - setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption); + glBindTexture(GL_TEXTURE_CUBE_MAP, mCurrTexture); + mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; + cubeMap->mImages[0]->updateBindStats(); + if (cubeMap->mImages[0]->mTexOptionsDirty) + { + cubeMap->mImages[0]->mTexOptionsDirty = false; + setTextureAddressMode(cubeMap->mImages[0]->mAddressMode); + setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption); } setTextureColorSpace(mTexColorSpace); - return true; - } - else - { - LL_WARNS() << "Using cube map without extension!" << LL_ENDL; - return false; - } - } - return true; + return true; + } + else + { + LL_WARNS() << "Using cube map without extension!" << LL_ENDL; + return false; + } + } + return true; } // LLRenderTarget is unavailible on the mapserver since it uses FBOs. bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) { - if (mIndex < 0) return false; + if (mIndex < 0) return false; - gGL.flush(); + gGL.flush(); - if (bindDepth) - { + if (bindDepth) + { llassert(renderTarget->getDepth()); // target MUST have a depth buffer attachment - bindManual(renderTarget->getUsage(), renderTarget->getDepth()); - } - else - { - bindManual(renderTarget->getUsage(), renderTarget->getTexture()); - } + bindManual(renderTarget->getUsage(), renderTarget->getDepth()); + } + else + { + bindManual(renderTarget->getUsage(), renderTarget->getTexture()); + } - return true; + return true; } bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0) - { - return false; - } - - if(mCurrTexture != texture) - { - gGL.flush(); - - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); + if (mIndex < 0) + { + return false; + } + + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); mHasMipMaps = hasMips; setTextureColorSpace(mTexColorSpace); - } - return true; + } + return true; } void LLTexUnit::unbind(eTextureType type) { - stop_glerror(); + stop_glerror(); - if (mIndex < 0) return; + if (mIndex < 0) return; - //always flush and activate for consistency - // some code paths assume unbind always flushes and sets the active texture - gGL.flush(); - activate(); + //always flush and activate for consistency + // some code paths assume unbind always flushes and sets the active texture + gGL.flush(); + activate(); - // Disabled caching of binding state. - if (mCurrTexType == type) - { - mCurrTexture = 0; + // Disabled caching of binding state. + if (mCurrTexType == type) + { + mCurrTexture = 0; // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping". mTexColorSpace = TCS_LINEAR; - if (type == LLTexUnit::TT_TEXTURE) - { - glBindTexture(sGLTextureType[type], sWhiteTexture); - } - else - { - glBindTexture(sGLTextureType[type], 0); - } - stop_glerror(); - } + if (type == LLTexUnit::TT_TEXTURE) + { + glBindTexture(sGLTextureType[type], sWhiteTexture); + } + else + { + glBindTexture(sGLTextureType[type], 0); + } + stop_glerror(); + } } void LLTexUnit::unbindFast(eTextureType type) @@ -462,184 +462,184 @@ void LLTexUnit::unbindFast(eTextureType type) void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { - if (mIndex < 0 || mCurrTexture == 0) return; + if (mIndex < 0 || mCurrTexture == 0) return; - gGL.flush(); + gGL.flush(); - activate(); + activate(); - glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); - glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); - if (mCurrTexType == TT_CUBE_MAP) - { - glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); - } + glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); + glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); + if (mCurrTexType == TT_CUBE_MAP) + { + glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); + } } void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option) { - if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return; - - gGL.flush(); - - if (option == TFO_POINT) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - if (option >= TFO_TRILINEAR && mHasMipMaps) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - else if (option >= TFO_BILINEAR) - { - if (mHasMipMaps) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - } - else - { - if (mHasMipMaps) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - } - - if (gGLManager.mGLVersion >= 4.59f) - { - if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) - { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); - } - else - { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); - } - } + if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return; + + gGL.flush(); + + if (option == TFO_POINT) + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + else + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + if (option >= TFO_TRILINEAR && mHasMipMaps) + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } + else if (option >= TFO_BILINEAR) + { + if (mHasMipMaps) + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } + else + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + } + else + { + if (mHasMipMaps) + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + } + else + { + glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + } + + if (gGLManager.mGLVersion >= 4.59f) + { + if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) + { + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + } + else + { + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); + } + } } GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) { - switch(src) - { - // All four cases should return the same value. - case TBS_PREV_COLOR: - case TBS_PREV_ALPHA: - case TBS_ONE_MINUS_PREV_COLOR: - case TBS_ONE_MINUS_PREV_ALPHA: - return GL_PREVIOUS; - - // All four cases should return the same value. - case TBS_TEX_COLOR: - case TBS_TEX_ALPHA: - case TBS_ONE_MINUS_TEX_COLOR: - case TBS_ONE_MINUS_TEX_ALPHA: - return GL_TEXTURE; - - // All four cases should return the same value. - case TBS_VERT_COLOR: - case TBS_VERT_ALPHA: - case TBS_ONE_MINUS_VERT_COLOR: - case TBS_ONE_MINUS_VERT_ALPHA: - return GL_PRIMARY_COLOR; - - // All four cases should return the same value. - case TBS_CONST_COLOR: - case TBS_CONST_ALPHA: - case TBS_ONE_MINUS_CONST_COLOR: - case TBS_ONE_MINUS_CONST_ALPHA: - return GL_CONSTANT; - - default: - LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL; - return GL_PRIMARY_COLOR; - } + switch(src) + { + // All four cases should return the same value. + case TBS_PREV_COLOR: + case TBS_PREV_ALPHA: + case TBS_ONE_MINUS_PREV_COLOR: + case TBS_ONE_MINUS_PREV_ALPHA: + return GL_PREVIOUS; + + // All four cases should return the same value. + case TBS_TEX_COLOR: + case TBS_TEX_ALPHA: + case TBS_ONE_MINUS_TEX_COLOR: + case TBS_ONE_MINUS_TEX_ALPHA: + return GL_TEXTURE; + + // All four cases should return the same value. + case TBS_VERT_COLOR: + case TBS_VERT_ALPHA: + case TBS_ONE_MINUS_VERT_COLOR: + case TBS_ONE_MINUS_VERT_ALPHA: + return GL_PRIMARY_COLOR; + + // All four cases should return the same value. + case TBS_CONST_COLOR: + case TBS_CONST_ALPHA: + case TBS_ONE_MINUS_CONST_COLOR: + case TBS_ONE_MINUS_CONST_ALPHA: + return GL_CONSTANT; + + default: + LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL; + return GL_PRIMARY_COLOR; + } } GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) { - switch(src) - { - // All four cases should return the same value. - case TBS_PREV_COLOR: - case TBS_TEX_COLOR: - case TBS_VERT_COLOR: - case TBS_CONST_COLOR: - return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; - - // All four cases should return the same value. - case TBS_PREV_ALPHA: - case TBS_TEX_ALPHA: - case TBS_VERT_ALPHA: - case TBS_CONST_ALPHA: - return GL_SRC_ALPHA; - - // All four cases should return the same value. - case TBS_ONE_MINUS_PREV_COLOR: - case TBS_ONE_MINUS_TEX_COLOR: - case TBS_ONE_MINUS_VERT_COLOR: - case TBS_ONE_MINUS_CONST_COLOR: - return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR; - - // All four cases should return the same value. - case TBS_ONE_MINUS_PREV_ALPHA: - case TBS_ONE_MINUS_TEX_ALPHA: - case TBS_ONE_MINUS_VERT_ALPHA: - case TBS_ONE_MINUS_CONST_ALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - - default: - LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL; - return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; - } + switch(src) + { + // All four cases should return the same value. + case TBS_PREV_COLOR: + case TBS_TEX_COLOR: + case TBS_VERT_COLOR: + case TBS_CONST_COLOR: + return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; + + // All four cases should return the same value. + case TBS_PREV_ALPHA: + case TBS_TEX_ALPHA: + case TBS_VERT_ALPHA: + case TBS_CONST_ALPHA: + return GL_SRC_ALPHA; + + // All four cases should return the same value. + case TBS_ONE_MINUS_PREV_COLOR: + case TBS_ONE_MINUS_TEX_COLOR: + case TBS_ONE_MINUS_VERT_COLOR: + case TBS_ONE_MINUS_CONST_COLOR: + return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR; + + // All four cases should return the same value. + case TBS_ONE_MINUS_PREV_ALPHA: + case TBS_ONE_MINUS_TEX_ALPHA: + case TBS_ONE_MINUS_VERT_ALPHA: + case TBS_ONE_MINUS_CONST_ALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + + default: + LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL; + return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; + } } void LLTexUnit::setColorScale(S32 scale) { - if (mCurrColorScale != scale || gGL.mDirty) - { - mCurrColorScale = scale; - gGL.flush(); - glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); - } + if (mCurrColorScale != scale || gGL.mDirty) + { + mCurrColorScale = scale; + gGL.flush(); + glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); + } } void LLTexUnit::setAlphaScale(S32 scale) { - if (mCurrAlphaScale != scale || gGL.mDirty) - { - mCurrAlphaScale = scale; - gGL.flush(); - glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); - } + if (mCurrAlphaScale != scale || gGL.mDirty) + { + mCurrAlphaScale = scale; + gGL.flush(); + glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); + } } -// Useful for debugging that you've manually assigned a texture operation to the correct +// Useful for debugging that you've manually assigned a texture operation to the correct // texture unit based on the currently set active texture in opengl. void LLTexUnit::debugTextureUnit(void) { - if (mIndex < 0) return; + if (mIndex < 0) return; - GLint activeTexture; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - if ((GL_TEXTURE0 + mIndex) != activeTexture) - { - U32 set_unit = (activeTexture - GL_TEXTURE0); - LL_WARNS() << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << LL_ENDL; - } + GLint activeTexture; + glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); + if ((GL_TEXTURE0 + mIndex) != activeTexture) + { + U32 set_unit = (activeTexture - GL_TEXTURE0); + LL_WARNS() << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << LL_ENDL; + } } void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) @@ -656,46 +656,46 @@ LLLightState::LLLightState(S32 index) mSpotExponent(0.f), mSpotCutoff(180.f) { - if (mIndex == 0) - { - mDiffuse.set(1,1,1,1); + if (mIndex == 0) + { + mDiffuse.set(1,1,1,1); mDiffuseB.set(0,0,0,0); - mSpecular.set(1,1,1,1); - } + mSpecular.set(1,1,1,1); + } mSunIsPrimary = true; - mAmbient.set(0,0,0,1); - mPosition.set(0,0,1,0); - mSpotDirection.set(0,0,-1); + mAmbient.set(0,0,0,1); + mPosition.set(0,0,1,0); + mSpotDirection.set(0,0,-1); } void LLLightState::enable() { - mEnabled = true; + mEnabled = true; } void LLLightState::disable() { - mEnabled = false; + mEnabled = false; } void LLLightState::setDiffuse(const LLColor4& diffuse) { - if (mDiffuse != diffuse) - { - ++gGL.mLightHash; - mDiffuse = diffuse; - } + if (mDiffuse != diffuse) + { + ++gGL.mLightHash; + mDiffuse = diffuse; + } } void LLLightState::setDiffuseB(const LLColor4& diffuse) { if (mDiffuseB != diffuse) - { - ++gGL.mLightHash; - mDiffuseB = diffuse; - } + { + ++gGL.mLightHash; + mDiffuseB = diffuse; + } } void LLLightState::setSunPrimary(bool v) @@ -703,7 +703,7 @@ void LLLightState::setSunPrimary(bool v) if (mSunIsPrimary != v) { ++gGL.mLightHash; - mSunIsPrimary = v; + mSunIsPrimary = v; } } @@ -727,134 +727,134 @@ void LLLightState::setFalloff(F32 v) void LLLightState::setAmbient(const LLColor4& ambient) { - if (mAmbient != ambient) - { - ++gGL.mLightHash; - mAmbient = ambient; - } + if (mAmbient != ambient) + { + ++gGL.mLightHash; + mAmbient = ambient; + } } void LLLightState::setSpecular(const LLColor4& specular) { - if (mSpecular != specular) - { - ++gGL.mLightHash; - mSpecular = specular; - } + if (mSpecular != specular) + { + ++gGL.mLightHash; + mSpecular = specular; + } } void LLLightState::setPosition(const LLVector4& position) { - //always set position because modelview matrix may have changed - ++gGL.mLightHash; - mPosition = position; - //transform position by current modelview matrix - glh::vec4f pos(position.mV); - const glh::matrix4f& mat = gGL.getModelviewMatrix(); - mat.mult_matrix_vec(pos); - mPosition.set(pos.v); + //always set position because modelview matrix may have changed + ++gGL.mLightHash; + mPosition = position; + //transform position by current modelview matrix + glh::vec4f pos(position.mV); + const glh::matrix4f& mat = gGL.getModelviewMatrix(); + mat.mult_matrix_vec(pos); + mPosition.set(pos.v); } void LLLightState::setConstantAttenuation(const F32& atten) { - if (mConstantAtten != atten) - { - mConstantAtten = atten; - ++gGL.mLightHash; - } + if (mConstantAtten != atten) + { + mConstantAtten = atten; + ++gGL.mLightHash; + } } void LLLightState::setLinearAttenuation(const F32& atten) { - if (mLinearAtten != atten) - { - ++gGL.mLightHash; - mLinearAtten = atten; - } + if (mLinearAtten != atten) + { + ++gGL.mLightHash; + mLinearAtten = atten; + } } void LLLightState::setQuadraticAttenuation(const F32& atten) { - if (mQuadraticAtten != atten) - { - ++gGL.mLightHash; - mQuadraticAtten = atten; - } + if (mQuadraticAtten != atten) + { + ++gGL.mLightHash; + mQuadraticAtten = atten; + } } void LLLightState::setSpotExponent(const F32& exponent) { - if (mSpotExponent != exponent) - { - ++gGL.mLightHash; - mSpotExponent = exponent; - } + if (mSpotExponent != exponent) + { + ++gGL.mLightHash; + mSpotExponent = exponent; + } } void LLLightState::setSpotCutoff(const F32& cutoff) { - if (mSpotCutoff != cutoff) - { - ++gGL.mLightHash; - mSpotCutoff = cutoff; - } + if (mSpotCutoff != cutoff) + { + ++gGL.mLightHash; + mSpotCutoff = cutoff; + } } void LLLightState::setSpotDirection(const LLVector3& direction) { - //always set direction because modelview matrix may have changed - ++gGL.mLightHash; - mSpotDirection = direction; - //transform direction by current modelview matrix - glh::vec3f dir(direction.mV); - const glh::matrix4f& mat = gGL.getModelviewMatrix(); - mat.mult_matrix_dir(dir); + //always set direction because modelview matrix may have changed + ++gGL.mLightHash; + mSpotDirection = direction; + //transform direction by current modelview matrix + glh::vec3f dir(direction.mV); + const glh::matrix4f& mat = gGL.getModelviewMatrix(); + mat.mult_matrix_dir(dir); - mSpotDirection.set(dir.v); + mSpotDirection.set(dir.v); } LLRender::LLRender() : mDirty(false), mCount(0), - mQuadCycle(0), + mQuadCycle(0), mMode(LLRender::TRIANGLES), mCurrTextureUnitIndex(0) -{ - for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) - { +{ + for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) + { mTexUnits[i].mIndex = i; - } + } - for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) - { + for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) + { mLightState[i].mIndex = i; - } + } - for (U32 i = 0; i < 4; i++) - { - mCurrColorMask[i] = true; - } + for (U32 i = 0; i < 4; i++) + { + mCurrColorMask[i] = true; + } - mCurrBlendColorSFactor = BF_UNDEF; - mCurrBlendAlphaSFactor = BF_UNDEF; - mCurrBlendColorDFactor = BF_UNDEF; - mCurrBlendAlphaDFactor = BF_UNDEF; + mCurrBlendColorSFactor = BF_UNDEF; + mCurrBlendAlphaSFactor = BF_UNDEF; + mCurrBlendColorDFactor = BF_UNDEF; + mCurrBlendAlphaDFactor = BF_UNDEF; - mMatrixMode = LLRender::MM_MODELVIEW; - - for (U32 i = 0; i < NUM_MATRIX_MODES; ++i) - { - mMatIdx[i] = 0; - mMatHash[i] = 0; - mCurMatHash[i] = 0xFFFFFFFF; - } + mMatrixMode = LLRender::MM_MODELVIEW; - mLightHash = 0; + for (U32 i = 0; i < NUM_MATRIX_MODES; ++i) + { + mMatIdx[i] = 0; + mMatHash[i] = 0; + mCurMatHash[i] = 0xFFFFFFFF; + } + + mLightHash = 0; } LLRender::~LLRender() { - shutdown(); + shutdown(); } bool LLRender::init(bool needs_vertex_buffer) @@ -923,22 +923,22 @@ void LLRender::shutdown() void LLRender::refreshState(void) { - mDirty = true; + mDirty = true; - U32 active_unit = mCurrTextureUnitIndex; + U32 active_unit = mCurrTextureUnitIndex; - for (U32 i = 0; i < mTexUnits.size(); i++) - { - mTexUnits[i].refreshState(); - } - - mTexUnits[active_unit].activate(); + for (U32 i = 0; i < mTexUnits.size(); i++) + { + mTexUnits[i].refreshState(); + } + + mTexUnits[active_unit].activate(); + + setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]); - setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]); - flush(); - mDirty = false; + mDirty = false; } void LLRender::syncLightState() @@ -990,36 +990,36 @@ void LLRender::syncLightState() void LLRender::syncMatrices() { - static const U32 name[] = - { - LLShaderMgr::MODELVIEW_MATRIX, - LLShaderMgr::PROJECTION_MATRIX, - LLShaderMgr::TEXTURE_MATRIX0, - LLShaderMgr::TEXTURE_MATRIX1, - LLShaderMgr::TEXTURE_MATRIX2, - LLShaderMgr::TEXTURE_MATRIX3, - }; + static const U32 name[] = + { + LLShaderMgr::MODELVIEW_MATRIX, + LLShaderMgr::PROJECTION_MATRIX, + LLShaderMgr::TEXTURE_MATRIX0, + LLShaderMgr::TEXTURE_MATRIX1, + LLShaderMgr::TEXTURE_MATRIX2, + LLShaderMgr::TEXTURE_MATRIX3, + }; - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - static glh::matrix4f cached_mvp; + static glh::matrix4f cached_mvp; static glh::matrix4f cached_inv_mdv; - static U32 cached_mvp_mdv_hash = 0xFFFFFFFF; - static U32 cached_mvp_proj_hash = 0xFFFFFFFF; - - static glh::matrix4f cached_normal; - static U32 cached_normal_hash = 0xFFFFFFFF; + static U32 cached_mvp_mdv_hash = 0xFFFFFFFF; + static U32 cached_mvp_proj_hash = 0xFFFFFFFF; - if (shader) - { - //llassert(shader); + static glh::matrix4f cached_normal; + static U32 cached_normal_hash = 0xFFFFFFFF; - bool mvp_done = false; + if (shader) + { + //llassert(shader); + + bool mvp_done = false; - U32 i = MM_MODELVIEW; - if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW]) - { //update modelview, normal, and MVP - glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; + U32 i = MM_MODELVIEW; + if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW]) + { //update modelview, normal, and MVP + glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; // if MDV has changed, update the cached inverse as well if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW]) @@ -1027,240 +1027,240 @@ void LLRender::syncMatrices() cached_inv_mdv = mat.inverse(); } - shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m); - shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW]; + shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m); + shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW]; - //update normal matrix - S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX); - if (loc > -1) - { - if (cached_normal_hash != mMatHash[i]) - { - cached_normal = cached_inv_mdv.transpose(); - cached_normal_hash = mMatHash[i]; - } + //update normal matrix + S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX); + if (loc > -1) + { + if (cached_normal_hash != mMatHash[i]) + { + cached_normal = cached_inv_mdv.transpose(); + cached_normal_hash = mMatHash[i]; + } - glh::matrix4f& norm = cached_normal; + glh::matrix4f& norm = cached_normal; - F32 norm_mat[] = - { - norm.m[0], norm.m[1], norm.m[2], - norm.m[4], norm.m[5], norm.m[6], - norm.m[8], norm.m[9], norm.m[10] - }; + F32 norm_mat[] = + { + norm.m[0], norm.m[1], norm.m[2], + norm.m[4], norm.m[5], norm.m[6], + norm.m[8], norm.m[9], norm.m[10] + }; - shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat); - } + shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat); + } if (shader->getUniformLocation(LLShaderMgr::INVERSE_MODELVIEW_MATRIX)) - { - shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, cached_inv_mdv.m); + { + shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, cached_inv_mdv.m); + } + + //update MVP matrix + mvp_done = true; + loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); + if (loc > -1) + { + U32 proj = MM_PROJECTION; + + if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) + { + cached_mvp = mat; + cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]); + cached_mvp_mdv_hash = mMatHash[i]; + cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; + } + + shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); } + } - //update MVP matrix - mvp_done = true; - loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); - if (loc > -1) - { - U32 proj = MM_PROJECTION; - - if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) - { - cached_mvp = mat; - cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]); - cached_mvp_mdv_hash = mMatHash[i]; - cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; - } - - shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); - } - } - - i = MM_PROJECTION; - if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION]) - { //update projection matrix, normal, and MVP - glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; + i = MM_PROJECTION; + if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION]) + { //update projection matrix, normal, and MVP + glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; // GZ: This was previously disabled seemingly due to a bug involving the deferred renderer's regular pushing and popping of mats. - // We're reenabling this and cleaning up the code around that - that would've been the appropriate course initially. - // Anything beyond the standard proj and inv proj mats are special cases. Please setup special uniforms accordingly in the future. + // We're reenabling this and cleaning up the code around that - that would've been the appropriate course initially. + // Anything beyond the standard proj and inv proj mats are special cases. Please setup special uniforms accordingly in the future. if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX)) { - glh::matrix4f inv_proj = mat.inverse(); - shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); + glh::matrix4f inv_proj = mat.inverse(); + shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); } - // Used by some full screen effects - such as full screen lights, glow, etc. + // Used by some full screen effects - such as full screen lights, glow, etc. if (shader->getUniformLocation(LLShaderMgr::IDENTITY_MATRIX)) { shader->uniformMatrix4fv(LLShaderMgr::IDENTITY_MATRIX, 1, GL_FALSE, glh::matrix4f::identity().m); } - shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m); - shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION]; - - if (!mvp_done) - { - //update MVP matrix - S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); - if (loc > -1) - { - if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) - { - U32 mdv = MM_MODELVIEW; - cached_mvp = mat; - cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]); - cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW]; - cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; - } - - shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); - } - } - } - - for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i) - { - if (mMatHash[i] != shader->mMatHash[i]) - { - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m); - shader->mMatHash[i] = mMatHash[i]; - } - } - - - if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics) - { //also sync light state - syncLightState(); - } - } + shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m); + shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION]; + + if (!mvp_done) + { + //update MVP matrix + S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); + if (loc > -1) + { + if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) + { + U32 mdv = MM_MODELVIEW; + cached_mvp = mat; + cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]); + cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW]; + cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; + } + + shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); + } + } + } + + for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i) + { + if (mMatHash[i] != shader->mMatHash[i]) + { + shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m); + shader->mMatHash[i] = mMatHash[i]; + } + } + + + if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics) + { //also sync light state + syncLightState(); + } + } } void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) { - flush(); + flush(); - { - glh::matrix4f trans_mat(1,0,0,x, - 0,1,0,y, - 0,0,1,z, - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat); - mMatHash[mMatrixMode]++; - } + { + glh::matrix4f trans_mat(1,0,0,x, + 0,1,0,y, + 0,0,1,z, + 0,0,0,1); + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat); + mMatHash[mMatrixMode]++; + } } void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z) { - flush(); - - { - glh::matrix4f scale_mat(x,0,0,0, - 0,y,0,0, - 0,0,z,0, - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat); - mMatHash[mMatrixMode]++; - } + flush(); + + { + glh::matrix4f scale_mat(x,0,0,0, + 0,y,0,0, + 0,0,z,0, + 0,0,0,1); + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat); + mMatHash[mMatrixMode]++; + } } void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar) { - flush(); + flush(); + + { - { + glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left), + 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom), + 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear), + 0,0,0,1); - glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left), - 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom), - 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear), - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat); + mMatHash[mMatrixMode]++; + } } void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) { - flush(); + flush(); + + { + F32 r = a * DEG_TO_RAD; - { - F32 r = a * DEG_TO_RAD; + F32 c = cosf(r); + F32 s = sinf(r); - F32 c = cosf(r); - F32 s = sinf(r); + F32 ic = 1.f-c; - F32 ic = 1.f-c; + glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0, + x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0, + x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0, + 0,0,0,1); - glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0, - x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0, - x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0, - 0,0,0,1); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat); + mMatHash[mMatrixMode]++; + } } void LLRender::pushMatrix() { - flush(); - - { - if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1) - { - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]]; - ++mMatIdx[mMatrixMode]; - } - else - { - LL_WARNS() << "Matrix stack overflow." << LL_ENDL; - } - } + flush(); + + { + if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1) + { + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]]; + ++mMatIdx[mMatrixMode]; + } + else + { + LL_WARNS() << "Matrix stack overflow." << LL_ENDL; + } + } } void LLRender::popMatrix() { - flush(); - { - if (mMatIdx[mMatrixMode] > 0) - { - --mMatIdx[mMatrixMode]; - mMatHash[mMatrixMode]++; - } - else - { - LL_WARNS() << "Matrix stack underflow." << LL_ENDL; - } - } + flush(); + { + if (mMatIdx[mMatrixMode] > 0) + { + --mMatIdx[mMatrixMode]; + mMatHash[mMatrixMode]++; + } + else + { + LL_WARNS() << "Matrix stack underflow." << LL_ENDL; + } + } } void LLRender::loadMatrix(const GLfloat* m) { - flush(); - { - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m); - mMatHash[mMatrixMode]++; - } + flush(); + { + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m); + mMatHash[mMatrixMode]++; + } } void LLRender::multMatrix(const GLfloat* m) { - flush(); - { - glh::matrix4f mat((GLfloat*) m); - - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat); - mMatHash[mMatrixMode]++; - } + flush(); + { + glh::matrix4f mat((GLfloat*) m); + + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat); + mMatHash[mMatrixMode]++; + } } void LLRender::matrixMode(eMatrixMode mode) { - if (mode == MM_TEXTURE) - { + if (mode == MM_TEXTURE) + { U32 tex_index = gGL.getCurrentTexUnitIndex(); // the shaders don't actually reference anything beyond texture_matrix0/1 outside of terrain rendering llassert(tex_index <= 3); @@ -1272,360 +1272,360 @@ void LLRender::matrixMode(eMatrixMode mode) LL_WARNS_ONCE() << "Attempted to assign matrix mode out of bounds: " << mode << LL_ENDL; mode = MM_TEXTURE0; } - } + } - mMatrixMode = mode; + mMatrixMode = mode; } LLRender::eMatrixMode LLRender::getMatrixMode() { - if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3) - { //always return MM_TEXTURE if current matrix mode points at any texture matrix - return MM_TEXTURE; - } + if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3) + { //always return MM_TEXTURE if current matrix mode points at any texture matrix + return MM_TEXTURE; + } - return mMatrixMode; + return mMatrixMode; } void LLRender::loadIdentity() { - flush(); + flush(); - { - llassert_always(mMatrixMode < NUM_MATRIX_MODES) ; + { + llassert_always(mMatrixMode < NUM_MATRIX_MODES) ; - mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity(); - mMatHash[mMatrixMode]++; - } + mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity(); + mMatHash[mMatrixMode]++; + } } const glh::matrix4f& LLRender::getModelviewMatrix() { - return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; + return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; } const glh::matrix4f& LLRender::getProjectionMatrix() { - return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; + return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; } void LLRender::translateUI(F32 x, F32 y, F32 z) { - if (mUIOffset.empty()) - { - LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL; - } + if (mUIOffset.empty()) + { + LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL; + } - mUIOffset.back().mV[0] += x; - mUIOffset.back().mV[1] += y; - mUIOffset.back().mV[2] += z; + mUIOffset.back().mV[0] += x; + mUIOffset.back().mV[1] += y; + mUIOffset.back().mV[2] += z; } void LLRender::scaleUI(F32 x, F32 y, F32 z) { - if (mUIScale.empty()) - { - LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL; - } + if (mUIScale.empty()) + { + LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL; + } - mUIScale.back().scaleVec(LLVector3(x,y,z)); + mUIScale.back().scaleVec(LLVector3(x,y,z)); } void LLRender::pushUIMatrix() { - if (mUIOffset.empty()) - { - mUIOffset.push_back(LLVector3(0,0,0)); - } - else - { - mUIOffset.push_back(mUIOffset.back()); - } - - if (mUIScale.empty()) - { - mUIScale.push_back(LLVector3(1,1,1)); - } - else - { - mUIScale.push_back(mUIScale.back()); - } + if (mUIOffset.empty()) + { + mUIOffset.push_back(LLVector3(0,0,0)); + } + else + { + mUIOffset.push_back(mUIOffset.back()); + } + + if (mUIScale.empty()) + { + mUIScale.push_back(LLVector3(1,1,1)); + } + else + { + mUIScale.push_back(mUIScale.back()); + } } void LLRender::popUIMatrix() { - if (mUIOffset.empty()) - { - LL_ERRS() << "UI offset stack blown." << LL_ENDL; - } - mUIOffset.pop_back(); - mUIScale.pop_back(); + if (mUIOffset.empty()) + { + LL_ERRS() << "UI offset stack blown." << LL_ENDL; + } + mUIOffset.pop_back(); + mUIScale.pop_back(); } LLVector3 LLRender::getUITranslation() { - if (mUIOffset.empty()) - { - return LLVector3(0,0,0); - } - return mUIOffset.back(); + if (mUIOffset.empty()) + { + return LLVector3(0,0,0); + } + return mUIOffset.back(); } LLVector3 LLRender::getUIScale() { - if (mUIScale.empty()) - { - return LLVector3(1,1,1); - } - return mUIScale.back(); + if (mUIScale.empty()) + { + return LLVector3(1,1,1); + } + return mUIScale.back(); } void LLRender::loadUIIdentity() { - if (mUIOffset.empty()) - { - LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL; - } - mUIOffset.back().setVec(0,0,0); - mUIScale.back().setVec(1,1,1); + if (mUIOffset.empty()) + { + LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL; + } + mUIOffset.back().setVec(0,0,0); + mUIScale.back().setVec(1,1,1); } void LLRender::setColorMask(bool writeColor, bool writeAlpha) { - setColorMask(writeColor, writeColor, writeColor, writeAlpha); + setColorMask(writeColor, writeColor, writeColor, writeAlpha); } void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) { - flush(); - - if (mCurrColorMask[0] != writeColorR || - mCurrColorMask[1] != writeColorG || - mCurrColorMask[2] != writeColorB || - mCurrColorMask[3] != writeAlpha) - { - mCurrColorMask[0] = writeColorR; - mCurrColorMask[1] = writeColorG; - mCurrColorMask[2] = writeColorB; - mCurrColorMask[3] = writeAlpha; + flush(); - glColorMask(writeColorR ? GL_TRUE : GL_FALSE, - writeColorG ? GL_TRUE : GL_FALSE, - writeColorB ? GL_TRUE : GL_FALSE, - writeAlpha ? GL_TRUE : GL_FALSE); - } + if (mCurrColorMask[0] != writeColorR || + mCurrColorMask[1] != writeColorG || + mCurrColorMask[2] != writeColorB || + mCurrColorMask[3] != writeAlpha) + { + mCurrColorMask[0] = writeColorR; + mCurrColorMask[1] = writeColorG; + mCurrColorMask[2] = writeColorB; + mCurrColorMask[3] = writeAlpha; + + glColorMask(writeColorR ? GL_TRUE : GL_FALSE, + writeColorG ? GL_TRUE : GL_FALSE, + writeColorB ? GL_TRUE : GL_FALSE, + writeAlpha ? GL_TRUE : GL_FALSE); + } } void LLRender::setSceneBlendType(eBlendType type) { - switch (type) - { - case BT_ALPHA: - blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA); - break; - case BT_ADD: - blendFunc(BF_ONE, BF_ONE); - break; - case BT_ADD_WITH_ALPHA: - blendFunc(BF_SOURCE_ALPHA, BF_ONE); - break; - case BT_MULT: - blendFunc(BF_DEST_COLOR, BF_ZERO); - break; - case BT_MULT_ALPHA: - blendFunc(BF_DEST_ALPHA, BF_ZERO); - break; - case BT_MULT_X2: - blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR); - break; - case BT_REPLACE: - blendFunc(BF_ONE, BF_ZERO); - break; - default: - LL_ERRS() << "Unknown Scene Blend Type: " << type << LL_ENDL; - break; - } + switch (type) + { + case BT_ALPHA: + blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA); + break; + case BT_ADD: + blendFunc(BF_ONE, BF_ONE); + break; + case BT_ADD_WITH_ALPHA: + blendFunc(BF_SOURCE_ALPHA, BF_ONE); + break; + case BT_MULT: + blendFunc(BF_DEST_COLOR, BF_ZERO); + break; + case BT_MULT_ALPHA: + blendFunc(BF_DEST_ALPHA, BF_ZERO); + break; + case BT_MULT_X2: + blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR); + break; + case BT_REPLACE: + blendFunc(BF_ONE, BF_ZERO); + break; + default: + LL_ERRS() << "Unknown Scene Blend Type: " << type << LL_ENDL; + break; + } } void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) { - llassert(sfactor < BF_UNDEF); - llassert(dfactor < BF_UNDEF); - if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || - mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) - { - mCurrBlendColorSFactor = sfactor; - mCurrBlendAlphaSFactor = sfactor; - mCurrBlendColorDFactor = dfactor; - mCurrBlendAlphaDFactor = dfactor; - flush(); - glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); - } + llassert(sfactor < BF_UNDEF); + llassert(dfactor < BF_UNDEF); + if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || + mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) + { + mCurrBlendColorSFactor = sfactor; + mCurrBlendAlphaSFactor = sfactor; + mCurrBlendColorDFactor = dfactor; + mCurrBlendAlphaDFactor = dfactor; + flush(); + glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); + } } void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, - eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor) -{ - llassert(color_sfactor < BF_UNDEF); - llassert(color_dfactor < BF_UNDEF); - llassert(alpha_sfactor < BF_UNDEF); - llassert(alpha_dfactor < BF_UNDEF); - - if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || - mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) - { - mCurrBlendColorSFactor = color_sfactor; - mCurrBlendAlphaSFactor = alpha_sfactor; - mCurrBlendColorDFactor = color_dfactor; - mCurrBlendAlphaDFactor = alpha_dfactor; - flush(); - + eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor) +{ + llassert(color_sfactor < BF_UNDEF); + llassert(color_dfactor < BF_UNDEF); + llassert(alpha_sfactor < BF_UNDEF); + llassert(alpha_dfactor < BF_UNDEF); + + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || + mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) + { + mCurrBlendColorSFactor = color_sfactor; + mCurrBlendAlphaSFactor = alpha_sfactor; + mCurrBlendColorDFactor = color_dfactor; + mCurrBlendAlphaDFactor = alpha_dfactor; + flush(); + glBlendFuncSeparate(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor], sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]); - } + } } LLTexUnit* LLRender::getTexUnit(U32 index) { - if (index < mTexUnits.size()) - { - return &mTexUnits[index]; - } - else - { - LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL; - return &mDummyTexUnit; - } + if (index < mTexUnits.size()) + { + return &mTexUnits[index]; + } + else + { + LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL; + return &mDummyTexUnit; + } } LLLightState* LLRender::getLight(U32 index) { - if (index < mLightState.size()) - { - return &mLightState[index]; - } - - return NULL; + if (index < mLightState.size()) + { + return &mLightState[index]; + } + + return NULL; } void LLRender::setAmbientLightColor(const LLColor4& color) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE - if (color != mAmbientLightColor) - { - ++mLightHash; - mAmbientLightColor = color; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE + if (color != mAmbientLightColor) + { + ++mLightHash; + mAmbientLightColor = color; + } } bool LLRender::verifyTexUnitActive(U32 unitToVerify) { - if (mCurrTextureUnitIndex == unitToVerify) - { - return true; - } - else - { - LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL; - return false; - } + if (mCurrTextureUnitIndex == unitToVerify) + { + return true; + } + else + { + LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL; + return false; + } } void LLRender::clearErrors() { - while (glGetError()) - { - //loop until no more error flags left - } + while (glGetError()) + { + //loop until no more error flags left + } } void LLRender::begin(const GLuint& mode) { - if (mode != mMode) - { - if (mode == LLRender::QUADS) - { - mQuadCycle = 1; - } - - if (mMode == LLRender::QUADS || - mMode == LLRender::LINES || - mMode == LLRender::TRIANGLES || - mMode == LLRender::POINTS) - { - flush(); - } - else if (mCount != 0) - { - LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL; - } - - mMode = mode; - } + if (mode != mMode) + { + if (mode == LLRender::QUADS) + { + mQuadCycle = 1; + } + + if (mMode == LLRender::QUADS || + mMode == LLRender::LINES || + mMode == LLRender::TRIANGLES || + mMode == LLRender::POINTS) + { + flush(); + } + else if (mCount != 0) + { + LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL; + } + + mMode = mode; + } } void LLRender::end() -{ - if (mCount == 0) - { - return; - //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL; - } - - if ((mMode != LLRender::QUADS && - mMode != LLRender::LINES && - mMode != LLRender::TRIANGLES && - mMode != LLRender::POINTS) || - mCount > 2048) - { - flush(); - } +{ + if (mCount == 0) + { + return; + //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL; + } + + if ((mMode != LLRender::QUADS && + mMode != LLRender::LINES && + mMode != LLRender::TRIANGLES && + mMode != LLRender::POINTS) || + mCount > 2048) + { + flush(); + } } void LLRender::flush() { - if (mCount > 0) - { + if (mCount > 0) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; llassert(LLGLSLShader::sCurBoundShaderPtr != nullptr); - if (!mUIOffset.empty()) - { - sUICalls++; - sUIVerts += mCount; - } - - //store mCount in a local variable to avoid re-entrance (drawArrays may call flush) - U32 count = mCount; - - if (mMode == LLRender::QUADS && !sGLCoreProfile) - { - if (mCount%4 != 0) - { - count -= (mCount % 4); - LL_WARNS() << "Incomplete quad requested." << LL_ENDL; - } - } - - if (mMode == LLRender::TRIANGLES) - { - if (mCount%3 != 0) - { - count -= (mCount % 3); - LL_WARNS() << "Incomplete triangle requested." << LL_ENDL; - } - } - - if (mMode == LLRender::LINES) - { - if (mCount%2 != 0) - { - count -= (mCount % 2); - LL_WARNS() << "Incomplete line requested." << LL_ENDL; - } - } - - mCount = 0; + if (!mUIOffset.empty()) + { + sUICalls++; + sUIVerts += mCount; + } + + //store mCount in a local variable to avoid re-entrance (drawArrays may call flush) + U32 count = mCount; + + if (mMode == LLRender::QUADS && !sGLCoreProfile) + { + if (mCount%4 != 0) + { + count -= (mCount % 4); + LL_WARNS() << "Incomplete quad requested." << LL_ENDL; + } + } + + if (mMode == LLRender::TRIANGLES) + { + if (mCount%3 != 0) + { + count -= (mCount % 3); + LL_WARNS() << "Incomplete triangle requested." << LL_ENDL; + } + } + + if (mMode == LLRender::LINES) + { + if (mCount%2 != 0) + { + count -= (mCount % 2); + LL_WARNS() << "Incomplete line requested." << LL_ENDL; + } + } + + mCount = 0; if (mBuffer) { @@ -1649,8 +1649,8 @@ void LLRender::flush() hash.finalize(); } - - + + U64 vhash = hash.digest(); // check the VB cache before making a new vertex buffer @@ -1660,7 +1660,7 @@ void LLRender::flush() // Most of our usage of the "immediate mode" style draw calls is actually // sending the same geometry over and over again. // To leverage this, we maintain a running hash of the vertex stream being - // built up before a flush, and then check that hash against a VB + // built up before a flush, and then check that hash against a VB // cache just before creating a vertex buffer in VRAM std::unordered_map::iterator cache = sVBCache.find(vhash); @@ -1739,504 +1739,504 @@ void LLRender::flush() LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL; } - - mVerticesp[0] = mVerticesp[count]; - mTexcoordsp[0] = mTexcoordsp[count]; - mColorsp[0] = mColorsp[count]; - - mCount = 0; - } + + mVerticesp[0] = mVerticesp[count]; + mTexcoordsp[0] = mTexcoordsp[count]; + mColorsp[0] = mColorsp[count]; + + mCount = 0; + } } void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) -{ - //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095] - if (mCount > 2048) - { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below - switch (mMode) - { - case LLRender::POINTS: flush(); break; - case LLRender::TRIANGLES: if (mCount%3==0) flush(); break; - case LLRender::QUADS: if(mCount%4 == 0) flush(); break; - case LLRender::LINES: if (mCount%2 == 0) flush(); break; - } - } - - if (mCount > 4094) - { - // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; - return; - } - - if (mUIOffset.empty()) - { - mVerticesp[mCount] = LLVector3(x,y,z); - } - else - { - LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back()); - mVerticesp[mCount] = vert; - } - - if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile) - { - mQuadCycle++; - if (mQuadCycle == 4) - { //copy two vertices so fourth quad element will add a triangle - mQuadCycle = 0; - - mCount++; - mVerticesp[mCount] = mVerticesp[mCount-3]; - mColorsp[mCount] = mColorsp[mCount-3]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-3]; - - mCount++; - mVerticesp[mCount] = mVerticesp[mCount-2]; - mColorsp[mCount] = mColorsp[mCount-2]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-2]; - } - } - - mCount++; - mVerticesp[mCount] = mVerticesp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +{ + //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095] + if (mCount > 2048) + { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below + switch (mMode) + { + case LLRender::POINTS: flush(); break; + case LLRender::TRIANGLES: if (mCount%3==0) flush(); break; + case LLRender::QUADS: if(mCount%4 == 0) flush(); break; + case LLRender::LINES: if (mCount%2 == 0) flush(); break; + } + } + + if (mCount > 4094) + { + // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; + return; + } + + if (mUIOffset.empty()) + { + mVerticesp[mCount] = LLVector3(x,y,z); + } + else + { + LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back()); + mVerticesp[mCount] = vert; + } + + if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile) + { + mQuadCycle++; + if (mQuadCycle == 4) + { //copy two vertices so fourth quad element will add a triangle + mQuadCycle = 0; + + mCount++; + mVerticesp[mCount] = mVerticesp[mCount-3]; + mColorsp[mCount] = mColorsp[mCount-3]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-3]; + + mCount++; + mVerticesp[mCount] = mVerticesp[mCount-2]; + mColorsp[mCount] = mColorsp[mCount-2]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-2]; + } + } + + mCount++; + mVerticesp[mCount] = mVerticesp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; } void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) { - if (mCount + vert_count > 4094) - { - // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; - return; - } - - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy two - mVerticesp[mCount++] = verts[i-3]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i-1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last one - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - else - { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; - - mCount++; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - - if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen - mVerticesp[mCount] = mVerticesp[mCount-1]; + if (mCount + vert_count > 4094) + { + // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; + return; + } + + if (sGLCoreProfile && mMode == LLRender::QUADS) + { //quads are deprecated, convert to triangle list + S32 i = 0; + + while (i < vert_count) + { + //read first three + mVerticesp[mCount++] = verts[i++]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount++] = verts[i++]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount++] = verts[i++]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + //copy two + mVerticesp[mCount++] = verts[i-3]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount++] = verts[i-1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + //copy last one + mVerticesp[mCount++] = verts[i++]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + } + } + else + { + for (S32 i = 0; i < vert_count; i++) + { + mVerticesp[mCount] = verts[i]; + + mCount++; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + } + } + + if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen + mVerticesp[mCount] = mVerticesp[mCount-1]; } void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count) { - if (mCount + vert_count > 4094) - { - // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; - return; - } - - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last two - mVerticesp[mCount] = verts[i-3]; - mTexcoordsp[mCount++] = uvs[i-3]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i-1]; - mTexcoordsp[mCount++] = uvs[i-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last one - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - else - { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - - mCount++; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - - if (mCount > 0) - { - mVerticesp[mCount] = mVerticesp[mCount - 1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; - } + if (mCount + vert_count > 4094) + { + // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; + return; + } + + if (sGLCoreProfile && mMode == LLRender::QUADS) + { //quads are deprecated, convert to triangle list + S32 i = 0; + + while (i < vert_count) + { + //read first three + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount++] = uvs[i++]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount++] = uvs[i++]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount++] = uvs[i++]; + mColorsp[mCount] = mColorsp[mCount-1]; + + //copy last two + mVerticesp[mCount] = verts[i-3]; + mTexcoordsp[mCount++] = uvs[i-3]; + mColorsp[mCount] = mColorsp[mCount-1]; + + mVerticesp[mCount] = verts[i-1]; + mTexcoordsp[mCount++] = uvs[i-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + + //copy last one + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount++] = uvs[i++]; + mColorsp[mCount] = mColorsp[mCount-1]; + } + } + else + { + for (S32 i = 0; i < vert_count; i++) + { + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + + mCount++; + mColorsp[mCount] = mColorsp[mCount-1]; + } + } + + if (mCount > 0) + { + mVerticesp[mCount] = mVerticesp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + } } void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) { - if (mCount + vert_count > 4094) - { - // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; - return; - } - - - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - //copy last two - mVerticesp[mCount] = verts[i-3]; - mTexcoordsp[mCount] = uvs[i-3]; - mColorsp[mCount++] = colors[i-3]; - - mVerticesp[mCount] = verts[i-1]; - mTexcoordsp[mCount] = uvs[i-1]; - mColorsp[mCount++] = colors[i-1]; - - //copy last one - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - } - } - else - { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount] = colors[i]; - - mCount++; - } - } - - if (mCount > 0) - { - mVerticesp[mCount] = mVerticesp[mCount - 1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; - mColorsp[mCount] = mColorsp[mCount - 1]; - } + if (mCount + vert_count > 4094) + { + // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL; + return; + } + + + if (sGLCoreProfile && mMode == LLRender::QUADS) + { //quads are deprecated, convert to triangle list + S32 i = 0; + + while (i < vert_count) + { + //read first three + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount++] = colors[i++]; + + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount++] = colors[i++]; + + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount++] = colors[i++]; + + //copy last two + mVerticesp[mCount] = verts[i-3]; + mTexcoordsp[mCount] = uvs[i-3]; + mColorsp[mCount++] = colors[i-3]; + + mVerticesp[mCount] = verts[i-1]; + mTexcoordsp[mCount] = uvs[i-1]; + mColorsp[mCount++] = colors[i-1]; + + //copy last one + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount++] = colors[i++]; + } + } + else + { + for (S32 i = 0; i < vert_count; i++) + { + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount] = colors[i]; + + mCount++; + } + } + + if (mCount > 0) + { + mVerticesp[mCount] = mVerticesp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + mColorsp[mCount] = mColorsp[mCount - 1]; + } } void LLRender::vertex2i(const GLint& x, const GLint& y) { - vertex3f((GLfloat) x, (GLfloat) y, 0); + vertex3f((GLfloat) x, (GLfloat) y, 0); } void LLRender::vertex2f(const GLfloat& x, const GLfloat& y) -{ - vertex3f(x,y,0); +{ + vertex3f(x,y,0); } void LLRender::vertex2fv(const GLfloat* v) -{ - vertex3f(v[0], v[1], 0); +{ + vertex3f(v[0], v[1], 0); } void LLRender::vertex3fv(const GLfloat* v) { - vertex3f(v[0], v[1], v[2]); + vertex3f(v[0], v[1], v[2]); } void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y) -{ - mTexcoordsp[mCount] = LLVector2(x,y); +{ + mTexcoordsp[mCount] = LLVector2(x,y); } void LLRender::texCoord2i(const GLint& x, const GLint& y) -{ - texCoord2f((GLfloat) x, (GLfloat) y); +{ + texCoord2f((GLfloat) x, (GLfloat) y); } void LLRender::texCoord2fv(const GLfloat* tc) -{ - texCoord2f(tc[0], tc[1]); +{ + texCoord2f(tc[0], tc[1]); } void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) { - if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR) - { - mColorsp[mCount] = LLColor4U(r,g,b,a); - } - else - { //not using shaders or shader reads color from a uniform - diffuseColor4ub(r,g,b,a); - } + if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR) + { + mColorsp[mCount] = LLColor4U(r,g,b,a); + } + else + { //not using shaders or shader reads color from a uniform + diffuseColor4ub(r,g,b,a); + } } void LLRender::color4ubv(const GLubyte* c) { - color4ub(c[0], c[1], c[2], c[3]); + color4ub(c[0], c[1], c[2], c[3]); } void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a) { - color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255), - (GLubyte) (llclamp(g, 0.f, 1.f)*255), - (GLubyte) (llclamp(b, 0.f, 1.f)*255), - (GLubyte) (llclamp(a, 0.f, 1.f)*255)); + color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255), + (GLubyte) (llclamp(g, 0.f, 1.f)*255), + (GLubyte) (llclamp(b, 0.f, 1.f)*255), + (GLubyte) (llclamp(a, 0.f, 1.f)*255)); } void LLRender::color4fv(const GLfloat* c) -{ - color4f(c[0],c[1],c[2],c[3]); +{ + color4f(c[0],c[1],c[2],c[3]); } void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b) -{ - color4f(r,g,b,1); +{ + color4f(r,g,b,1); } void LLRender::color3fv(const GLfloat* c) -{ - color4f(c[0],c[1],c[2],1); +{ + color4f(c[0],c[1],c[2],1); } void LLRender::diffuseColor3f(F32 r, F32 g, F32 b) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f); - } + if (shader) + { + shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f); + } } void LLRender::diffuseColor3fv(const F32* c) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f); - } + if (shader) + { + shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f); + } } void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a); - } + if (shader) + { + shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a); + } } void LLRender::diffuseColor4fv(const F32* c) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c); - } + if (shader) + { + shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c); + } } void LLRender::diffuseColor4ubv(const U8* c) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f); - } + if (shader) + { + shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f); + } } void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a) { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader != NULL); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader != NULL); - if (shader) - { - shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f); - } + if (shader) + { + shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f); + } } void LLRender::debugTexUnits(void) { - LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL; - std::string active_enabled = "false"; - for (U32 i = 0; i < mTexUnits.size(); i++) - { - if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE) - { - if (i == mCurrTextureUnitIndex) active_enabled = "true"; - LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL; - LL_INFOS("TextureUnit") << "Enabled As: " ; - switch (getTexUnit(i)->mCurrTexType) - { - case LLTexUnit::TT_TEXTURE: - LL_CONT << "Texture 2D"; - break; - case LLTexUnit::TT_RECT_TEXTURE: - LL_CONT << "Texture Rectangle"; - break; - case LLTexUnit::TT_CUBE_MAP: - LL_CONT << "Cube Map"; - break; - default: - LL_CONT << "ARGH!!! NONE!"; - break; - } - LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL; - } - } - LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL; + LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL; + std::string active_enabled = "false"; + for (U32 i = 0; i < mTexUnits.size(); i++) + { + if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE) + { + if (i == mCurrTextureUnitIndex) active_enabled = "true"; + LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL; + LL_INFOS("TextureUnit") << "Enabled As: " ; + switch (getTexUnit(i)->mCurrTexType) + { + case LLTexUnit::TT_TEXTURE: + LL_CONT << "Texture 2D"; + break; + case LLTexUnit::TT_RECT_TEXTURE: + LL_CONT << "Texture Rectangle"; + break; + case LLTexUnit::TT_CUBE_MAP: + LL_CONT << "Cube Map"; + break; + default: + LL_CONT << "ARGH!!! NONE!"; + break; + } + LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL; + } + } + LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL; } glh::matrix4f copy_matrix(F32* src) { - glh::matrix4f ret; - ret.set_value(src); - return ret; + glh::matrix4f ret; + ret.set_value(src); + return ret; } glh::matrix4f get_current_modelview() { - return copy_matrix(gGLModelView); + return copy_matrix(gGLModelView); } glh::matrix4f get_current_projection() { - return copy_matrix(gGLProjection); + return copy_matrix(gGLProjection); } glh::matrix4f get_last_modelview() { - return copy_matrix(gGLLastModelView); + return copy_matrix(gGLLastModelView); } glh::matrix4f get_last_projection() { - return copy_matrix(gGLLastProjection); + return copy_matrix(gGLLastProjection); } void copy_matrix(const glh::matrix4f& src, F32* dst) { - for (U32 i = 0; i < 16; i++) - { - dst[i] = src.m[i]; - } + for (U32 i = 0; i < 16; i++) + { + dst[i] = src.m[i]; + } } void set_current_modelview(const glh::matrix4f& mat) { - copy_matrix(mat, gGLModelView); + copy_matrix(mat, gGLModelView); } void set_current_projection(glh::matrix4f& mat) { - copy_matrix(mat, gGLProjection); + copy_matrix(mat, gGLProjection); } glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) { - glh::matrix4f ret( - 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), - 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), - 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), - 0.f, 0.f, 0.f, 1.f); + glh::matrix4f ret( + 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), + 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), + 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), + 0.f, 0.f, 0.f, 1.f); - return ret; + return ret; } glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) { - GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); + GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); - return glh::matrix4f(f/aspect, 0, 0, 0, - 0, f, 0, 0, - 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), - 0, 0, -1.f, 0); + return glh::matrix4f(f/aspect, 0, 0, 0, + 0, f, 0, 0, + 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), + 0, 0, -1.f, 0); } glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) { - LLVector3 f = center-eye; - f.normVec(); - up.normVec(); - LLVector3 s = f % up; - LLVector3 u = s % f; - - return glh::matrix4f(s[0], s[1], s[2], 0, - u[0], u[1], u[2], 0, - -f[0], -f[1], -f[2], 0, - 0, 0, 0, 1); - + LLVector3 f = center-eye; + f.normVec(); + up.normVec(); + LLVector3 s = f % up; + LLVector3 u = s % f; + + return glh::matrix4f(s[0], s[1], s[2], 0, + u[0], u[1], u[2], 0, + -f[0], -f[1], -f[2], 0, + 0, 0, 0, 1); + } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index da401572d1..340276a752 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -1,25 +1,25 @@ -/** +/** * @file llrendertarget.h * @brief Off screen render target abstraction. Loose wrapper for GL_EXT_framebuffer_objects. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,56 +37,56 @@ SAMPLE USAGE: - LLRenderTarget target; + LLRenderTarget target; - ... + ... - //allocate a 256x256 RGBA render target with depth buffer - target.allocate(256,256,GL_RGBA,TRUE); + //allocate a 256x256 RGBA render target with depth buffer + target.allocate(256,256,GL_RGBA,TRUE); - //render to contents of offscreen buffer - target.bindTarget(); - target.clear(); - ... ... - target.flush(); + //render to contents of offscreen buffer + target.bindTarget(); + target.clear(); + ... ... + target.flush(); - ... + ... - //use target as a texture - gGL.getTexUnit(INDEX)->bind(&target); - ... ... + //use target as a texture + gGL.getTexUnit(INDEX)->bind(&target); + ... ... */ class LLRenderTarget { public: - //whether or not to use FBO implementation - static bool sUseFBO; - static U32 sBytesAllocated; - static U32 sCurFBO; - static U32 sCurResX; - static U32 sCurResY; + //whether or not to use FBO implementation + static bool sUseFBO; + static U32 sBytesAllocated; + static U32 sCurFBO; + static U32 sCurResX; + static U32 sCurResY; - LLRenderTarget(); - ~LLRenderTarget(); + LLRenderTarget(); + ~LLRenderTarget(); - //allocate resources for rendering - //must be called before use - //multiple calls will release previously allocated resources + //allocate resources for rendering + //must be called before use + //multiple calls will release previously allocated resources // resX - width // resY - height // color_fmt - GL color format (e.g. GL_RGB) // depth - if true, allocate a depth buffer // usage - deprecated, should always be TT_TEXTURE - bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureMipGeneration generateMipMaps = LLTexUnit::TMG_NONE); + bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureMipGeneration generateMipMaps = LLTexUnit::TMG_NONE); - //resize existing attachments to use new resolution and color format - // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined - // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded - // DO use for render targets that resize often and aren't likely to ruin someone's day if they break - void resize(U32 resx, U32 resy); + //resize existing attachments to use new resolution and color format + // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined + // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded + // DO use for render targets that resize often and aren't likely to ruin someone's day if they break + void resize(U32 resx, U32 resy); //point this render target at a particular LLImageGL // Intended usage: @@ -96,98 +96,98 @@ public: // < issue GL calls> // target.flush(); // target.releaseColorAttachment(); - // + // // attachment -- LLImageGL to render into // use_name -- optional texture name to target instead of attachment->getTexName() // NOTE: setColorAttachment and releaseColorAttachment cannot be used in conjuction with - // addColorAttachment, allocateDepth, resize, etc. + // addColorAttachment, allocateDepth, resize, etc. void setColorAttachment(LLImageGL* attachment, LLGLuint use_name = 0); // detach from current color attachment void releaseColorAttachment(); - //add color buffer attachment - //limit of 4 color attachments per render target - bool addColorAttachment(U32 color_fmt); + //add color buffer attachment + //limit of 4 color attachments per render target + bool addColorAttachment(U32 color_fmt); - //allocate a depth texture - bool allocateDepth(); + //allocate a depth texture + bool allocateDepth(); - //share depth buffer with provided render target - void shareDepthBuffer(LLRenderTarget& target); + //share depth buffer with provided render target + void shareDepthBuffer(LLRenderTarget& target); - //free any allocated resources - //safe to call redundantly + //free any allocated resources + //safe to call redundantly // asserts that this target is not currently bound or present in the RT stack - void release(); + void release(); - //bind target for rendering - //applies appropriate viewport - // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget + //bind target for rendering + //applies appropriate viewport + // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget // and restores previous binding on flush() (maintains a stack of Render Targets) // Asserts that this target is not currently bound in the stack - void bindTarget(); + void bindTarget(); - //clear render targer, clears depth buffer if present, - //uses scissor rect if in copy-to-texture mode + //clear render targer, clears depth buffer if present, + //uses scissor rect if in copy-to-texture mode // asserts that this target is currently bound - void clear(U32 mask = 0xFFFFFFFF); - - //get applied viewport - void getViewport(S32* viewport); + void clear(U32 mask = 0xFFFFFFFF); + + //get applied viewport + void getViewport(S32* viewport); - //get X resolution - U32 getWidth() const { return mResX; } + //get X resolution + U32 getWidth() const { return mResX; } - //get Y resolution - U32 getHeight() const { return mResY; } + //get Y resolution + U32 getHeight() const { return mResY; } - LLTexUnit::eTextureType getUsage(void) const { return mUsage; } + LLTexUnit::eTextureType getUsage(void) const { return mUsage; } - U32 getTexture(U32 attachment = 0) const; - U32 getNumTextures() const; + U32 getTexture(U32 attachment = 0) const; + U32 getNumTextures() const; - U32 getDepth(void) const { return mDepth; } + U32 getDepth(void) const { return mDepth; } - void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR); + void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR); - //flush rendering operations - //must be called when rendering is complete - //should be used 1:1 with bindTarget - // call bindTarget once, do all your rendering, call flush once + //flush rendering operations + //must be called when rendering is complete + //should be used 1:1 with bindTarget + // call bindTarget once, do all your rendering, call flush once // If an LLRenderTarget was bound when bindTarget was called, binds that RenderTarget for rendering (maintains RT stack) // asserts that this target is currently bound - void flush(); + void flush(); - //Returns TRUE if target is ready to be rendered into. - //That is, if the target has been allocated with at least - //one renderable attachment (i.e. color buffer, depth buffer). - bool isComplete() const; + //Returns TRUE if target is ready to be rendered into. + //That is, if the target has been allocated with at least + //one renderable attachment (i.e. color buffer, depth buffer). + bool isComplete() const; // Returns true if this RenderTarget is bound somewhere in the stack bool isBoundInStack() const; - static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } + static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } - // *HACK - void swapFBORefs(LLRenderTarget& other); + // *HACK + void swapFBORefs(LLRenderTarget& other); protected: - U32 mResX; - U32 mResY; - std::vector mTex; - std::vector mInternalFormat; - U32 mFBO; + U32 mResX; + U32 mResY; + std::vector mTex; + std::vector mInternalFormat; + U32 mFBO; LLRenderTarget* mPreviousRT = nullptr; U32 mDepth; bool mUseDepth; - LLTexUnit::eTextureMipGeneration mGenerateMipMaps; - U32 mMipLevels; + LLTexUnit::eTextureMipGeneration mGenerateMipMaps; + U32 mMipLevels; + + LLTexUnit::eTextureType mUsage; - LLTexUnit::eTextureType mUsage; - - static LLRenderTarget* sBoundTarget; + static LLRenderTarget* sBoundTarget; }; #endif diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 636e13719a..0f3716bc18 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llshadermgr.cpp * @brief Shader manager implementation. * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -58,90 +58,90 @@ LLShaderMgr::~LLShaderMgr() // static LLShaderMgr * LLShaderMgr::instance() { - if(NULL == sInstance) - { - LL_ERRS("Shaders") << "LLShaderMgr should already have been instantiated by the application!" << LL_ENDL; - } + if(NULL == sInstance) + { + LL_ERRS("Shaders") << "LLShaderMgr should already have been instantiated by the application!" << LL_ENDL; + } - return sInstance; + return sInstance; } BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) { - llassert_always(shader != NULL); - LLShaderFeatures *features = & shader->mFeatures; - - if (features->attachNothing) - { - return TRUE; - } - ////////////////////////////////////// - // Attach Vertex Shader Features First - ////////////////////////////////////// - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->calculatesAtmospherics) - { - if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl")) - { - return FALSE; - } - } - - if (features->calculatesLighting || features->calculatesAtmospherics) - { - if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl")) - { - return FALSE; - } - } - - if (features->calculatesLighting) - { - if (features->isSpecular) - { + llassert_always(shader != NULL); + LLShaderFeatures *features = & shader->mFeatures; + + if (features->attachNothing) + { + return TRUE; + } + ////////////////////////////////////// + // Attach Vertex Shader Features First + ////////////////////////////////////// + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->calculatesAtmospherics) + { + if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl")) + { + return FALSE; + } + } + + if (features->calculatesLighting || features->calculatesAtmospherics) + { + if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl")) + { + return FALSE; + } + } + + if (features->calculatesLighting) + { + if (features->isSpecular) + { if (!shader->attachVertexObject("lighting/lightFuncSpecularV.glsl")) - { - return FALSE; - } - - if (!features->isAlphaLighting) - { + { + return FALSE; + } + + if (!features->isAlphaLighting) + { if (!shader->attachVertexObject("lighting/sumLightsSpecularV.glsl")) - { - return FALSE; - } - } - + { + return FALSE; + } + } + if (!shader->attachVertexObject("lighting/lightSpecularV.glsl")) - { - return FALSE; - } - } - else - { + { + return FALSE; + } + } + else + { if (!shader->attachVertexObject("lighting/lightFuncV.glsl")) - { - return FALSE; - } - - if (!features->isAlphaLighting) - { + { + return FALSE; + } + + if (!features->isAlphaLighting) + { if (!shader->attachVertexObject("lighting/sumLightsV.glsl")) - { - return FALSE; - } - } - + { + return FALSE; + } + } + if (!shader->attachVertexObject("lighting/lightV.glsl")) - { - return FALSE; - } - } - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->calculatesAtmospherics) + { + return FALSE; + } + } + } + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->calculatesAtmospherics) { if (!shader->attachVertexObject("environment/srgbF.glsl")) // NOTE -- "F" suffix is superfluous here, there is nothing fragment specific in srgbF { @@ -153,39 +153,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } if (!shader->attachVertexObject("windlight/atmosphericsV.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - if (features->hasSkinning) - { + if (features->hasSkinning) + { if (!shader->attachVertexObject("avatar/avatarSkinV.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - if (features->hasObjectSkinning) - { + if (features->hasObjectSkinning) + { shader->mRiggedVariant = shader; if (!shader->attachVertexObject("avatar/objectSkinV.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } if (!shader->attachVertexObject("deferred/textureUtilV.glsl")) { return FALSE; } - - /////////////////////////////////////// - // Attach Fragment Shader Features Next - /////////////////////////////////////// + + /////////////////////////////////////// + // Attach Fragment Shader Features Next + /////////////////////////////////////// // NOTE order of shader object attaching is VERY IMPORTANT!!! - + if (!shader->attachFragmentObject("deferred/globalF.glsl")) { return FALSE; @@ -199,46 +199,46 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } - if(features->calculatesAtmospherics || features->hasGamma || features->isDeferred) - { - if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl")) - { - return FALSE; - } - } + if(features->calculatesAtmospherics || features->hasGamma || features->isDeferred) + { + if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl")) + { + return FALSE; + } + } if (features->calculatesLighting || features->calculatesAtmospherics) - { + { if (!shader->attachFragmentObject("windlight/atmosphericsHelpersF.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } // we want this BEFORE shadows and AO because those facilities use pos/norm access if (features->isDeferred || features->hasReflectionProbes) - { + { if (!shader->attachFragmentObject("deferred/deferredUtil.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - if (features->hasScreenSpaceReflections || features->hasReflectionProbes) - { + if (features->hasScreenSpaceReflections || features->hasReflectionProbes) + { if (!shader->attachFragmentObject("deferred/screenSpaceReflUtil.glsl")) { return FALSE; } - } + } if (features->hasShadows) - { + { if (!shader->attachFragmentObject("deferred/shadowUtil.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } if (features->hasReflectionProbes) { @@ -249,33 +249,33 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } if (features->hasAmbientOcclusion) - { + { if (!shader->attachFragmentObject("deferred/aoUtil.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - if (features->hasGamma || features->isDeferred) - { + if (features->hasGamma || features->isDeferred) + { if (!shader->attachFragmentObject("windlight/gammaF.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - if (features->hasAtmospherics || features->isDeferred) + if (features->hasAtmospherics || features->isDeferred) { if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) { return FALSE; } if (!shader->attachFragmentObject("windlight/atmosphericsF.glsl")) - { - return FALSE; - } - } - + { + return FALSE; + } + } + if (features->isPBRTerrain) { if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl")) @@ -283,71 +283,71 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->hasAtmospherics) - { + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->hasAtmospherics) + { if (!shader->attachFragmentObject("environment/waterFogF.glsl")) - { - return FALSE; - } - } - - if (features->hasLighting) - { - if (features->disableTextureIndex) - { - if (features->hasAlphaMask) - { + { + return FALSE; + } + } + + if (features->hasLighting) + { + if (features->disableTextureIndex) + { + if (features->hasAlphaMask) + { if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl")) - { - return FALSE; - } - } - else - { + { + return FALSE; + } + } + else + { if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl")) - { - return FALSE; - } - } - } - else - { - if (features->hasAlphaMask) - { + { + return FALSE; + } + } + } + else + { + if (features->hasAlphaMask) + { if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl")) - { - return FALSE; - } - } - else - { + { + return FALSE; + } + } + else + { if (!shader->attachFragmentObject("lighting/lightF.glsl")) - { - return FALSE; - } - } - shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1); - } - } - - if (features->mIndexedTextureChannels <= 1) - { - if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl")) - { - return FALSE; - } - } - else - { + { + return FALSE; + } + } + shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1); + } + } + + if (features->mIndexedTextureChannels <= 1) + { + if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl")) + { + return FALSE; + } + } + else + { if (!shader->attachVertexObject("objects/indexedTextureV.glsl")) - { - return FALSE; - } - } + { + return FALSE; + } + } - return TRUE; + return TRUE; } //============================================================================ @@ -355,20 +355,20 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) static std::string get_shader_log(GLuint ret) { - std::string res; - - //get log length - GLint length; + std::string res; + + //get log length + GLint length; glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &length); - if (length > 0) - { - //the log could be any size, so allocate appropriately - GLchar* log = new GLchar[length]; + if (length > 0) + { + //the log could be any size, so allocate appropriately + GLchar* log = new GLchar[length]; glGetShaderInfoLog(ret, length, &length, log); - res = std::string((char *)log); - delete[] log; - } - return res; + res = std::string((char *)log); + delete[] log; + } + return res; } static std::string get_program_log(GLuint ret) @@ -376,7 +376,7 @@ static std::string get_program_log(GLuint ret) LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; std::string res; - //get log length + //get log length GLint length; glGetProgramiv(ret, GL_INFO_LOG_LENGTH, &length); if (length > 0) @@ -408,16 +408,16 @@ static std::string get_object_log(GLuint ret) //dump shader source for debugging void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text) { - char num_str[16]; // U32 = max 10 digits + char num_str[16]; // U32 = max 10 digits - LL_SHADER_LOADING_WARNS() << "\n"; + LL_SHADER_LOADING_WARNS() << "\n"; - for (U32 i = 0; i < shader_code_count; i++) - { - snprintf(num_str, sizeof(num_str), "%4d: ", i+1); - std::string line_number(num_str); - LL_CONT << line_number << shader_code_text[i]; - } + for (U32 i = 0; i < shader_code_count; i++) + { + snprintf(num_str, sizeof(num_str), "%4d: ", i+1); + std::string line_number(num_str); + LL_CONT << line_number << shader_code_text[i]; + } LL_CONT << LL_ENDL; } @@ -431,11 +431,11 @@ void LLShaderMgr::dumpObjectLog(GLuint ret, BOOL warns, const std::string& filen fname = "unknown shader file"; } - if (log.length() > 0) - { + if (log.length() > 0) + { LL_SHADER_LOADING_WARNS() << "Shader loading from " << fname << LL_ENDL; LL_SHADER_LOADING_WARNS() << "\n" << log << LL_ENDL; - } + } } GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map* defines, S32 texture_index_channels) @@ -449,25 +449,25 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } #endif - GLenum error = GL_NO_ERROR; + GLenum error = GL_NO_ERROR; + + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL; + } - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL; - } - - if (filename.empty()) - { - return 0; - } + if (filename.empty()) + { + return 0; + } - //read in from file - LLFILE* file = NULL; + //read in from file + LLFILE* file = NULL; - S32 try_gpu_class = shader_level; - S32 gpu_class; + S32 try_gpu_class = shader_level; + S32 gpu_class; std::string open_file_name; @@ -492,7 +492,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev { //find the most relevant file for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--) - { //search from the current gpu class down to class 1 to find the most relevant shader + { //search from the current gpu class down to class 1 to find the most relevant shader std::stringstream fname; fname << getShaderDirPrefix(); fname << gpu_class << "/" << filename; @@ -513,7 +513,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev */ LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL; - file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */ + file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */ if (file) { LL_DEBUGS("ShaderLoading") << "Loading file: " << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL; @@ -521,31 +521,31 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } } } - - if (file == NULL) - { - LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL; - return 0; - } - //we can't have any lines longer than 1024 characters - //or any shaders longer than 4096 lines... deal - DaveP + if (file == NULL) + { + LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL; + return 0; + } + + //we can't have any lines longer than 1024 characters + //or any shaders longer than 4096 lines... deal - DaveP GLchar buff[1024]; GLchar *extra_code_text[1024]; GLchar *shader_code_text[4096 + LL_ARRAY_SIZE(extra_code_text)] = { NULL }; GLuint extra_code_count = 0, shader_code_count = 0; BOOST_STATIC_ASSERT(LL_ARRAY_SIZE(extra_code_text) < LL_ARRAY_SIZE(shader_code_text)); - - - S32 major_version = gGLManager.mGLSLVersionMajor; - S32 minor_version = gGLManager.mGLSLVersionMinor; - - if (major_version == 1 && minor_version < 30) - { + + + S32 major_version = gGLManager.mGLSLVersionMajor; + S32 minor_version = gGLManager.mGLSLVersionMinor; + + if (major_version == 1 && minor_version < 30) + { llassert(false); // GL 3.1 or later required - } - else - { + } + else + { if (major_version >= 4) { //set version to 400 or 420 @@ -561,24 +561,24 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev else if (major_version == 3) { if (minor_version < 10) - { - shader_code_text[shader_code_count++] = strdup("#version 300\n"); - } - else if (minor_version <= 19) - { - shader_code_text[shader_code_count++] = strdup("#version 310\n"); - } - else if (minor_version <= 29) - { - shader_code_text[shader_code_count++] = strdup("#version 320\n"); - } + { + shader_code_text[shader_code_count++] = strdup("#version 300\n"); + } + else if (minor_version <= 19) + { + shader_code_text[shader_code_count++] = strdup("#version 310\n"); + } + else if (minor_version <= 29) + { + shader_code_text[shader_code_count++] = strdup("#version 320\n"); + } else { shader_code_text[shader_code_count++] = strdup("#version 330\n"); } } - else - { + else + { if (type == GL_GEOMETRY_SHADER) { //set version to 1.50 @@ -595,10 +595,10 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("precision mediump int;\n"); extra_code_text[extra_code_count++] = strdup("precision highp float;\n"); } - } + } - extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); - } + extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); + } if (sMirrorsEnabled) { @@ -613,125 +613,125 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_HDRI 1.0\n"); // bit 2 extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n"); - if (defines) - { - for (auto iter = defines->begin(); iter != defines->end(); ++iter) - { - std::string define = "#define " + iter->first + " " + iter->second + "\n"; - extra_code_text[extra_code_count++] = (GLchar *) strdup(define.c_str()); - } - } - - if( gGLManager.mIsAMD ) - { - extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" ); - } - - if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER) - { - //use specified number of texture channels for indexed texture rendering - - /* prepend shader code that looks like this: - - uniform sampler2D tex0; - uniform sampler2D tex1; - uniform sampler2D tex2; - . - . - . - uniform sampler2D texN; - - flat in int vary_texture_index; - - vec4 ret = vec4(1,0,1,1); - - vec4 diffuseLookup(vec2 texcoord) - { - switch (vary_texture_index) - { - case 0: ret = texture(tex0, texcoord); break; - case 1: ret = texture(tex1, texcoord); break; - case 2: ret = texture(tex2, texcoord); break; - . - . - . - case N: return texture(texN, texcoord); break; - } - - return ret; - } - */ - - extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n"); - - //uniform declartion - for (S32 i = 0; i < texture_index_channels; ++i) - { - std::string decl = llformat("uniform sampler2D tex%d;\n", i); - extra_code_text[extra_code_count++] = strdup(decl.c_str()); - } - - if (texture_index_channels > 1) - { - extra_code_text[extra_code_count++] = strdup("flat in int vary_texture_index;\n"); - } - - extra_code_text[extra_code_count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); - extra_code_text[extra_code_count++] = strdup("{\n"); - - - if (texture_index_channels == 1) - { //don't use flow control, that's silly - extra_code_text[extra_code_count++] = strdup("return texture(tex0, texcoord);\n"); - extra_code_text[extra_code_count++] = strdup("}\n"); - } - else if (major_version > 1 || minor_version >= 30) - { //switches are supported in GLSL 1.30 and later - if (gGLManager.mIsNVIDIA) - { //switches are unreliable on some NVIDIA drivers - for (U32 i = 0; i < texture_index_channels; ++i) - { - std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i); - extra_code_text[extra_code_count++] = strdup(if_string.c_str()); - } - extra_code_text[extra_code_count++] = strdup("\treturn vec4(1,0,1,1);\n"); - extra_code_text[extra_code_count++] = strdup("}\n"); - } - else - { - extra_code_text[extra_code_count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n"); - extra_code_text[extra_code_count++] = strdup("\tswitch (vary_texture_index)\n"); - extra_code_text[extra_code_count++] = strdup("\t{\n"); - - //switch body - for (S32 i = 0; i < texture_index_channels; ++i) - { - std::string case_str = llformat("\t\tcase %d: return texture(tex%d, texcoord);\n", i, i); - extra_code_text[extra_code_count++] = strdup(case_str.c_str()); - } - - extra_code_text[extra_code_count++] = strdup("\t}\n"); - extra_code_text[extra_code_count++] = strdup("\treturn ret;\n"); - extra_code_text[extra_code_count++] = strdup("}\n"); - } - } - else - { //should never get here. Indexed texture rendering requires GLSL 1.30 or later - // (for passing integers between vertex and fragment shaders) - LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL; - } - } - - //copy file into memory - enum { - flag_write_to_out_of_extra_block_area = 0x01 - , flag_extra_block_marker_was_found = 0x02 - }; - - unsigned char flags = flag_write_to_out_of_extra_block_area; - - GLuint out_of_extra_block_counter = 0, start_shader_code = shader_code_count, file_lines_count = 0; - + if (defines) + { + for (auto iter = defines->begin(); iter != defines->end(); ++iter) + { + std::string define = "#define " + iter->first + " " + iter->second + "\n"; + extra_code_text[extra_code_count++] = (GLchar *) strdup(define.c_str()); + } + } + + if( gGLManager.mIsAMD ) + { + extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" ); + } + + if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER) + { + //use specified number of texture channels for indexed texture rendering + + /* prepend shader code that looks like this: + + uniform sampler2D tex0; + uniform sampler2D tex1; + uniform sampler2D tex2; + . + . + . + uniform sampler2D texN; + + flat in int vary_texture_index; + + vec4 ret = vec4(1,0,1,1); + + vec4 diffuseLookup(vec2 texcoord) + { + switch (vary_texture_index) + { + case 0: ret = texture(tex0, texcoord); break; + case 1: ret = texture(tex1, texcoord); break; + case 2: ret = texture(tex2, texcoord); break; + . + . + . + case N: return texture(texN, texcoord); break; + } + + return ret; + } + */ + + extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n"); + + //uniform declartion + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string decl = llformat("uniform sampler2D tex%d;\n", i); + extra_code_text[extra_code_count++] = strdup(decl.c_str()); + } + + if (texture_index_channels > 1) + { + extra_code_text[extra_code_count++] = strdup("flat in int vary_texture_index;\n"); + } + + extra_code_text[extra_code_count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); + extra_code_text[extra_code_count++] = strdup("{\n"); + + + if (texture_index_channels == 1) + { //don't use flow control, that's silly + extra_code_text[extra_code_count++] = strdup("return texture(tex0, texcoord);\n"); + extra_code_text[extra_code_count++] = strdup("}\n"); + } + else if (major_version > 1 || minor_version >= 30) + { //switches are supported in GLSL 1.30 and later + if (gGLManager.mIsNVIDIA) + { //switches are unreliable on some NVIDIA drivers + for (U32 i = 0; i < texture_index_channels; ++i) + { + std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i); + extra_code_text[extra_code_count++] = strdup(if_string.c_str()); + } + extra_code_text[extra_code_count++] = strdup("\treturn vec4(1,0,1,1);\n"); + extra_code_text[extra_code_count++] = strdup("}\n"); + } + else + { + extra_code_text[extra_code_count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n"); + extra_code_text[extra_code_count++] = strdup("\tswitch (vary_texture_index)\n"); + extra_code_text[extra_code_count++] = strdup("\t{\n"); + + //switch body + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string case_str = llformat("\t\tcase %d: return texture(tex%d, texcoord);\n", i, i); + extra_code_text[extra_code_count++] = strdup(case_str.c_str()); + } + + extra_code_text[extra_code_count++] = strdup("\t}\n"); + extra_code_text[extra_code_count++] = strdup("\treturn ret;\n"); + extra_code_text[extra_code_count++] = strdup("}\n"); + } + } + else + { //should never get here. Indexed texture rendering requires GLSL 1.30 or later + // (for passing integers between vertex and fragment shaders) + LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL; + } + } + + //copy file into memory + enum { + flag_write_to_out_of_extra_block_area = 0x01 + , flag_extra_block_marker_was_found = 0x02 + }; + + unsigned char flags = flag_write_to_out_of_extra_block_area; + + GLuint out_of_extra_block_counter = 0, start_shader_code = shader_code_count, file_lines_count = 0; + #define TOUCH_SHADERS 0 #if TOUCH_SHADERS @@ -739,13 +739,13 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev bool touched = false; #endif - while(NULL != fgets((char *)buff, 1024, file) - && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text))) - { - file_lines_count++; + while(NULL != fgets((char *)buff, 1024, file) + && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text))) + { + file_lines_count++; + + bool extra_block_area_found = NULL != strstr((const char*)buff, "[EXTRA_CODE_HERE]"); - bool extra_block_area_found = NULL != strstr((const char*)buff, "[EXTRA_CODE_HERE]"); - #if TOUCH_SHADERS if (NULL != strstr((const char*)buff, marker)) { @@ -753,67 +753,67 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } #endif - if(extra_block_area_found && !(flag_extra_block_marker_was_found & flags)) - { - if(!(flag_write_to_out_of_extra_block_area & flags)) - { - //shift - for(GLuint to = start_shader_code, from = extra_code_count + start_shader_code; - from < shader_code_count; ++to, ++from) - { - shader_code_text[to] = shader_code_text[from]; - } - - shader_code_count -= extra_code_count; - } - - //copy extra code - for(GLuint n = 0; n < extra_code_count - && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)); ++n) - { - shader_code_text[shader_code_count++] = extra_code_text[n]; - } - - extra_code_count = 0; - - flags &= ~flag_write_to_out_of_extra_block_area; - flags |= flag_extra_block_marker_was_found; - } + if(extra_block_area_found && !(flag_extra_block_marker_was_found & flags)) + { + if(!(flag_write_to_out_of_extra_block_area & flags)) + { + //shift + for(GLuint to = start_shader_code, from = extra_code_count + start_shader_code; + from < shader_code_count; ++to, ++from) + { + shader_code_text[to] = shader_code_text[from]; + } + + shader_code_count -= extra_code_count; + } + + //copy extra code + for(GLuint n = 0; n < extra_code_count + && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)); ++n) + { + shader_code_text[shader_code_count++] = extra_code_text[n]; + } + + extra_code_count = 0; + + flags &= ~flag_write_to_out_of_extra_block_area; + flags |= flag_extra_block_marker_was_found; + } else { shader_code_text[shader_code_count] = (GLchar *)strdup((char *)buff); - + if(flag_write_to_out_of_extra_block_area & flags) { shader_code_text[extra_code_count + start_shader_code + out_of_extra_block_counter] = shader_code_text[shader_code_count]; out_of_extra_block_counter++; - + if(out_of_extra_block_counter == extra_code_count) { shader_code_count += extra_code_count; flags &= ~flag_write_to_out_of_extra_block_area; } } - + ++shader_code_count; - } - } //while - - if(!(flag_extra_block_marker_was_found & flags)) - { - for(GLuint n = start_shader_code; n < extra_code_count + start_shader_code; ++n) - { - shader_code_text[n] = extra_code_text[n - start_shader_code]; - } - - if (file_lines_count < extra_code_count) - { - shader_code_count += extra_code_count; - } - - extra_code_count = 0; - } + } + } //while + + if(!(flag_extra_block_marker_was_found & flags)) + { + for(GLuint n = start_shader_code; n < extra_code_count + start_shader_code; ++n) + { + shader_code_text[n] = extra_code_text[n - start_shader_code]; + } + + if (file_lines_count < extra_code_count) + { + shader_code_count += extra_code_count; + } + + extra_code_count = 0; + } #if TOUCH_SHADERS if (!touched) @@ -822,106 +822,106 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } #endif - fclose(file); + fclose(file); - //create shader object + //create shader object GLuint ret = glCreateShader(type); - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShader: " << error << " for file: " << open_file_name << LL_ENDL; - if (ret) - { - glDeleteShader(ret); //no longer need handle - ret = 0; - } - } - - //load source - if (ret) - { - glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL); - - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSource: " << error << " for file: " << open_file_name << LL_ENDL; - glDeleteShader(ret); //no longer need handle - ret = 0; - } - } - - //compile source - if (ret) - { - glCompileShader(ret); - - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShader: " << error << " for file: " << open_file_name << LL_ENDL; - glDeleteShader(ret); //no longer need handle - ret = 0; - } - } - - if (error == GL_NO_ERROR) - { - //check for errors - GLint success = GL_TRUE; + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShader: " << error << " for file: " << open_file_name << LL_ENDL; + if (ret) + { + glDeleteShader(ret); //no longer need handle + ret = 0; + } + } + + //load source + if (ret) + { + glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL); + + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSource: " << error << " for file: " << open_file_name << LL_ENDL; + glDeleteShader(ret); //no longer need handle + ret = 0; + } + } + + //compile source + if (ret) + { + glCompileShader(ret); + + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShader: " << error << " for file: " << open_file_name << LL_ENDL; + glDeleteShader(ret); //no longer need handle + ret = 0; + } + } + + if (error == GL_NO_ERROR) + { + //check for errors + GLint success = GL_TRUE; glGetShaderiv(ret, GL_COMPILE_STATUS, &success); - error = glGetError(); - if (error != GL_NO_ERROR || success == GL_FALSE) - { - //an error occured, print log - LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL; - dumpObjectLog(ret, TRUE, open_file_name); - dumpShaderSource(shader_code_count, shader_code_text); - glDeleteShader(ret); //no longer need handle - ret = 0; - } - } - else - { - ret = 0; - } - stop_glerror(); - - //free memory - for (GLuint i = 0; i < shader_code_count; i++) - { - free(shader_code_text[i]); - } - - //successfully loaded, save results - if (ret) - { - // Add shader file to map + error = glGetError(); + if (error != GL_NO_ERROR || success == GL_FALSE) + { + //an error occured, print log + LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL; + dumpObjectLog(ret, TRUE, open_file_name); + dumpShaderSource(shader_code_count, shader_code_text); + glDeleteShader(ret); //no longer need handle + ret = 0; + } + } + else + { + ret = 0; + } + stop_glerror(); + + //free memory + for (GLuint i = 0; i < shader_code_count; i++) + { + free(shader_code_text[i]); + } + + //successfully loaded, save results + if (ret) + { + // Add shader file to map if (type == GL_VERTEX_SHADER) { mVertexShaderObjects[filename] = ret; } else if (type == GL_FRAGMENT_SHADER) { mFragmentShaderObjects[filename] = ret; } - shader_level = try_gpu_class; - } - else - { - if (shader_level > 1) - { - shader_level--; - return loadShaderFile(filename, shader_level, type, defines, texture_index_channels); - } - LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; - } - return ret; + shader_level = try_gpu_class; + } + else + { + if (shader_level > 1) + { + shader_level--; + return loadShaderFile(filename, shader_level, type, defines, texture_index_channels); + } + LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; + } + return ret; } BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors) { - //check for errors + //check for errors { LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER("glLinkProgram"); glLinkProgram(obj); @@ -941,238 +941,238 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors) } } - std::string log = get_program_log(obj); - LLStringUtil::toLower(log); - if (log.find("software") != std::string::npos) - { - LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL; - success = GL_FALSE; - suppress_errors = FALSE; - } - return success; + std::string log = get_program_log(obj); + LLStringUtil::toLower(log); + if (log.find("software") != std::string::npos) + { + LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL; + success = GL_FALSE; + suppress_errors = FALSE; + } + return success; } BOOL LLShaderMgr::validateProgramObject(GLuint obj) { - //check program validity against current GL - glValidateProgram(obj); - GLint success = GL_TRUE; + //check program validity against current GL + glValidateProgram(obj); + GLint success = GL_TRUE; glGetProgramiv(obj, GL_LINK_STATUS, &success); - if (success == GL_FALSE) - { - LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL; - dumpObjectLog(obj); - } - else - { - dumpObjectLog(obj, FALSE); - } - - return success; + if (success == GL_FALSE) + { + LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL; + dumpObjectLog(obj); + } + else + { + dumpObjectLog(obj, FALSE); + } + + return success; } void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version) { - LL_INFOS() << "Initializing shader cache" << LL_ENDL; - - mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled; - - if(!mShaderCacheEnabled || mShaderCacheInitialized) - return; - - mShaderCacheInitialized = true; - - mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); - LLFile::mkdir(mShaderCacheDir); - - { - std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); - if (gDirUtilp->fileExists(meta_out_path)) - { - LL_INFOS() << "Loading shader cache metadata" << LL_ENDL; - - llifstream instream(meta_out_path); - LLSD in_data; - LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); - instream.close(); - - if (old_cache_version == current_cache_version) - { - for (const auto& data_pair : llsd::inMap(in_data)) - { - ProgramBinaryData binary_info = ProgramBinaryData(); - binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger(); - binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger(); - binary_info.mLastUsedTime = data_pair.second["last_used"].asReal(); - mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info); - } - } - else - { - LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL; - clearShaderCache(); - } - } - } + LL_INFOS() << "Initializing shader cache" << LL_ENDL; + + mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled; + + if(!mShaderCacheEnabled || mShaderCacheInitialized) + return; + + mShaderCacheInitialized = true; + + mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); + LLFile::mkdir(mShaderCacheDir); + + { + std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); + if (gDirUtilp->fileExists(meta_out_path)) + { + LL_INFOS() << "Loading shader cache metadata" << LL_ENDL; + + llifstream instream(meta_out_path); + LLSD in_data; + LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); + instream.close(); + + if (old_cache_version == current_cache_version) + { + for (const auto& data_pair : llsd::inMap(in_data)) + { + ProgramBinaryData binary_info = ProgramBinaryData(); + binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger(); + binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger(); + binary_info.mLastUsedTime = data_pair.second["last_used"].asReal(); + mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info); + } + } + else + { + LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL; + clearShaderCache(); + } + } + } } void LLShaderMgr::clearShaderCache() { - std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); - LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL; - const std::string mask = "*"; - gDirUtilp->deleteFilesInDir(shader_cache, mask); - mShaderBinaryCache.clear(); + std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); + LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL; + const std::string mask = "*"; + gDirUtilp->deleteFilesInDir(shader_cache, mask); + mShaderBinaryCache.clear(); } void LLShaderMgr::persistShaderCacheMetadata() { - if(!mShaderCacheEnabled) return; - - LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL; - - LLSD out = LLSD::emptyMap(); - - static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days - const F32 current_time = LLTimer::getTotalSeconds(); - for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();) - { - const ProgramBinaryData& shader_metadata = it->second; - if ((shader_metadata.mLastUsedTime + LRU_TIME) < current_time) - { - std::string shader_path = gDirUtilp->add(mShaderCacheDir, it->first.asString() + ".shaderbin"); - LLFile::remove(shader_path); - it = mShaderBinaryCache.erase(it); - } - else - { - LLSD data = LLSD::emptyMap(); - data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat); - data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength); - data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime); - out[it->first.asString()] = data; - ++it; - } - } - - std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); - llofstream outstream(meta_out_path); - LLSDSerialize::toNotation(out, outstream); - outstream.close(); + if(!mShaderCacheEnabled) return; + + LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL; + + LLSD out = LLSD::emptyMap(); + + static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days + const F32 current_time = LLTimer::getTotalSeconds(); + for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();) + { + const ProgramBinaryData& shader_metadata = it->second; + if ((shader_metadata.mLastUsedTime + LRU_TIME) < current_time) + { + std::string shader_path = gDirUtilp->add(mShaderCacheDir, it->first.asString() + ".shaderbin"); + LLFile::remove(shader_path); + it = mShaderBinaryCache.erase(it); + } + else + { + LLSD data = LLSD::emptyMap(); + data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat); + data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength); + data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime); + out[it->first.asString()] = data; + ++it; + } + } + + std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); + llofstream outstream(meta_out_path); + LLSDSerialize::toNotation(out, outstream); + outstream.close(); } bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader) { - if (!mShaderCacheEnabled) return false; - - glProgramParameteri(shader->mProgramObject, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); - - auto binary_iter = mShaderBinaryCache.find(shader->mShaderHash); - if (binary_iter != mShaderBinaryCache.end()) - { - std::string in_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin"); - auto& shader_info = binary_iter->second; - if (shader_info.mBinaryLength > 0) - { - std::vector in_data; - in_data.resize(shader_info.mBinaryLength); - - LLUniqueFile filep = LLFile::fopen(in_path, "rb"); - if (filep) - { - size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep); - filep.close(); - - if (result == in_data.size()) - { - GLenum error = glGetError(); // Clear current error - glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength); - - error = glGetError(); - GLint success = GL_TRUE; - glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success); - if (error == GL_NO_ERROR && success == GL_TRUE) - { - binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds(); - LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL; - return true; - } - } - } - } - //an error occured, normally we would print log but in this case it means the shader needs recompiling. - LL_INFOS() << "Failed to load cached binary for shader: " << shader->mName << " falling back to compilation" << LL_ENDL; - LLFile::remove(in_path); - mShaderBinaryCache.erase(binary_iter); - } - return false; + if (!mShaderCacheEnabled) return false; + + glProgramParameteri(shader->mProgramObject, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); + + auto binary_iter = mShaderBinaryCache.find(shader->mShaderHash); + if (binary_iter != mShaderBinaryCache.end()) + { + std::string in_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin"); + auto& shader_info = binary_iter->second; + if (shader_info.mBinaryLength > 0) + { + std::vector in_data; + in_data.resize(shader_info.mBinaryLength); + + LLUniqueFile filep = LLFile::fopen(in_path, "rb"); + if (filep) + { + size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep); + filep.close(); + + if (result == in_data.size()) + { + GLenum error = glGetError(); // Clear current error + glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength); + + error = glGetError(); + GLint success = GL_TRUE; + glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success); + if (error == GL_NO_ERROR && success == GL_TRUE) + { + binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds(); + LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL; + return true; + } + } + } + } + //an error occured, normally we would print log but in this case it means the shader needs recompiling. + LL_INFOS() << "Failed to load cached binary for shader: " << shader->mName << " falling back to compilation" << LL_ENDL; + LLFile::remove(in_path); + mShaderBinaryCache.erase(binary_iter); + } + return false; } bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader) { - if (!mShaderCacheEnabled) return true; - - ProgramBinaryData binary_info = ProgramBinaryData(); - glGetProgramiv(shader->mProgramObject, GL_PROGRAM_BINARY_LENGTH, &binary_info.mBinaryLength); - if (binary_info.mBinaryLength > 0) - { - std::vector program_binary; - program_binary.resize(binary_info.mBinaryLength); - - GLenum error = glGetError(); // Clear current error - glGetProgramBinary(shader->mProgramObject, program_binary.size() * sizeof(U8), nullptr, &binary_info.mBinaryFormat, program_binary.data()); - error = glGetError(); - if (error == GL_NO_ERROR) - { - std::string out_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin"); - LLUniqueFile outfile = LLFile::fopen(out_path, "wb"); - if (outfile) - { - fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile); - outfile.close(); - - binary_info.mLastUsedTime = LLTimer::getTotalSeconds(); - - mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info); - return true; - } - } - } - return false; + if (!mShaderCacheEnabled) return true; + + ProgramBinaryData binary_info = ProgramBinaryData(); + glGetProgramiv(shader->mProgramObject, GL_PROGRAM_BINARY_LENGTH, &binary_info.mBinaryLength); + if (binary_info.mBinaryLength > 0) + { + std::vector program_binary; + program_binary.resize(binary_info.mBinaryLength); + + GLenum error = glGetError(); // Clear current error + glGetProgramBinary(shader->mProgramObject, program_binary.size() * sizeof(U8), nullptr, &binary_info.mBinaryFormat, program_binary.data()); + error = glGetError(); + if (error == GL_NO_ERROR) + { + std::string out_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin"); + LLUniqueFile outfile = LLFile::fopen(out_path, "wb"); + if (outfile) + { + fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile); + outfile.close(); + + binary_info.mLastUsedTime = LLTimer::getTotalSeconds(); + + mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info); + return true; + } + } + } + return false; } //virtual void LLShaderMgr::initAttribsAndUniforms() { - //MUST match order of enum in LLVertexBuffer.h - mReservedAttribs.push_back("position"); - mReservedAttribs.push_back("normal"); - mReservedAttribs.push_back("texcoord0"); - mReservedAttribs.push_back("texcoord1"); - mReservedAttribs.push_back("texcoord2"); - mReservedAttribs.push_back("texcoord3"); - mReservedAttribs.push_back("diffuse_color"); - mReservedAttribs.push_back("emissive"); - mReservedAttribs.push_back("tangent"); - mReservedAttribs.push_back("weight"); - mReservedAttribs.push_back("weight4"); - mReservedAttribs.push_back("clothing"); - mReservedAttribs.push_back("texture_index"); - - //matrix state - mReservedUniforms.push_back("modelview_matrix"); - mReservedUniforms.push_back("projection_matrix"); - mReservedUniforms.push_back("inv_proj"); - mReservedUniforms.push_back("modelview_projection_matrix"); + //MUST match order of enum in LLVertexBuffer.h + mReservedAttribs.push_back("position"); + mReservedAttribs.push_back("normal"); + mReservedAttribs.push_back("texcoord0"); + mReservedAttribs.push_back("texcoord1"); + mReservedAttribs.push_back("texcoord2"); + mReservedAttribs.push_back("texcoord3"); + mReservedAttribs.push_back("diffuse_color"); + mReservedAttribs.push_back("emissive"); + mReservedAttribs.push_back("tangent"); + mReservedAttribs.push_back("weight"); + mReservedAttribs.push_back("weight4"); + mReservedAttribs.push_back("clothing"); + mReservedAttribs.push_back("texture_index"); + + //matrix state + mReservedUniforms.push_back("modelview_matrix"); + mReservedUniforms.push_back("projection_matrix"); + mReservedUniforms.push_back("inv_proj"); + mReservedUniforms.push_back("modelview_projection_matrix"); mReservedUniforms.push_back("inv_modelview"); mReservedUniforms.push_back("identity_matrix"); - mReservedUniforms.push_back("normal_matrix"); - mReservedUniforms.push_back("texture_matrix0"); - mReservedUniforms.push_back("texture_matrix1"); - mReservedUniforms.push_back("texture_matrix2"); - mReservedUniforms.push_back("texture_matrix3"); - mReservedUniforms.push_back("object_plane_s"); - mReservedUniforms.push_back("object_plane_t"); + mReservedUniforms.push_back("normal_matrix"); + mReservedUniforms.push_back("texture_matrix0"); + mReservedUniforms.push_back("texture_matrix1"); + mReservedUniforms.push_back("texture_matrix2"); + mReservedUniforms.push_back("texture_matrix3"); + mReservedUniforms.push_back("object_plane_s"); + mReservedUniforms.push_back("object_plane_t"); mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF) mReservedUniforms.push_back("texture_normal_transform"); // (GLTF) @@ -1181,38 +1181,38 @@ void LLShaderMgr::initAttribsAndUniforms() llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1); - mReservedUniforms.push_back("viewport"); + mReservedUniforms.push_back("viewport"); - mReservedUniforms.push_back("light_position"); - mReservedUniforms.push_back("light_direction"); - mReservedUniforms.push_back("light_attenuation"); + mReservedUniforms.push_back("light_position"); + mReservedUniforms.push_back("light_direction"); + mReservedUniforms.push_back("light_attenuation"); mReservedUniforms.push_back("light_deferred_attenuation"); - mReservedUniforms.push_back("light_diffuse"); - mReservedUniforms.push_back("light_ambient"); - mReservedUniforms.push_back("light_count"); - mReservedUniforms.push_back("light"); - mReservedUniforms.push_back("light_col"); - mReservedUniforms.push_back("far_z"); + mReservedUniforms.push_back("light_diffuse"); + mReservedUniforms.push_back("light_ambient"); + mReservedUniforms.push_back("light_count"); + mReservedUniforms.push_back("light"); + mReservedUniforms.push_back("light_col"); + mReservedUniforms.push_back("far_z"); - llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1); + llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1); //NOTE: MUST match order in eGLSLReservedUniforms - mReservedUniforms.push_back("proj_mat"); - mReservedUniforms.push_back("proj_near"); - mReservedUniforms.push_back("proj_p"); - mReservedUniforms.push_back("proj_n"); - mReservedUniforms.push_back("proj_origin"); - mReservedUniforms.push_back("proj_range"); - mReservedUniforms.push_back("proj_ambiance"); - mReservedUniforms.push_back("proj_shadow_idx"); - mReservedUniforms.push_back("shadow_fade"); - mReservedUniforms.push_back("proj_focus"); - mReservedUniforms.push_back("proj_lod"); - mReservedUniforms.push_back("proj_ambient_lod"); - - llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1); - - mReservedUniforms.push_back("color"); + mReservedUniforms.push_back("proj_mat"); + mReservedUniforms.push_back("proj_near"); + mReservedUniforms.push_back("proj_p"); + mReservedUniforms.push_back("proj_n"); + mReservedUniforms.push_back("proj_origin"); + mReservedUniforms.push_back("proj_range"); + mReservedUniforms.push_back("proj_ambiance"); + mReservedUniforms.push_back("proj_shadow_idx"); + mReservedUniforms.push_back("shadow_fade"); + mReservedUniforms.push_back("proj_focus"); + mReservedUniforms.push_back("proj_lod"); + mReservedUniforms.push_back("proj_ambient_lod"); + + llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1); + + mReservedUniforms.push_back("color"); mReservedUniforms.push_back("emissiveColor"); mReservedUniforms.push_back("metallicFactor"); mReservedUniforms.push_back("roughnessFactor"); @@ -1220,95 +1220,95 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("clipPlane"); mReservedUniforms.push_back("clipSign"); - mReservedUniforms.push_back("diffuseMap"); + mReservedUniforms.push_back("diffuseMap"); mReservedUniforms.push_back("altDiffuseMap"); - mReservedUniforms.push_back("specularMap"); + mReservedUniforms.push_back("specularMap"); mReservedUniforms.push_back("emissiveMap"); - mReservedUniforms.push_back("bumpMap"); + mReservedUniforms.push_back("bumpMap"); mReservedUniforms.push_back("bumpMap2"); - mReservedUniforms.push_back("environmentMap"); + mReservedUniforms.push_back("environmentMap"); mReservedUniforms.push_back("sceneMap"); mReservedUniforms.push_back("sceneDepth"); mReservedUniforms.push_back("reflectionProbes"); mReservedUniforms.push_back("irradianceProbes"); mReservedUniforms.push_back("heroProbes"); - mReservedUniforms.push_back("cloud_noise_texture"); + mReservedUniforms.push_back("cloud_noise_texture"); mReservedUniforms.push_back("cloud_noise_texture_next"); - mReservedUniforms.push_back("fullbright"); - mReservedUniforms.push_back("lightnorm"); - mReservedUniforms.push_back("sunlight_color"); - mReservedUniforms.push_back("ambient_color"); + mReservedUniforms.push_back("fullbright"); + mReservedUniforms.push_back("lightnorm"); + mReservedUniforms.push_back("sunlight_color"); + mReservedUniforms.push_back("ambient_color"); mReservedUniforms.push_back("sky_hdr_scale"); mReservedUniforms.push_back("sky_sunlight_scale"); mReservedUniforms.push_back("sky_ambient_scale"); - mReservedUniforms.push_back("blue_horizon"); + mReservedUniforms.push_back("blue_horizon"); mReservedUniforms.push_back("blue_density"); mReservedUniforms.push_back("haze_horizon"); - mReservedUniforms.push_back("haze_density"); - mReservedUniforms.push_back("cloud_shadow"); - mReservedUniforms.push_back("density_multiplier"); - mReservedUniforms.push_back("distance_multiplier"); - mReservedUniforms.push_back("max_y"); - mReservedUniforms.push_back("glow"); - mReservedUniforms.push_back("cloud_color"); - mReservedUniforms.push_back("cloud_pos_density1"); - mReservedUniforms.push_back("cloud_pos_density2"); - mReservedUniforms.push_back("cloud_scale"); - mReservedUniforms.push_back("gamma"); - mReservedUniforms.push_back("scene_light_strength"); + mReservedUniforms.push_back("haze_density"); + mReservedUniforms.push_back("cloud_shadow"); + mReservedUniforms.push_back("density_multiplier"); + mReservedUniforms.push_back("distance_multiplier"); + mReservedUniforms.push_back("max_y"); + mReservedUniforms.push_back("glow"); + mReservedUniforms.push_back("cloud_color"); + mReservedUniforms.push_back("cloud_pos_density1"); + mReservedUniforms.push_back("cloud_pos_density2"); + mReservedUniforms.push_back("cloud_scale"); + mReservedUniforms.push_back("gamma"); + mReservedUniforms.push_back("scene_light_strength"); - llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1); + llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1); - mReservedUniforms.push_back("center"); - mReservedUniforms.push_back("size"); - mReservedUniforms.push_back("falloff"); + mReservedUniforms.push_back("center"); + mReservedUniforms.push_back("size"); + mReservedUniforms.push_back("falloff"); - mReservedUniforms.push_back("box_center"); - mReservedUniforms.push_back("box_size"); + mReservedUniforms.push_back("box_center"); + mReservedUniforms.push_back("box_size"); - mReservedUniforms.push_back("minLuminance"); - mReservedUniforms.push_back("maxExtractAlpha"); - mReservedUniforms.push_back("lumWeights"); - mReservedUniforms.push_back("warmthWeights"); - mReservedUniforms.push_back("warmthAmount"); - mReservedUniforms.push_back("glowStrength"); - mReservedUniforms.push_back("glowDelta"); - mReservedUniforms.push_back("glowNoiseMap"); + mReservedUniforms.push_back("minLuminance"); + mReservedUniforms.push_back("maxExtractAlpha"); + mReservedUniforms.push_back("lumWeights"); + mReservedUniforms.push_back("warmthWeights"); + mReservedUniforms.push_back("warmthAmount"); + mReservedUniforms.push_back("glowStrength"); + mReservedUniforms.push_back("glowDelta"); + mReservedUniforms.push_back("glowNoiseMap"); - llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1); + llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1); - mReservedUniforms.push_back("minimum_alpha"); - mReservedUniforms.push_back("emissive_brightness"); + mReservedUniforms.push_back("minimum_alpha"); + mReservedUniforms.push_back("emissive_brightness"); // Deferred - mReservedUniforms.push_back("shadow_matrix"); - mReservedUniforms.push_back("env_mat"); - mReservedUniforms.push_back("shadow_clip"); - mReservedUniforms.push_back("sun_wash"); - mReservedUniforms.push_back("shadow_noise"); - mReservedUniforms.push_back("blur_size"); - mReservedUniforms.push_back("ssao_radius"); - mReservedUniforms.push_back("ssao_max_radius"); - mReservedUniforms.push_back("ssao_factor"); - mReservedUniforms.push_back("ssao_factor_inv"); - mReservedUniforms.push_back("ssao_effect_mat"); - mReservedUniforms.push_back("screen_res"); - mReservedUniforms.push_back("near_clip"); - mReservedUniforms.push_back("shadow_offset"); - mReservedUniforms.push_back("shadow_bias"); - mReservedUniforms.push_back("spot_shadow_bias"); - mReservedUniforms.push_back("spot_shadow_offset"); - mReservedUniforms.push_back("sun_dir"); + mReservedUniforms.push_back("shadow_matrix"); + mReservedUniforms.push_back("env_mat"); + mReservedUniforms.push_back("shadow_clip"); + mReservedUniforms.push_back("sun_wash"); + mReservedUniforms.push_back("shadow_noise"); + mReservedUniforms.push_back("blur_size"); + mReservedUniforms.push_back("ssao_radius"); + mReservedUniforms.push_back("ssao_max_radius"); + mReservedUniforms.push_back("ssao_factor"); + mReservedUniforms.push_back("ssao_factor_inv"); + mReservedUniforms.push_back("ssao_effect_mat"); + mReservedUniforms.push_back("screen_res"); + mReservedUniforms.push_back("near_clip"); + mReservedUniforms.push_back("shadow_offset"); + mReservedUniforms.push_back("shadow_bias"); + mReservedUniforms.push_back("spot_shadow_bias"); + mReservedUniforms.push_back("spot_shadow_offset"); + mReservedUniforms.push_back("sun_dir"); mReservedUniforms.push_back("moon_dir"); - mReservedUniforms.push_back("shadow_res"); - mReservedUniforms.push_back("proj_shadow_res"); - mReservedUniforms.push_back("depth_cutoff"); - mReservedUniforms.push_back("norm_cutoff"); - mReservedUniforms.push_back("shadow_target_width"); - - llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH + 1); + mReservedUniforms.push_back("shadow_res"); + mReservedUniforms.push_back("proj_shadow_res"); + mReservedUniforms.push_back("depth_cutoff"); + mReservedUniforms.push_back("norm_cutoff"); + mReservedUniforms.push_back("shadow_target_width"); + + llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH + 1); mReservedUniforms.push_back("iterationCount"); mReservedUniforms.push_back("rayStep"); @@ -1322,105 +1322,105 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("inv_modelview_delta"); mReservedUniforms.push_back("cube_snapshot"); - mReservedUniforms.push_back("tc_scale"); - mReservedUniforms.push_back("rcp_screen_res"); - mReservedUniforms.push_back("rcp_frame_opt"); - mReservedUniforms.push_back("rcp_frame_opt2"); - - mReservedUniforms.push_back("focal_distance"); - mReservedUniforms.push_back("blur_constant"); - mReservedUniforms.push_back("tan_pixel_angle"); - mReservedUniforms.push_back("magnification"); - mReservedUniforms.push_back("max_cof"); - mReservedUniforms.push_back("res_scale"); - mReservedUniforms.push_back("dof_width"); - mReservedUniforms.push_back("dof_height"); - - mReservedUniforms.push_back("depthMap"); - mReservedUniforms.push_back("shadowMap0"); - mReservedUniforms.push_back("shadowMap1"); - mReservedUniforms.push_back("shadowMap2"); - mReservedUniforms.push_back("shadowMap3"); - mReservedUniforms.push_back("shadowMap4"); - mReservedUniforms.push_back("shadowMap5"); - - llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1); - - mReservedUniforms.push_back("normalMap"); - mReservedUniforms.push_back("positionMap"); - mReservedUniforms.push_back("diffuseRect"); - mReservedUniforms.push_back("specularRect"); + mReservedUniforms.push_back("tc_scale"); + mReservedUniforms.push_back("rcp_screen_res"); + mReservedUniforms.push_back("rcp_frame_opt"); + mReservedUniforms.push_back("rcp_frame_opt2"); + + mReservedUniforms.push_back("focal_distance"); + mReservedUniforms.push_back("blur_constant"); + mReservedUniforms.push_back("tan_pixel_angle"); + mReservedUniforms.push_back("magnification"); + mReservedUniforms.push_back("max_cof"); + mReservedUniforms.push_back("res_scale"); + mReservedUniforms.push_back("dof_width"); + mReservedUniforms.push_back("dof_height"); + + mReservedUniforms.push_back("depthMap"); + mReservedUniforms.push_back("shadowMap0"); + mReservedUniforms.push_back("shadowMap1"); + mReservedUniforms.push_back("shadowMap2"); + mReservedUniforms.push_back("shadowMap3"); + mReservedUniforms.push_back("shadowMap4"); + mReservedUniforms.push_back("shadowMap5"); + + llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1); + + mReservedUniforms.push_back("normalMap"); + mReservedUniforms.push_back("positionMap"); + mReservedUniforms.push_back("diffuseRect"); + mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("emissiveRect"); mReservedUniforms.push_back("exposureMap"); mReservedUniforms.push_back("brdfLut"); - mReservedUniforms.push_back("noiseMap"); - mReservedUniforms.push_back("lightFunc"); - mReservedUniforms.push_back("lightMap"); - mReservedUniforms.push_back("bloomMap"); - mReservedUniforms.push_back("projectionMap"); - mReservedUniforms.push_back("norm_mat"); - mReservedUniforms.push_back("texture_gamma"); - - mReservedUniforms.push_back("specular_color"); - mReservedUniforms.push_back("env_intensity"); - - mReservedUniforms.push_back("matrixPalette"); - mReservedUniforms.push_back("translationPalette"); - - mReservedUniforms.push_back("screenTex"); - mReservedUniforms.push_back("screenDepth"); - mReservedUniforms.push_back("refTex"); - mReservedUniforms.push_back("eyeVec"); - mReservedUniforms.push_back("time"); - mReservedUniforms.push_back("waveDir1"); - mReservedUniforms.push_back("waveDir2"); - mReservedUniforms.push_back("lightDir"); - mReservedUniforms.push_back("specular"); - mReservedUniforms.push_back("lightExp"); - mReservedUniforms.push_back("waterFogColor"); + mReservedUniforms.push_back("noiseMap"); + mReservedUniforms.push_back("lightFunc"); + mReservedUniforms.push_back("lightMap"); + mReservedUniforms.push_back("bloomMap"); + mReservedUniforms.push_back("projectionMap"); + mReservedUniforms.push_back("norm_mat"); + mReservedUniforms.push_back("texture_gamma"); + + mReservedUniforms.push_back("specular_color"); + mReservedUniforms.push_back("env_intensity"); + + mReservedUniforms.push_back("matrixPalette"); + mReservedUniforms.push_back("translationPalette"); + + mReservedUniforms.push_back("screenTex"); + mReservedUniforms.push_back("screenDepth"); + mReservedUniforms.push_back("refTex"); + mReservedUniforms.push_back("eyeVec"); + mReservedUniforms.push_back("time"); + mReservedUniforms.push_back("waveDir1"); + mReservedUniforms.push_back("waveDir2"); + mReservedUniforms.push_back("lightDir"); + mReservedUniforms.push_back("specular"); + mReservedUniforms.push_back("lightExp"); + mReservedUniforms.push_back("waterFogColor"); mReservedUniforms.push_back("waterFogColorLinear"); - mReservedUniforms.push_back("waterFogDensity"); - mReservedUniforms.push_back("waterFogKS"); - mReservedUniforms.push_back("refScale"); - mReservedUniforms.push_back("waterHeight"); - mReservedUniforms.push_back("waterPlane"); - mReservedUniforms.push_back("normScale"); - mReservedUniforms.push_back("fresnelScale"); - mReservedUniforms.push_back("fresnelOffset"); - mReservedUniforms.push_back("blurMultiplier"); - mReservedUniforms.push_back("sunAngle"); - mReservedUniforms.push_back("scaledAngle"); - mReservedUniforms.push_back("sunAngle2"); - - mReservedUniforms.push_back("camPosLocal"); - - mReservedUniforms.push_back("gWindDir"); - mReservedUniforms.push_back("gSinWaveParams"); - mReservedUniforms.push_back("gGravity"); - - mReservedUniforms.push_back("detail_0"); - mReservedUniforms.push_back("detail_1"); - mReservedUniforms.push_back("detail_2"); - mReservedUniforms.push_back("detail_3"); - - mReservedUniforms.push_back("alpha_ramp"); - - mReservedUniforms.push_back("detail_0_base_color"); - mReservedUniforms.push_back("detail_1_base_color"); - mReservedUniforms.push_back("detail_2_base_color"); - mReservedUniforms.push_back("detail_3_base_color"); - mReservedUniforms.push_back("detail_0_normal"); - mReservedUniforms.push_back("detail_1_normal"); - mReservedUniforms.push_back("detail_2_normal"); - mReservedUniforms.push_back("detail_3_normal"); - mReservedUniforms.push_back("detail_0_metallic_roughness"); - mReservedUniforms.push_back("detail_1_metallic_roughness"); - mReservedUniforms.push_back("detail_2_metallic_roughness"); - mReservedUniforms.push_back("detail_3_metallic_roughness"); - mReservedUniforms.push_back("detail_0_emissive"); - mReservedUniforms.push_back("detail_1_emissive"); - mReservedUniforms.push_back("detail_2_emissive"); - mReservedUniforms.push_back("detail_3_emissive"); + mReservedUniforms.push_back("waterFogDensity"); + mReservedUniforms.push_back("waterFogKS"); + mReservedUniforms.push_back("refScale"); + mReservedUniforms.push_back("waterHeight"); + mReservedUniforms.push_back("waterPlane"); + mReservedUniforms.push_back("normScale"); + mReservedUniforms.push_back("fresnelScale"); + mReservedUniforms.push_back("fresnelOffset"); + mReservedUniforms.push_back("blurMultiplier"); + mReservedUniforms.push_back("sunAngle"); + mReservedUniforms.push_back("scaledAngle"); + mReservedUniforms.push_back("sunAngle2"); + + mReservedUniforms.push_back("camPosLocal"); + + mReservedUniforms.push_back("gWindDir"); + mReservedUniforms.push_back("gSinWaveParams"); + mReservedUniforms.push_back("gGravity"); + + mReservedUniforms.push_back("detail_0"); + mReservedUniforms.push_back("detail_1"); + mReservedUniforms.push_back("detail_2"); + mReservedUniforms.push_back("detail_3"); + + mReservedUniforms.push_back("alpha_ramp"); + + mReservedUniforms.push_back("detail_0_base_color"); + mReservedUniforms.push_back("detail_1_base_color"); + mReservedUniforms.push_back("detail_2_base_color"); + mReservedUniforms.push_back("detail_3_base_color"); + mReservedUniforms.push_back("detail_0_normal"); + mReservedUniforms.push_back("detail_1_normal"); + mReservedUniforms.push_back("detail_2_normal"); + mReservedUniforms.push_back("detail_3_normal"); + mReservedUniforms.push_back("detail_0_metallic_roughness"); + mReservedUniforms.push_back("detail_1_metallic_roughness"); + mReservedUniforms.push_back("detail_2_metallic_roughness"); + mReservedUniforms.push_back("detail_3_metallic_roughness"); + mReservedUniforms.push_back("detail_0_emissive"); + mReservedUniforms.push_back("detail_1_emissive"); + mReservedUniforms.push_back("detail_2_emissive"); + mReservedUniforms.push_back("detail_3_emissive"); mReservedUniforms.push_back("baseColorFactors"); mReservedUniforms.push_back("metallicFactors"); @@ -1428,8 +1428,8 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("emissiveColors"); mReservedUniforms.push_back("minimum_alphas"); - mReservedUniforms.push_back("origin"); - mReservedUniforms.push_back("display_gamma"); + mReservedUniforms.push_back("origin"); + mReservedUniforms.push_back("display_gamma"); mReservedUniforms.push_back("inscatter"); mReservedUniforms.push_back("sun_size"); @@ -1462,17 +1462,17 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("debug_normal_draw_length"); - llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); + llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); - std::set dupe_check; + std::set dupe_check; - for (U32 i = 0; i < mReservedUniforms.size(); ++i) - { - if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end()) - { - LL_ERRS() << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << LL_ENDL; - } - dupe_check.insert(mReservedUniforms[i]); - } + for (U32 i = 0; i < mReservedUniforms.size(); ++i) + { + if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end()) + { + LL_ERRS() << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << LL_ENDL; + } + dupe_check.insert(mReservedUniforms[i]); + } } diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index eb13418cd7..8b13e822d5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -1,25 +1,25 @@ -/** +/** * @file llshadermgr.h * @brief Shader Manager * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,8 +33,8 @@ class LLShaderMgr { public: - LLShaderMgr(); - virtual ~LLShaderMgr(); + LLShaderMgr(); + virtual ~LLShaderMgr(); // clang-format off typedef enum @@ -323,23 +323,23 @@ public: } eGLSLReservedUniforms; // clang-format on - // singleton pattern implementation - static LLShaderMgr * instance(); + // singleton pattern implementation + static LLShaderMgr * instance(); - virtual void initAttribsAndUniforms(void); + virtual void initAttribsAndUniforms(void); - BOOL attachShaderFeatures(LLGLSLShader * shader); - void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = ""); + BOOL attachShaderFeatures(LLGLSLShader * shader); + void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = ""); void dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text); - BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE); - BOOL validateProgramObject(GLuint obj); - GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map* defines = NULL, S32 texture_index_channels = -1); + BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE); + BOOL validateProgramObject(GLuint obj); + GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map* defines = NULL, S32 texture_index_channels = -1); - // Implemented in the application to actually point to the shader directory. - virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual + // Implemented in the application to actually point to the shader directory. + virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual - // Implemented in the application to actually update out of date uniforms for a particular shader - virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual + // Implemented in the application to actually update out of date uniforms for a particular shader + virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version); void clearShaderCache(); @@ -349,14 +349,14 @@ public: bool saveCachedProgramBinary(LLGLSLShader* shader); public: - // Map of shader names to compiled + // Map of shader names to compiled std::map mVertexShaderObjects; std::map mFragmentShaderObjects; - //global (reserved slot) shader parameters - std::vector mReservedAttribs; + //global (reserved slot) shader parameters + std::vector mReservedAttribs; - std::vector mReservedUniforms; + std::vector mReservedUniforms; struct ProgramBinaryData { @@ -372,8 +372,8 @@ public: protected: - // our parameter manager singleton instance - static LLShaderMgr * sInstance; + // our parameter manager singleton instance + static LLShaderMgr * sInstance; }; //LLShaderMgr diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1d81c3778b..7caf20f40b 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvertexbuffer.cpp * @brief LLVertexBuffer implementation * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,25 +41,25 @@ //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2 U32 nhpo2(U32 v) { - U32 r = 1; - while (r < v) { - r *= 2; - } - return r; + U32 r = 1; + while (r < v) { + r *= 2; + } + return r; } //which power of 2 is i? //assumes i is a power of 2 > 0 U32 wpo2(U32 i) { - llassert(i > 0); - llassert(nhpo2(i) == i); + llassert(i > 0); + llassert(nhpo2(i) == i); - U32 r = 0; + U32 r = 0; - while (i >>= 1) ++r; + while (i >>= 1) ++r; - return r; + return r; } struct CompareMappedRegion @@ -381,7 +381,7 @@ public: Entry& entry = entries.back(); name = entry.mGLName; data = entry.mData; - + entries.pop_back(); if (entries.empty()) { @@ -474,9 +474,9 @@ public: } #if 0 - LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", - mDistributed / 1000000, - mAllocated / 1000000, + LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", + mDistributed / 1000000, + mAllocated / 1000000, (mAllocated + mReserved) / 1000000, // total bytes ((mAllocated+mReserved-mDistributed)*100)/llmax(mDistributed, (U64) 1), // overhead percent (mHits*100)/llmax(mMisses+mHits, (U32)1)) // hit rate percent @@ -522,7 +522,7 @@ U64 LLVertexBuffer::getBytesAllocated() } //============================================================================ -// +// //static U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -533,50 +533,50 @@ U32 LLVertexBuffer::sVertexCount = 0; //NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware const U32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { - sizeof(LLVector4), // TYPE_VERTEX, - sizeof(LLVector4), // TYPE_NORMAL, - sizeof(LLVector2), // TYPE_TEXCOORD0, - sizeof(LLVector2), // TYPE_TEXCOORD1, - sizeof(LLVector2), // TYPE_TEXCOORD2, - sizeof(LLVector2), // TYPE_TEXCOORD3, - sizeof(LLColor4U), // TYPE_COLOR, - sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently - sizeof(LLVector4), // TYPE_TANGENT, - sizeof(F32), // TYPE_WEIGHT, - sizeof(LLVector4), // TYPE_WEIGHT4, - sizeof(LLVector4), // TYPE_CLOTHWEIGHT, - sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes + sizeof(LLVector4), // TYPE_VERTEX, + sizeof(LLVector4), // TYPE_NORMAL, + sizeof(LLVector2), // TYPE_TEXCOORD0, + sizeof(LLVector2), // TYPE_TEXCOORD1, + sizeof(LLVector2), // TYPE_TEXCOORD2, + sizeof(LLVector2), // TYPE_TEXCOORD3, + sizeof(LLColor4U), // TYPE_COLOR, + sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently + sizeof(LLVector4), // TYPE_TANGENT, + sizeof(F32), // TYPE_WEIGHT, + sizeof(LLVector4), // TYPE_WEIGHT4, + sizeof(LLVector4), // TYPE_CLOTHWEIGHT, + sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes }; static const std::string vb_type_name[] = { - "TYPE_VERTEX", - "TYPE_NORMAL", - "TYPE_TEXCOORD0", - "TYPE_TEXCOORD1", - "TYPE_TEXCOORD2", - "TYPE_TEXCOORD3", - "TYPE_COLOR", - "TYPE_EMISSIVE", - "TYPE_TANGENT", - "TYPE_WEIGHT", - "TYPE_WEIGHT4", - "TYPE_CLOTHWEIGHT", - "TYPE_TEXTURE_INDEX", - "TYPE_MAX", - "TYPE_INDEX", + "TYPE_VERTEX", + "TYPE_NORMAL", + "TYPE_TEXCOORD0", + "TYPE_TEXCOORD1", + "TYPE_TEXCOORD2", + "TYPE_TEXCOORD3", + "TYPE_COLOR", + "TYPE_EMISSIVE", + "TYPE_TANGENT", + "TYPE_WEIGHT", + "TYPE_WEIGHT4", + "TYPE_CLOTHWEIGHT", + "TYPE_TEXTURE_INDEX", + "TYPE_MAX", + "TYPE_INDEX", }; const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = { - GL_TRIANGLES, - GL_TRIANGLE_STRIP, - GL_TRIANGLE_FAN, - GL_POINTS, - GL_LINES, - GL_LINE_STRIP, - GL_QUADS, - GL_LINE_LOOP, + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_POINTS, + GL_LINES, + GL_LINE_STRIP, + GL_QUADS, + GL_LINE_LOOP, }; //static @@ -598,7 +598,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } } else - { //was disabled + { //was disabled if (data_mask & mask) { //needs to be enabled glEnableVertexAttribArray(loc); @@ -627,18 +627,18 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos) void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); + + gGL.syncMatrices(); - gGL.syncMatrices(); + U32 mask = LLVertexBuffer::MAP_VERTEX; + if (tc) + { + mask = mask | LLVertexBuffer::MAP_TEXCOORD0; + } - U32 mask = LLVertexBuffer::MAP_VERTEX; - if (tc) - { - mask = mask | LLVertexBuffer::MAP_TEXCOORD0; - } + unbind(); - unbind(); - gGL.begin(mode); if (tc != nullptr) @@ -672,32 +672,32 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of llassert(start < (U32)mNumVerts); llassert(end < (U32)mNumVerts); - if (start >= (U32) mNumVerts || - end >= (U32) mNumVerts) - { - LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL; - } + if (start >= (U32) mNumVerts || + end >= (U32) mNumVerts) + { + LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL; + } - llassert(mNumIndices >= 0); + llassert(mNumIndices >= 0); - if (indices_offset >= (U32) mNumIndices || - indices_offset + count > (U32) mNumIndices) - { - LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL; - } + if (indices_offset >= (U32) mNumIndices || + indices_offset + count > (U32) mNumIndices) + { + LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL; + } - { - U16* idx = (U16*) mMappedIndexData+indices_offset; - for (U32 i = 0; i < count; ++i) - { + { + U16* idx = (U16*) mMappedIndexData+indices_offset; + for (U32 i = 0; i < count; ++i) + { llassert(idx[i] >= start); llassert(idx[i] <= end); - if (idx[i] < start || idx[i] > end) - { - LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL; - } - } + if (idx[i] < start || idx[i] > end) + { + LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL; + } + } LLVector4a* v = (LLVector4a*)mMappedData; @@ -709,29 +709,29 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of } } - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader && shader->mFeatures.mIndexedTextureChannels > 1) + { + LLVector4a* v = (LLVector4a*) mMappedData; - if (shader && shader->mFeatures.mIndexedTextureChannels > 1) - { - LLVector4a* v = (LLVector4a*) mMappedData; - - for (U32 i = start; i < end; i++) - { + for (U32 i = start; i < end; i++) + { U32 idx = (U32) (v[i][3]+0.25f); - if (idx >= shader->mFeatures.mIndexedTextureChannels) - { - LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL; - } - } - } - } + if (idx >= shader->mFeatures.mIndexedTextureChannels) + { + LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL; + } + } + } + } return true; } #ifdef LL_PROFILER_ENABLE_RENDER_DOC void LLVertexBuffer::setLabel(const char* label) { - LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label); + LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label); } #endif @@ -756,7 +756,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const llassert(first + count <= mNumVerts); llassert(mGLBuffer == sGLRenderBuffer); llassert(mGLIndices == sGLRenderIndices); - + gGL.syncMatrices(); glDrawArrays(sGLMode[mode], first, count); } @@ -778,21 +778,21 @@ void LLVertexBuffer::initClass(LLWindow* window) #endif } -//static +//static void LLVertexBuffer::unbind() { glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - sGLRenderBuffer = 0; - sGLRenderIndices = 0; + sGLRenderBuffer = 0; + sGLRenderIndices = 0; } //static void LLVertexBuffer::cleanupClass() { - unbind(); - + unbind(); + delete sVBOPool; sVBOPool = nullptr; @@ -812,71 +812,71 @@ void LLVertexBuffer::cleanupClass() //---------------------------------------------------------------------------- -LLVertexBuffer::LLVertexBuffer(U32 typemask) -: LLRefCount(), - mTypeMask(typemask) +LLVertexBuffer::LLVertexBuffer(U32 typemask) +: LLRefCount(), + mTypeMask(typemask) { - //zero out offsets - for (U32 i = 0; i < TYPE_MAX; i++) - { - mOffsets[i] = 0; - } + //zero out offsets + for (U32 i = 0; i < TYPE_MAX; i++) + { + mOffsets[i] = 0; + } } //static U32 LLVertexBuffer::calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices) { U32 offset = 0; - for (U32 i=0; i= 0); + llassert(nverts >= 0); - bool success = true; + bool success = true; - if (nverts > 65536) - { - LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; - nverts = 65536; - } + if (nverts > 65536) + { + LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; + nverts = 65536; + } - U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); + U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); if (needed_size != mSize) { @@ -1012,42 +1012,42 @@ bool LLVertexBuffer::updateNumVerts(U32 nverts) } llassert(mSize == needed_size); - mNumVerts = nverts; - return success; + mNumVerts = nverts; + return success; } bool LLVertexBuffer::updateNumIndices(U32 nindices) { - llassert(nindices >= 0); + llassert(nindices >= 0); - bool success = true; + bool success = true; - U32 needed_size = sizeof(U16) * nindices; + U32 needed_size = sizeof(U16) * nindices; - if (needed_size != mIndicesSize) - { - success &= createGLIndices(needed_size); - } + if (needed_size != mIndicesSize) + { + success &= createGLIndices(needed_size); + } llassert(mIndicesSize == needed_size); - mNumIndices = nindices; - return success; + mNumIndices = nindices; + return success; } bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices) { - if (nverts < 0 || nindices < 0 || - nverts > 65536) - { - LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL; - } + if (nverts < 0 || nindices < 0 || + nverts > 65536) + { + LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL; + } + + bool success = true; - bool success = true; + success &= updateNumVerts(nverts); + success &= updateNumIndices(nindices); - success &= updateNumVerts(nverts); - success &= updateNumIndices(nindices); - - return success; + return success; } //---------------------------------------------------------------------------- @@ -1056,17 +1056,17 @@ bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices) // otherwise return false bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end) { - - if (end < region.mStart || - start > region.mEnd) - { //gap exists, do not merge - return false; - } + + if (end < region.mStart || + start > region.mEnd) + { //gap exists, do not merge + return false; + } region.mStart = llmin(region.mStart, start); region.mEnd = llmax(region.mEnd, end); - return true; + return true; } @@ -1074,7 +1074,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end) U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 index, S32 count) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - + if (count == -1) { count = mNumVerts - index; @@ -1083,24 +1083,24 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde U32 start = mOffsets[type] + sTypeSize[type] * index; U32 end = start + sTypeSize[type] * count-1; - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - MappedRegion& region = mMappedVertexRegions[i]; + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + MappedRegion& region = mMappedVertexRegions[i]; if (expand_region(region, start, end)) { flagged = true; break; } - } + } - if (!flagged) - { - //didn't expand an existing region, make a new one + if (!flagged) + { + //didn't expand an existing region, make a new one mMappedVertexRegions.push_back({ start, end }); - } - + } + return mMappedData+mOffsets[type]+sTypeSize[type]*index; } @@ -1108,11 +1108,11 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - - if (count == -1) - { - count = mNumIndices-index; - } + + if (count == -1) + { + count = mNumIndices-index; + } U32 start = sizeof(U16) * index; U32 end = start + sizeof(U16) * count-1; @@ -1175,23 +1175,23 @@ void LLVertexBuffer::unmapBuffer() } }; - if (!mMappedVertexRegions.empty()) - { + if (!mMappedVertexRegions.empty()) + { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex"); if (sGLRenderBuffer != mGLBuffer) { glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; } - + U32 start = 0; U32 end = 0; std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion()); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + const MappedRegion& region = mMappedVertexRegions[i]; if (region.mStart == end + 1) { end = region.mEnd; @@ -1202,15 +1202,15 @@ void LLVertexBuffer::unmapBuffer() start = region.mStart; end = region.mEnd; } - } + } flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start); - mMappedVertexRegions.clear(); - } - - if (!mMappedIndexRegions.empty()) - { + mMappedVertexRegions.clear(); + } + + if (!mMappedIndexRegions.empty()) + { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); if (mGLIndices != sGLRenderIndices) @@ -1240,86 +1240,86 @@ void LLVertexBuffer::unmapBuffer() flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start); - mMappedIndexRegions.clear(); - } + mMappedIndexRegions.clear(); + } } //---------------------------------------------------------------------------- template struct VertexBufferStrider { - typedef LLStrider strider_t; - static bool get(LLVertexBuffer& vbo, - strider_t& strider, - S32 index, S32 count) - { - if (type == LLVertexBuffer::TYPE_INDEX) - { - U8* ptr = vbo.mapIndexBuffer(index, count); - - if (ptr == NULL) - { - LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL; - return false; - } - - strider = (T*)ptr; - strider.setStride(0); - return true; - } - else if (vbo.hasDataType(type)) - { + typedef LLStrider strider_t; + static bool get(LLVertexBuffer& vbo, + strider_t& strider, + S32 index, S32 count) + { + if (type == LLVertexBuffer::TYPE_INDEX) + { + U8* ptr = vbo.mapIndexBuffer(index, count); + + if (ptr == NULL) + { + LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL; + return false; + } + + strider = (T*)ptr; + strider.setStride(0); + return true; + } + else if (vbo.hasDataType(type)) + { U32 stride = LLVertexBuffer::sTypeSize[type]; - U8* ptr = vbo.mapVertexBuffer(type, index, count); - - if (ptr == NULL) - { - LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL; - return false; - } - - strider = (T*)ptr; - strider.setStride(stride); - return true; - } - else - { - LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL; - } - return false; - } + U8* ptr = vbo.mapVertexBuffer(type, index, count); + + if (ptr == NULL) + { + LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL; + return false; + } + + strider = (T*)ptr; + strider.setStride(stride); + return true; + } + else + { + LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL; + } + return false; + } }; bool LLVertexBuffer::getVertexStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getVertexStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getIndexStrider(LLStrider& strider, U32 index, S32 count) { llassert(mIndicesStride == 2); // cannot access 32-bit indices with U16 strider llassert(mIndicesType == GL_UNSIGNED_SHORT); - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getTexCoord0Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getTexCoord1Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getTexCoord2Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, S32 count) { @@ -1327,33 +1327,33 @@ bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, } bool LLVertexBuffer::getTangentStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getTangentStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getColorStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getWeightStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getWeight4Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count); + return VertexBufferStrider::get(*this, strider, index, count); } //---------------------------------------------------------------------------- @@ -1373,7 +1373,7 @@ void LLVertexBuffer::setBuffer() // this Vertex Buffer must provide all necessary attributes for currently bound shader llassert_msg((data_mask & mTypeMask) == data_mask, - "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x" + "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x" << std::hex << data_mask << " mTypeMask: 0x" << mTypeMask << " Missing: 0x" << (data_mask & ~mTypeMask) << std::dec); if (sGLRenderBuffer != mGLBuffer) @@ -1388,7 +1388,7 @@ void LLVertexBuffer::setBuffer() setupVertexBuffer(); sLastMask = data_mask; } - + if (mGLIndices != sGLRenderIndices) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 669d89aabf..b634609929 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -1,25 +1,25 @@ -/** +/** * @file llvertexbuffer.h * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,51 +51,51 @@ //============================================================================ -// base class +// base class class LLPrivateMemoryPool; class LLVertexBuffer final : public LLRefCount { public: - struct MappedRegion - { + struct MappedRegion + { U32 mStart; U32 mEnd; - }; + }; - LLVertexBuffer(const LLVertexBuffer& rhs) - { - *this = rhs; - } + LLVertexBuffer(const LLVertexBuffer& rhs) + { + *this = rhs; + } - const LLVertexBuffer& operator=(const LLVertexBuffer& rhs) - { - LL_ERRS() << "Illegal operation!" << LL_ENDL; - return *this; - } + const LLVertexBuffer& operator=(const LLVertexBuffer& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } - static void initClass(LLWindow* window); - static void cleanupClass(); - static void setupClientArrays(U32 data_mask); - static void drawArrays(U32 mode, const std::vector& pos); - static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp); + static void initClass(LLWindow* window); + static void cleanupClass(); + static void setupClientArrays(U32 data_mask); + static void drawArrays(U32 mode, const std::vector& pos); + static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp); - static void unbind(); //unbind any bound vertex buffer + static void unbind(); //unbind any bound vertex buffer - //get the size of a vertex with the given typemask - static U32 calcVertexSize(const U32& typemask); + //get the size of a vertex with the given typemask + static U32 calcVertexSize(const U32& typemask); - //get the size of a buffer with the given typemask and vertex count - //fill offsets with the offset of each vertex component array into the buffer - // indexed by the following enum - static U32 calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices); + //get the size of a buffer with the given typemask and vertex count + //fill offsets with the offset of each vertex component array into the buffer + // indexed by the following enum + static U32 calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices); - //WARNING -- when updating these enums you MUST - // 1 - update LLVertexBuffer::sTypeSize + //WARNING -- when updating these enums you MUST + // 1 - update LLVertexBuffer::sTypeSize // 2 - update LLVertexBuffer::vb_type_name - // 3 - add a strider accessor - // 4 - modify LLVertexBuffer::setupVertexBuffer - // 6 - modify LLViewerShaderMgr::mReservedAttribs - + // 3 - add a strider accessor + // 4 - modify LLVertexBuffer::setupVertexBuffer + // 6 - modify LLViewerShaderMgr::mReservedAttribs + // clang-format off enum AttributeType { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms() TYPE_VERTEX = 0, // "position" @@ -112,83 +112,83 @@ public: TYPE_CLOTHWEIGHT, // "clothing" TYPE_TEXTURE_INDEX, // "texture_index" TYPE_MAX, // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer - TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer + TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer }; // clang-format on enum { - MAP_VERTEX = (1<getVertexBuffer(verts); - // vb->getNormalStrider(norms); - // setVertsNorms(verts, norms); - // vb->unmapBuffer(); - bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getIndexStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getTexCoord0Strider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getTexCoord1Strider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getTexCoord2Strider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getNormalStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getNormalStrider(LLStrider& strider, U32 index = 0, S32 count = -1); - bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getColorStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getEmissiveStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getWeight4Strider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getClothWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); - + void setBuffer(); + + // Only call each getVertexPointer, etc, once before calling unmapBuffer() + // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() + // example: + // vb->getVertexBuffer(verts); + // vb->getNormalStrider(norms); + // setVertsNorms(verts, norms); + // vb->unmapBuffer(); + bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getIndexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord0Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord1Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord2Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getNormalStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getNormalStrider(LLStrider& strider, U32 index = 0, S32 count = -1); + bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getColorStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getEmissiveStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getWeight4Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getClothWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); + void setPositionData(const LLVector4a* data); void setNormalData(const LLVector4a* data); void setTangentData(const LLVector4a* data); @@ -198,75 +198,75 @@ public: void setIndexData(const U16* data); void setIndexData(const U32* data); - U32 getNumVerts() const { return mNumVerts; } - U32 getNumIndices() const { return mNumIndices; } - - U32 getTypeMask() const { return mTypeMask; } - bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); } + U32 getNumVerts() const { return mNumVerts; } + U32 getNumIndices() const { return mNumIndices; } + + U32 getTypeMask() const { return mTypeMask; } + bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); } U32 getSize() const { return mSize; } - U32 getIndicesSize() const { return mIndicesSize; } - U8* getMappedData() const { return mMappedData; } - U8* getMappedIndices() const { return mMappedIndexData; } - U32 getOffset(AttributeType type) const { return mOffsets[type]; } - + U32 getIndicesSize() const { return mIndicesSize; } + U8* getMappedData() const { return mMappedData; } + U8* getMappedIndices() const { return mMappedIndexData; } + U32 getOffset(AttributeType type) const { return mOffsets[type]; } + // these functions assume (and assert on) the current VBO being bound // Detailed error checking can be enabled by setting gDebugGL to true - void draw(U32 mode, U32 count, U32 indices_offset) const; - void drawArrays(U32 mode, U32 offset, U32 count) const; + void draw(U32 mode, U32 count, U32 indices_offset) const; + void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; - //for debugging, validate data in given range is valid - bool validateRange(U32 start, U32 end, U32 count, U32 offset) const; + //for debugging, validate data in given range is valid + bool validateRange(U32 start, U32 end, U32 count, U32 offset) const; + + #ifdef LL_PROFILER_ENABLE_RENDER_DOC + void setLabel(const char* label); + #endif - #ifdef LL_PROFILER_ENABLE_RENDER_DOC - void setLabel(const char* label); - #endif - -protected: - U32 mGLBuffer = 0; // GL VBO handle - U32 mGLIndices = 0; // GL IBO handle - U32 mNumVerts = 0; // Number of vertices allocated - U32 mNumIndices = 0; // Number of indices allocated +protected: + U32 mGLBuffer = 0; // GL VBO handle + U32 mGLIndices = 0; // GL IBO handle + U32 mNumVerts = 0; // Number of vertices allocated + U32 mNumIndices = 0; // Number of indices allocated U32 mIndicesType = GL_UNSIGNED_SHORT; // type of indices in index buffer U32 mIndicesStride = 2; // size of each index in bytes - U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute + U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute + + U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped) + U8* mMappedIndexData = nullptr; // pointer to currently mapped indices (NULL if unmapped) - U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped) - U8* mMappedIndexData = nullptr; // pointer to currently mapped indices (NULL if unmapped) + U32 mTypeMask = 0; // bitmask of present vertex attributes - U32 mTypeMask = 0; // bitmask of present vertex attributes - - U32 mSize = 0; // size in bytes of mMappedData - U32 mIndicesSize = 0; // size in bytes of mMappedIndexData + U32 mSize = 0; // size in bytes of mMappedData + U32 mIndicesSize = 0; // size in bytes of mMappedIndexData - std::vector mMappedVertexRegions; // list of mMappedData byte ranges that must be sent to GL - std::vector mMappedIndexRegions; // list of mMappedIndexData byte ranges that must be sent to GL + std::vector mMappedVertexRegions; // list of mMappedData byte ranges that must be sent to GL + std::vector mMappedIndexRegions; // list of mMappedIndexData byte ranges that must be sent to GL private: // DEPRECATED - // These function signatures are deprecated, but for some reason + // These function signatures are deprecated, but for some reason // there are classes in an external package that depend on LLVertexBuffer - + // TODO: move these classes into viewer repository friend class LLNavShapeVBOManager; friend class LLNavMeshVBOManager; - + LLVertexBuffer(U32 typemask, U32 usage) : LLVertexBuffer(typemask) {} - bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); } + bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); } public: static U64 getBytesAllocated(); - static const U32 sTypeSize[TYPE_MAX]; - static const U32 sGLMode[LLRender::NUM_MODES]; - static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static U32 sLastMask; - static U32 sVertexCount; + static const U32 sTypeSize[TYPE_MAX]; + static const U32 sGLMode[LLRender::NUM_MODES]; + static U32 sGLRenderBuffer; + static U32 sGLRenderIndices; + static U32 sLastMask; + static U32 sVertexCount; }; #ifdef LL_PROFILER_ENABLE_RENDER_DOC diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl index 43863dd37a..d3ca3ec8c1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file avatarEyesV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,12 +40,12 @@ out vec3 vary_position; void main() { - //transform vertex - vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - vary_normal = normalize(normal_matrix * normal); + //transform vertex + vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + + vary_normal = normalize(normal_matrix * normal); - vertex_color = diffuse_color; + vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index db7597dd74..b904df3a1b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file avatarF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,21 +37,21 @@ in vec3 vary_position; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec4 diff = texture(diffuseMap, vary_texcoord0.xy); - - if (diff.a < minimum_alpha) - { - discard; - } - - frag_data[0] = vec4(diff.rgb, 0.0); - frag_data[1] = vec4(0,0,0,0); - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + vec4 diff = texture(diffuseMap, vary_texcoord0.xy); + + if (diff.a < minimum_alpha) + { + discard; + } + + frag_data[0] = vec4(diff.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 5cc2846156..aabbbac12a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -1,28 +1,28 @@ -/** +/** * @file avatarV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + uniform mat4 projection_matrix; in vec3 position; @@ -39,27 +39,27 @@ out vec3 vary_position; void main() { - vary_texcoord0 = texcoord0; - - vec4 pos; - vec3 norm; - - vec4 pos_in = vec4(position.xyz, 1.0); - mat4 trans = getSkinnedTransform(); - pos.x = dot(trans[0], pos_in); - pos.y = dot(trans[1], pos_in); - pos.z = dot(trans[2], pos_in); - pos.w = 1.0; - - norm.x = dot(trans[0].xyz, normal); - norm.y = dot(trans[1].xyz, normal); - norm.z = dot(trans[2].xyz, normal); - norm = normalize(norm); - - vary_normal = norm; - + vary_texcoord0 = texcoord0; + + vec4 pos; + vec3 norm; + + vec4 pos_in = vec4(position.xyz, 1.0); + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], pos_in); + pos.y = dot(trans[1], pos_in); + pos.z = dot(trans[2], pos_in); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, normal); + norm.y = dot(trans[1].xyz, normal); + norm.z = dot(trans[2].xyz, normal); + norm = normalize(norm); + + vary_normal = norm; + vary_position = pos.xyz; - gl_Position = projection_matrix * pos; + gl_Position = projection_matrix * pos; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 8483f257fa..2cc3085cd0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -1,30 +1,30 @@ -/** +/** * @file bumpF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ /*[EXTRA_CODE_HERE]*/ - + out vec4 frag_data[4]; uniform float minimum_alpha; @@ -40,28 +40,28 @@ in vec2 vary_texcoord0; in vec3 vary_position; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec4 col = texture(diffuseMap, vary_texcoord0.xy); - - if(col.a < minimum_alpha) - { - discard; - } - col *= vertex_color; - - vec3 norm = texture(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0; + vec4 col = texture(diffuseMap, vary_texcoord0.xy); + + if(col.a < minimum_alpha) + { + discard; + } + col *= vertex_color; + + vec3 norm = texture(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0; + + vec3 tnorm = vec3(dot(norm,vary_mat0), + dot(norm,vary_mat1), + dot(norm,vary_mat2)); - vec3 tnorm = vec3(dot(norm,vary_mat0), - dot(norm,vary_mat1), - dot(norm,vary_mat2)); - - frag_data[0] = vec4(col.rgb, 0.0); - frag_data[1] = vertex_color.aaaa; // spec - //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested - vec3 nvn = normalize(tnorm); - frag_data[2] = vec4(nvn, GBUFFER_FLAG_HAS_ATMOS); + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vertex_color.aaaa; // spec + //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested + vec3 nvn = normalize(tnorm); + frag_data[2] = vec4(nvn, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(vertex_color.a, 0, 0, 0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 74319349f6..a381392f6c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file bumpV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,29 +48,29 @@ uniform mat4 projection_matrix; void main() { - //transform vertex + //transform vertex #ifdef HAS_SKIN mat4 mat = getObjectSkinnedTransform(); - mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; + mat = modelview_matrix * mat; + vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; vary_position = pos; - gl_Position = projection_matrix*vec4(pos, 1.0); + gl_Position = projection_matrix*vec4(pos, 1.0); - vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); + vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); + vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); #else vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vec3 n = normalize(normal_matrix * normal); - vec3 t = normalize(normal_matrix * tangent.xyz); + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vec3 n = normalize(normal_matrix * normal); + vec3 t = normalize(normal_matrix * tangent.xyz); #endif - vec3 b = cross(n, t) * tangent.w; - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vec3 b = cross(n, t) * tangent.w; + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + + vary_mat0 = vec3(t.x, b.x, n.x); + vary_mat1 = vec3(t.y, b.y, n.y); + vary_mat2 = vec3(t.z, b.z, n.z); - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); - - vertex_color = diffuse_color; + vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index f6696e270c..385920f622 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -1,24 +1,24 @@ -/** +/** * @file class1/deferred/deferredUtil.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -366,14 +366,14 @@ vec3 pbrIbl(vec3 diffuseColor, float perceptualRough) { // retrieve a scale and bias to F0. See [1], Figure 3 - vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough); - vec3 diffuseLight = irradiance; - vec3 specularLight = radiance; - - vec3 diffuse = diffuseLight * diffuseColor; - vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); + vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough); + vec3 diffuseLight = irradiance; + vec3 specularLight = radiance; - return (diffuse + specular) * ao; + vec3 diffuse = diffuseLight * diffuseColor; + vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); + + return (diffuse + specular) * ao; } @@ -382,18 +382,18 @@ vec3 pbrIbl(vec3 diffuseColor, // of the shading terms, outlined in the Readme.MD Appendix. struct PBRInfo { - float NdotL; // cos angle between normal and light direction - float NdotV; // cos angle between normal and view direction - float NdotH; // cos angle between normal and half vector - float LdotH; // cos angle between light direction and half vector - float VdotH; // cos angle between view direction and half vector - float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) - float metalness; // metallic value at the surface - vec3 reflectance0; // full reflectance color (normal incidence angle) - vec3 reflectance90; // reflectance color at grazing angle - float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) - vec3 diffuseColor; // color contribution from diffuse lighting - vec3 specularColor; // color contribution from specular lighting + float NdotL; // cos angle between normal and light direction + float NdotV; // cos angle between normal and view direction + float NdotH; // cos angle between normal and half vector + float LdotH; // cos angle between light direction and half vector + float VdotH; // cos angle between view direction and half vector + float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) + float metalness; // metallic value at the surface + vec3 reflectance0; // full reflectance color (normal incidence angle) + vec3 reflectance90; // reflectance color at grazing angle + float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) + vec3 diffuseColor; // color contribution from diffuse lighting + vec3 specularColor; // color contribution from specular lighting }; // Basic Lambertian diffuse @@ -401,14 +401,14 @@ struct PBRInfo // See also [1], Equation 1 vec3 diffuse(PBRInfo pbrInputs) { - return pbrInputs.diffuseColor / M_PI; + return pbrInputs.diffuseColor / M_PI; } // The following equation models the Fresnel reflectance term of the spec equation (aka F()) // Implementation of fresnel from [4], Equation 15 vec3 specularReflection(PBRInfo pbrInputs) { - return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); + return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); } // This calculates the specular geometric attenuation (aka G()), @@ -417,13 +417,13 @@ vec3 specularReflection(PBRInfo pbrInputs) // alphaRoughness as input as originally proposed in [2]. float geometricOcclusion(PBRInfo pbrInputs) { - float NdotL = pbrInputs.NdotL; - float NdotV = pbrInputs.NdotV; - float r = pbrInputs.alphaRoughness; + float NdotL = pbrInputs.NdotL; + float NdotV = pbrInputs.NdotV; + float r = pbrInputs.alphaRoughness; - float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); - float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); - return attenuationL * attenuationV; + float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); + float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); + return attenuationL * attenuationV; } // The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) @@ -431,13 +431,13 @@ float geometricOcclusion(PBRInfo pbrInputs) // Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. float microfacetDistribution(PBRInfo pbrInputs) { - float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; - float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; - return roughnessSq / (M_PI * f * f); + float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; + float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; + return roughnessSq / (M_PI * f * f); } -vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, - float perceptualRoughness, +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, float metallic, vec3 n, // normal vec3 v, // surface point to camera @@ -445,53 +445,53 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, { // make sure specular highlights from punctual lights don't fall off of polished surfaces perceptualRoughness = max(perceptualRoughness, 8.0/255.0); - - float alphaRoughness = perceptualRoughness * perceptualRoughness; - - // Compute reflectance. - float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); - - // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect. - // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%. - float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); - vec3 specularEnvironmentR0 = specularColor.rgb; - vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; - - vec3 h = normalize(l+v); // Half vector between both l and v - vec3 reflection = -normalize(reflect(v, n)); - reflection.y *= -1.0f; - - float NdotL = clamp(dot(n, l), 0.001, 1.0); - float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); - float NdotH = clamp(dot(n, h), 0.0, 1.0); - float LdotH = clamp(dot(l, h), 0.0, 1.0); - float VdotH = clamp(dot(v, h), 0.0, 1.0); - - PBRInfo pbrInputs = PBRInfo( - NdotL, - NdotV, - NdotH, - LdotH, - VdotH, - perceptualRoughness, - metallic, - specularEnvironmentR0, - specularEnvironmentR90, - alphaRoughness, - diffuseColor, - specularColor - ); - - // Calculate the shading terms for the microfacet specular shading model - vec3 F = specularReflection(pbrInputs); - float G = geometricOcclusion(pbrInputs); - float D = microfacetDistribution(pbrInputs); - - // Calculation of analytical lighting contribution - vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs); - vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV); - // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law) - vec3 color = NdotL * (diffuseContrib + specContrib); + + float alphaRoughness = perceptualRoughness * perceptualRoughness; + + // Compute reflectance. + float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); + + // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect. + // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%. + float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); + vec3 specularEnvironmentR0 = specularColor.rgb; + vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; + + vec3 h = normalize(l+v); // Half vector between both l and v + vec3 reflection = -normalize(reflect(v, n)); + reflection.y *= -1.0f; + + float NdotL = clamp(dot(n, l), 0.001, 1.0); + float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); + float NdotH = clamp(dot(n, h), 0.0, 1.0); + float LdotH = clamp(dot(l, h), 0.0, 1.0); + float VdotH = clamp(dot(v, h), 0.0, 1.0); + + PBRInfo pbrInputs = PBRInfo( + NdotL, + NdotV, + NdotH, + LdotH, + VdotH, + perceptualRoughness, + metallic, + specularEnvironmentR0, + specularEnvironmentR90, + alphaRoughness, + diffuseColor, + specularColor + ); + + // Calculate the shading terms for the microfacet specular shading model + vec3 F = specularReflection(pbrInputs); + float G = geometricOcclusion(pbrInputs); + float D = microfacetDistribution(pbrInputs); + + // Calculation of analytical lighting contribution + vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs); + vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV); + // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law) + vec3 color = NdotL * (diffuseContrib + specContrib); return clamp(color, vec3(0), vec3(10)); } @@ -509,9 +509,9 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 color = vec3(0); float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0); - + color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness); - + color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 3.0 * scol; //magic number to balance with legacy materials color += colorEmissive; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index 82d5d363d2..1751e17814 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file diffuseAlphaMaskF.glsl * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,21 +39,21 @@ in vec2 vary_texcoord0; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color; - - if (col.a < minimum_alpha) - { - discard; - } - - frag_data[0] = vec4(col.rgb, 0.0); - frag_data[1] = vec4(0,0,0,0); // spec - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color; + + if (col.a < minimum_alpha) + { + discard; + } + + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); // spec + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 788ea633fc..f5b517a8ea 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file diffuseAlphaMaskIndexedF.glsl * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,20 +37,20 @@ in vec2 vary_texcoord0; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; - - if (col.a < minimum_alpha) - { - discard; - } - - frag_data[0] = vec4(col.rgb, 0.0); - frag_data[1] = vec4(0,0,0,0); - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; + + if (col.a < minimum_alpha) + { + discard; + } + + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index 22e6d60419..89ea0c1710 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -1,28 +1,28 @@ -/** +/** * @file diffuseAlphaMaskNoColorF.glsl * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2005, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + /*[EXTRA_CODE_HERE]*/ out vec4 frag_data[4]; @@ -34,19 +34,19 @@ uniform sampler2D diffuseMap; in vec3 vary_normal; in vec2 vary_texcoord0; -void main() +void main() { - vec4 col = texture(diffuseMap, vary_texcoord0.xy); - - if (col.a < minimum_alpha) - { - discard; - } - - frag_data[0] = vec4(col.rgb, 0.0); - frag_data[1] = vec4(0,0,0,0); // spec - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + vec4 col = texture(diffuseMap, vary_texcoord0.xy); + + if (col.a < minimum_alpha) + { + discard; + } + + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); // spec + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 799fc62a42..7f056a51e8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -1,30 +1,30 @@ -/** +/** * @file diffuseF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ /*[EXTRA_CODE_HERE]*/ - + out vec4 frag_data[4]; uniform sampler2D diffuseMap; @@ -36,15 +36,15 @@ in vec3 vary_position; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb; - frag_data[0] = vec4(col, 0.0); - frag_data[1] = vertex_color.aaaa; // spec - //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb; + frag_data[0] = vec4(col, 0.0); + frag_data[1] = vertex_color.aaaa; // spec + //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(vertex_color.a, 0, 0, 0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 3362a180c6..5c73878ba9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file diffuseIndexedF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,17 +35,17 @@ in vec3 vary_position; void mirrorClip(vec3 pos); vec3 linear_to_srgb(vec3 c); -void main() +void main() { mirrorClip(vary_position); - vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; + vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; - vec3 spec; - spec.rgb = vec3(vertex_color.a); + vec3 spec; + spec.rgb = vec3(vertex_color.a); - frag_data[0] = vec4(col, 0.0); - frag_data[1] = vec4(spec, vertex_color.a); // spec - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + frag_data[0] = vec4(col, 0.0); + frag_data[1] = vec4(spec, vertex_color.a); // spec + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(vertex_color.a, 0, 0, 0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 64230dc680..4bd31cef9e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file diffuseV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -59,13 +59,13 @@ void main() vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); #else vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_normal = normalize(normal_matrix * normal); #endif - - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - passTextureIndex(); - vertex_color = diffuse_color; + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + + passTextureIndex(); + + vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index c64f65e32c..99cb23839a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file impostorF.glsl * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,20 +38,20 @@ in vec2 vary_texcoord0; vec3 linear_to_srgb(vec3 c); -void main() +void main() { - vec4 col = texture(diffuseMap, vary_texcoord0.xy); + vec4 col = texture(diffuseMap, vary_texcoord0.xy); - if (col.a < minimum_alpha) - { - discard; - } + if (col.a < minimum_alpha) + { + discard; + } - vec4 norm = texture(normalMap, vary_texcoord0.xy); - vec4 spec = texture(specularMap, vary_texcoord0.xy); + vec4 norm = texture(normalMap, vary_texcoord0.xy); + vec4 spec = texture(specularMap, vary_texcoord0.xy); - frag_data[0] = vec4(col.rgb, 0.0); - frag_data[1] = spec; - frag_data[2] = vec4(norm.xyz, GBUFFER_FLAG_HAS_ATMOS); + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = spec; + frag_data[2] = vec4(norm.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index ddf878ae60..b6528dfcf8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file materialV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -65,67 +65,67 @@ out vec3 vary_normal; in vec2 texcoord2; out vec2 vary_texcoord2; #endif - + out vec4 vertex_color; out vec2 vary_texcoord0; void main() { #ifdef HAS_SKIN - mat4 mat = getObjectSkinnedTransform(); + mat4 mat = getObjectSkinnedTransform(); - mat = modelview_matrix * mat; + mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; + vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; - vary_position = pos; + vary_position = pos; - gl_Position = projection_matrix*vec4(pos,1.0); + gl_Position = projection_matrix*vec4(pos,1.0); #else - //transform vertex - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + //transform vertex + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - + + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + #ifdef HAS_NORMAL_MAP - vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; + vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; #endif #ifdef HAS_SPECULAR_MAP - vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; + vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; #endif #ifdef HAS_SKIN - vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); + vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); #ifdef HAS_NORMAL_MAP - vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); + vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); vary_tangent = t; vary_sign = tangent.w; vary_normal = n; #else //HAS_NORMAL_MAP - vary_normal = n; + vary_normal = n; #endif //HAS_NORMAL_MAP #else //HAS_SKIN - vec3 n = normalize(normal_matrix * normal); + vec3 n = normalize(normal_matrix * normal); #ifdef HAS_NORMAL_MAP - vec3 t = normalize(normal_matrix * tangent.xyz); + vec3 t = normalize(normal_matrix * tangent.xyz); vary_tangent = t; vary_sign = tangent.w; vary_normal = n; #else //HAS_NORMAL_MAP - vary_normal = n; + vary_normal = n; #endif //HAS_NORMAL_MAP #endif //HAS_SKIN - - vertex_color = diffuse_color; + + vertex_color = diffuse_color; #if !defined(HAS_SKIN) - vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; #endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 5e0141910b..fd020afd57 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file pbropaqueV.glsl * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,7 +54,7 @@ out vec2 base_color_texcoord; out vec2 normal_texcoord; out vec2 metallic_roughness_texcoord; out vec2 emissive_texcoord; - + out vec4 vertex_color; out vec3 vary_tangent; @@ -68,18 +68,18 @@ vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] kh void main() { #ifdef HAS_SKIN - mat4 mat = getObjectSkinnedTransform(); + mat4 mat = getObjectSkinnedTransform(); - mat = modelview_matrix * mat; + mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; + vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; vary_position = pos; - gl_Position = projection_matrix*vec4(pos,1.0); + gl_Position = projection_matrix*vec4(pos,1.0); #else vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; - //transform vertex - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + //transform vertex + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); @@ -88,11 +88,11 @@ void main() emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); #ifdef HAS_SKIN - vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; - vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; #else //HAS_SKIN - vec3 n = normal_matrix * normal; - vec3 t = normal_matrix * tangent.xyz; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; #endif n = normalize(n); @@ -100,11 +100,11 @@ void main() vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_normal_transform, texture_matrix0)); vary_sign = tangent.w; vary_normal = n; - - vertex_color = diffuse_color; + + vertex_color = diffuse_color; } -#else +#else // fullbright HUD implementation @@ -121,7 +121,7 @@ in vec2 texcoord0; out vec2 base_color_texcoord; out vec2 emissive_texcoord; - + out vec4 vertex_color; vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); @@ -129,7 +129,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl void main() { //transform vertex - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 489fc26e3f..4efb9a1f53 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file class1\environment\pbrterrainV.glsl * * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -56,12 +56,12 @@ vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] kh void main() { //transform vertex - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; - vec3 n = normal_matrix * normal; + vec3 n = normal_matrix * normal; vary_vertex_normal = normal; - vec3 t = normal_matrix * tangent.xyz; + vec3 t = normal_matrix * tangent.xyz; vary_tangent = normalize(t); // *TODO: Decide if we want this. It may be better to just calculate the @@ -88,7 +88,7 @@ void main() #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 vary_texcoord0.xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0); #endif - + vec4 tc = vec4(texcoord1,0,1); vary_texcoord0.zw = tc.xy; vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 1629ed91c8..a0eb6cfbb8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -1,28 +1,28 @@ -/** +/** * @file postDeferredGammaCorrect.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + /*[EXTRA_CODE_HERE]*/ out vec4 frag_color; @@ -79,7 +79,7 @@ vec3 RRTAndODTFit(vec3 color) } -// tone mapping +// tone mapping vec3 toneMapACES_Hill(vec3 color) { color = ACESInputMat * color; @@ -103,7 +103,7 @@ vec3 toneMap(vec3 color) { #ifndef NO_POST float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - + color *= exposure * exp_scale; // mix ACES and Linear here as a compromise to avoid over-darkening legacy content @@ -117,38 +117,38 @@ vec3 toneMap(vec3 color) //================================= // borrowed noise from: -// -// By Morgan McGuire @morgan3d, http://graphicscodex.com +// +// By Morgan McGuire @morgan3d, http://graphicscodex.com // float hash(float n) { return fract(sin(n) * 1e4); } float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } float noise(float x) { - float i = floor(x); - float f = fract(x); - float u = f * f * (3.0 - 2.0 * f); - return mix(hash(i), hash(i + 1.0), u); + float i = floor(x); + float f = fract(x); + float u = f * f * (3.0 - 2.0 * f); + return mix(hash(i), hash(i + 1.0), u); } float noise(vec2 x) { - vec2 i = floor(x); - vec2 f = fract(x); - - // Four corners in 2D of a tile - float a = hash(i); - float b = hash(i + vec2(1.0, 0.0)); - float c = hash(i + vec2(0.0, 1.0)); - float d = hash(i + vec2(1.0, 1.0)); - - // Simple 2D lerp using smoothstep envelope between the values. - // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), - // mix(c, d, smoothstep(0.0, 1.0, f.x)), - // smoothstep(0.0, 1.0, f.y))); - - // Same code, with the clamps in smoothstep and common subexpressions - // optimized away. - vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; + vec2 i = floor(x); + vec2 f = fract(x); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Simple 2D lerp using smoothstep envelope between the values. + // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), + // mix(c, d, smoothstep(0.0, 1.0, f.x)), + // smoothstep(0.0, 1.0, f.y))); + + // Same code, with the clamps in smoothstep and common subexpressions + // optimized away. + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } //============================= @@ -171,7 +171,7 @@ vec3 legacyGamma(vec3 color) return c; } -void main() +void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) vec4 diff = texture(diffuseRect, vary_fragcoord); diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 708acd0194..05922ecb1a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file treeF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,18 +37,18 @@ in vec3 vary_position; uniform float minimum_alpha; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - vec4 col = texture(diffuseMap, vary_texcoord0.xy); - if (col.a < minimum_alpha) - { - discard; - } + vec4 col = texture(diffuseMap, vary_texcoord0.xy); + if (col.a < minimum_alpha) + { + discard; + } - frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); - frag_data[1] = vec4(0,0,0,0); - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); + frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); + frag_data[1] = vec4(0,0,0,0); + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); frag_data[3] = vec4(0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index c84fccd4c6..ef5602f1e5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file treeV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,13 +39,13 @@ out vec3 vary_position; void main() { - //transform vertex - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + //transform vertex + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - vary_normal = normalize(normal_matrix * normal); + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + + vary_normal = normalize(normal_matrix * normal); - vertex_color = vec4(1,1,1,1); + vertex_color = vec4(1,1,1,1); } diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl index 388042e7e0..2bfd45f3b0 100644 --- a/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file normaldebugF.glsl * * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -27,7 +27,7 @@ out vec4 frag_color; in vec4 vertex_color; -void main() +void main() { - frag_color = max(vertex_color, vec4(0)); + frag_color = max(vertex_color, vec4(0)); } diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl index b198bc2485..ae726190c7 100644 --- a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file normaldebugV.glsl * * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -65,10 +65,10 @@ void main() vec4 world_pos = mat * vec4(position.xyz,1.0); - gl_Position = projection_matrix * world_pos; - normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat); + gl_Position = projection_matrix * world_pos; + normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat); #ifdef HAS_ATTRIBUTE_TANGENT - tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat); + tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat); #endif } diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index c1ed1bfe6e..feb0947649 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -1,28 +1,28 @@ -/** +/** * @file radianceGenF.glsl * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + /*[EXTRA_CODE_HERE]*/ @@ -36,7 +36,7 @@ in vec3 vary_dir; //uniform float roughness; uniform float mipLevel; -uniform int u_width; +uniform int u_width; uniform float max_probe_lod; uniform float probe_strength; @@ -74,96 +74,96 @@ const float PI = 3.1415926536; // Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ float random(vec2 co) { - float a = 12.9898; - float b = 78.233; - float c = 43758.5453; - float dt= dot(co.xy ,vec2(a,b)); - float sn= mod(dt,3.14); - return fract(sin(sn) * c); + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,vec2(a,b)); + float sn= mod(dt,3.14); + return fract(sin(sn) * c); } -vec2 hammersley2d(uint i, uint N) +vec2 hammersley2d(uint i, uint N) { - // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html - uint bits = (i << 16u) | (i >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - float rdi = float(bits) * 2.3283064365386963e-10; - return vec2(float(i) /float(N), rdi); + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return vec2(float(i) /float(N), rdi); } // Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf -vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) +vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) { - // Maps a 2D point to a hemisphere with spread based on roughness - float alpha = roughness * roughness; - float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; - float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); - float sinTheta = sqrt(1.0 - cosTheta * cosTheta); - vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); - - // Tangent space - vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - vec3 tangentX = normalize(cross(up, normal)); - vec3 tangentY = normalize(cross(normal, tangentX)); - - // Convert to world Space - return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 tangentX = normalize(cross(up, normal)); + vec3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); } // Normal Distribution function float D_GGX(float dotNH, float roughness) { - float alpha = roughness * roughness; - float alpha2 = alpha * alpha; - float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; - return (alpha2)/(PI * denom*denom); + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); } vec4 prefilterEnvMap(vec3 R) { - vec3 N = R; - vec3 V = R; - vec4 color = vec4(0.0); - float totalWeight = 0.0; - float envMapDim = float(textureSize(reflectionProbes, 0).s); + vec3 N = R; + vec3 V = R; + vec4 color = vec4(0.0); + float totalWeight = 0.0; + float envMapDim = float(textureSize(reflectionProbes, 0).s); float roughness = mipLevel/max_probe_lod; int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1); float numMips = max_probe_lod+1; - for(uint i = 0u; i < numSamples; i++) { - vec2 Xi = hammersley2d(i, numSamples); - vec3 H = importanceSample_GGX(Xi, roughness, N); - vec3 L = 2.0 * dot(V, H) * H - V; - float dotNL = clamp(dot(N, L), 0.0, 1.0); - if(dotNL > 0.0) { - // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ - - float dotNH = clamp(dot(N, H), 0.0, 1.0); - float dotVH = clamp(dot(V, H), 0.0, 1.0); - - // Probability Distribution Function - float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; - // Slid angle of current smple - float omegaS = 1.0 / (float(numSamples) * pdf); - // Solid angle of 1 pixel across all cube faces - float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); - // Biased (+1.0) mip level for better result - float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod); - color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL; - totalWeight += dotNL; - } - } - return (color / totalWeight); + for(uint i = 0u; i < numSamples; i++) { + vec2 Xi = hammersley2d(i, numSamples); + vec3 H = importanceSample_GGX(Xi, roughness, N); + vec3 L = 2.0 * dot(V, H) * H - V; + float dotNL = clamp(dot(N, L), 0.0, 1.0); + if(dotNL > 0.0) { + // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ + + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotVH = clamp(dot(V, H), 0.0, 1.0); + + // Probability Distribution Function + float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; + // Slid angle of current smple + float omegaS = 1.0 / (float(numSamples) * pdf); + // Solid angle of 1 pixel across all cube faces + float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); + // Biased (+1.0) mip level for better result + float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod); + color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL; + totalWeight += dotNL; + } + } + return (color / totalWeight); } void main() -{ - vec3 N = normalize(vary_dir); - frag_color = max(prefilterEnvMap(N), vec4(0)); +{ + vec3 N = normalize(vary_dir); + frag_color = max(prefilterEnvMap(N), vec4(0)); frag_color.a *= probe_strength; } // ============================================================================================================= diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl index 142f2a5d71..09a505d69d 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file bumpF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,11 +34,11 @@ in vec3 vary_position; void mirrorClip(vec3 pos); -void main() +void main() { mirrorClip(vary_position); - float tex0 = texture(texture0, vary_texcoord0.xy).a; - float tex1 = texture(texture1, vary_texcoord1.xy).a; + float tex0 = texture(texture0, vary_texcoord0.xy).a; + float tex1 = texture(texture1, vary_texcoord1.xy).a; - frag_color = max(vec4(tex0+(1.0-tex1)-0.5), vec4(0)); + frag_color = max(vec4(tex0+(1.0-tex1)-0.5), vec4(0)); } diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index b8a02fbdec..95cdfb6fae 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -1,24 +1,24 @@ -/** +/** * @file bumpV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,7 +42,7 @@ uniform mat4 projection_matrix; void main() { - //transform vertex + //transform vertex #ifdef HAS_SKIN mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; @@ -51,8 +51,8 @@ void main() gl_Position = projection_matrix * pos; #else vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; - gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); + gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); #endif - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 7a1a54a77a..210ecce8db 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -1,24 +1,24 @@ -/** +/** * @file alphaF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -60,7 +60,7 @@ uniform vec2 screen_res; uniform int sun_up_factor; uniform vec4 light_position[8]; uniform vec3 light_direction[8]; -uniform vec4 light_attenuation[8]; +uniform vec4 light_attenuation[8]; uniform vec3 light_diffuse[8]; void waterClip(vec3 pos); @@ -91,15 +91,15 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec float falloff_factor = (12.0 * fa) - 9.0; float inverted_la = falloff_factor / la; // Yes, it makes me want to cry as well. DJH - + vec3 col = vec3(0); - //get light vector - vec3 lv = lp.xyz-v; + //get light vector + vec3 lv = lp.xyz-v; - //get distance - float dist = length(lv); - float da = 1.0; + //get distance + float dist = length(lv); + float da = 1.0; /*if (dist > inverted_la) { @@ -112,23 +112,23 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec if (proj_tc.z < 0 || proj_tc.z > 1 || proj_tc.x < 0 - || proj_tc.x > 1 + || proj_tc.x > 1 || proj_tc.y < 0 || proj_tc.y > 1) { return col; }*/ - if (dist > 0.0 && inverted_la > 0.0) - { + if (dist > 0.0 && inverted_la > 0.0) + { dist /= inverted_la; - //normalize light vector - lv = normalize(lv); - - //distance attenuation - float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); - dist_atten *= dist_atten; + //normalize light vector + lv = normalize(lv); + + //distance attenuation + float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); + dist_atten *= dist_atten; dist_atten *= 2.0f; if (dist_atten <= 0.0) @@ -136,20 +136,20 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec return col; } - // spotlight coefficient. - float spot = max(dot(-ln, lv), is_pointlight); - da *= spot*spot; // GL_SPOT_EXPONENT=2 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= dot(n, lv); + //angular attenuation + da *= dot(n, lv); da = max(0.0, da); - float lit = 0.0f; + float lit = 0.0f; float amb_da = 0.0;//ambiance; if (da > 0) { - lit = max(da * dist_atten,0.0); + lit = max(da * dist_atten,0.0); col = lit * light_col * diffuse; amb_da += (da*0.5+0.5) * ambiance; } @@ -166,12 +166,12 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec return col; } -void main() +void main() { mirrorClip(vary_position); vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; - + vec4 pos = vec4(vary_position, 1.0); #ifndef IS_AVATAR_SKIN // clip against water plane unless this is a legacy avatar skin @@ -202,7 +202,7 @@ void main() float final_alpha = diffuse_srgb.a * vertex_color.a; diffuse_srgb.rgb *= vertex_color.rgb; - + // Insure we don't pollute depth with invis pixels in impostor rendering // if (final_alpha < minimum_alpha) @@ -225,7 +225,7 @@ void main() final_alpha *= vertex_color.a; if (final_alpha < minimum_alpha) - { // TODO: figure out how to get invisible faces out of + { // TODO: figure out how to get invisible faces out of // render batches without breaking glow discard; } @@ -248,11 +248,11 @@ void main() vec3 glossenv; vec3 legacyenv; sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, frag, pos.xyz, norm.xyz, 0.0, 0.0, true, amblit_linear); - + float da = dot(norm.xyz, light_dir.xyz); da = clamp(da, -1.0, 1.0); - + float final_da = da; final_da = clamp(final_da, 0.0f, 1.0f); @@ -269,7 +269,7 @@ void main() color.rgb *= diffuse_linear.rgb; vec4 light = vec4(0,0,0,0); - + #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w); LIGHT_LOOP(1) diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index c382a9fbc0..03dc3d7113 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -1,28 +1,28 @@ -/** +/** * @file fullbrightShinyF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + /*[EXTRA_CODE_HERE]*/ out vec4 frag_color; @@ -59,16 +59,16 @@ void main() { mirrorClip(vary_position); #ifdef HAS_DIFFUSE_LOOKUP - vec4 color = diffuseLookup(vary_texcoord0.xy); + vec4 color = diffuseLookup(vary_texcoord0.xy); #else - vec4 color = texture(diffuseMap, vary_texcoord0.xy); + vec4 color = texture(diffuseMap, vary_texcoord0.xy); #endif - - color.rgb *= vertex_color.rgb; - // SL-9632 HUDs are affected by Atmosphere + color.rgb *= vertex_color.rgb; + + // SL-9632 HUDs are affected by Atmosphere #ifndef IS_HUD - + vec3 sunlit; vec3 amblit; vec3 additive; @@ -90,8 +90,8 @@ void main() applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity); #endif - color.a = 1.0; + color.a = 1.0; - frag_color = max(color, vec4(0)); + frag_color = max(color, vec4(0)); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 2a20eb79d2..d3e19cf4a8 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -100,7 +100,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float falloff_factor = (12.0 * fa) - 9.0; float inverted_la = falloff_factor / la; // Yes, it makes me want to cry as well. DJH - + vec3 col = vec3(0); //get light vector @@ -220,19 +220,19 @@ in vec2 vary_texcoord0; vec3 getNormal(inout float glossiness) { #ifdef HAS_NORMAL_MAP - vec4 vNt = texture(bumpMap, vary_texcoord1.xy); + vec4 vNt = texture(bumpMap, vary_texcoord1.xy); glossiness *= vNt.a; - vNt.xyz = vNt.xyz * 2 - 1; + vNt.xyz = vNt.xyz * 2 - 1; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - + vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); - return tnorm; + return tnorm; #else - return normalize(vary_normal); + return normalize(vary_normal); #endif } @@ -269,9 +269,9 @@ void waterClip() float getEmissive(vec4 diffcol) { #if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) - return emissive_brightness; + return emissive_brightness; #else - return max(diffcol.a, emissive_brightness); + return max(diffcol.a, emissive_brightness); #endif } @@ -295,7 +295,7 @@ void main() // diffcol == diffuse map combined with vertex color vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy); - diffcol.rgb *= vertex_color.rgb; + diffcol.rgb *= vertex_color.rgb; alphaMask(diffcol.a); // spec == specular map combined with specular color @@ -328,7 +328,7 @@ void main() vec3 additive; vec3 atten; calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); - + vec3 sunlit_linear = srgb_to_linear(sunlit); vec3 amblit_linear = amblit; @@ -336,7 +336,7 @@ void main() vec3 glossenv; vec3 legacyenv; sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env, true, amblit_linear); - + color = ambenv; float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); @@ -408,7 +408,7 @@ void main() frag_color = max(vec4(color, al), vec4(0)); -#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer +#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl float flag = GBUFFER_FLAG_HAS_ATMOS; diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index ef086fc3be..728d70ebb2 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -4,25 +4,25 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + out vec4 frag_color; uniform sampler2D diffuseMap; @@ -57,27 +57,27 @@ in vec3 vary_position; vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color); void mirrorClip(vec3 position); -void main() +void main() { - mirrorClip(vary_position); - vec4 color; + mirrorClip(vary_position); + vec4 color; //get detail normals - vec3 wave1 = texture(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; - vec3 wave2 = texture(bumpMap, littleWave.xy).xyz*2.0-1.0; - vec3 wave3 = texture(bumpMap, littleWave.zw).xyz*2.0-1.0; - vec3 wavef = normalize(wave1+wave2+wave3); - - //figure out distortion vector (ripply) - vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - distort = distort+wavef.xy*refScale; + vec3 wave1 = texture(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture(bumpMap, littleWave.zw).xyz*2.0-1.0; + vec3 wavef = normalize(wave1+wave2+wave3); + + //figure out distortion vector (ripply) + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + distort = distort+wavef.xy*refScale; #ifdef TRANSPARENT_WATER - vec4 fb = texture(screenTex, distort); + vec4 fb = texture(screenTex, distort); #else vec4 fb = vec4(waterFogColorLinear, 0.0); #endif - + fb = applyWaterFogViewLinearNoClip(vary_position, fb); frag_color = max(fb, vec4(0)); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index b2a81aa025..a5592188a9 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -1,28 +1,28 @@ -/** +/** * @file waterF.glsl * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + // class3/environment/waterF.glsl out vec4 frag_color; @@ -129,7 +129,7 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv, vec3 getPositionWithNDC(vec3 ndc); -void main() +void main() { mirrorClip(vary_position); vN = vary_normal; @@ -160,7 +160,7 @@ void main() vec3 wave3 = BlendNormal(wave3_a, wave3_b); vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - + //wave1 = transform_normal(wave1); //wave2 = transform_normal(wave2); //wave3 = transform_normal(wave3); @@ -171,7 +171,7 @@ void main() vec3 up = transform_normal(vec3(0,0,1)); float vdu = -dot(viewVec, up)*2; - + vec3 wave_ibl = wavef; wave_ibl.z *= 2.0; wave_ibl = transform_normal(normalize(wave_ibl)); @@ -185,13 +185,13 @@ void main() //wavef = vec3(0, 0, 1); wavef = transform_normal(wavef); - - float dist2 = dist; - dist = max(dist, 5.0); - - float dmod = sqrt(dist); - - //figure out distortion vector (ripply) + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + //figure out distortion vector (ripply) vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0); distort2 = clamp(distort2, vec2(0), vec2(0.999)); @@ -235,7 +235,7 @@ void main() float metallic = 0.0; float perceptualRoughness = 0.05; float gloss = 1.0 - perceptualRoughness; - + vec3 irradiance = vec3(0); vec3 radiance = vec3(0); sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); @@ -251,7 +251,7 @@ void main() vec3 colorEmissive = vec3(0); float ao = 1.0; vec3 light_dir = transform_normal(lightDir); - + perceptualRoughness = 0.0; metallic = 1.0; @@ -284,7 +284,7 @@ void main() color = ((1.0 - f) * color) + fb.rgb; float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); - + frag_color = max(vec4(color, spec), vec4(0)); } diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h index 6e576a1ffe..5ceac74a8a 100644 --- a/indra/newview/gltf/asset.h +++ b/indra/newview/gltf/asset.h @@ -33,7 +33,7 @@ #include "primitive.h" #include "animation.h" -extern F32SecondsImplicit gFrameTimeSeconds; +extern F32SecondsImplicit gFrameTimeSeconds; // LL GLTF Implementation namespace LL @@ -52,7 +52,7 @@ namespace LL std::string mName; const Material& operator=(const tinygltf::Material& src); - + void allocateGLResources(Asset& asset); }; @@ -64,7 +64,7 @@ namespace LL std::string mName; const Mesh& operator=(const tinygltf::Mesh& src); - + void allocateGLResources(Asset& asset); }; @@ -85,7 +85,7 @@ namespace LL // if true, translation/rotation/scale are valid and up to date bool mTRSValid = false; - + bool mNeedsApplyMatrix = false; std::vector mChildren; @@ -146,7 +146,7 @@ namespace LL std::string mName; const Scene& operator=(const tinygltf::Scene& src); - + void updateTransforms(Asset& asset); void updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview); }; @@ -229,7 +229,7 @@ namespace LL // prepare the asset for rendering void allocateGLResources(const std::string& filename, const tinygltf::Model& model); - + // Called periodically (typically once per frame) // Any ongoing work (such as animations) should be handled here // NOT guaranteed to be called every frame @@ -242,7 +242,7 @@ namespace LL // update node render transforms void updateRenderTransforms(const LLMatrix4a& modelview); - + void render(bool opaque, bool rigged = false); void renderOpaque(); void renderTransparent(); @@ -256,9 +256,9 @@ namespace LL LLVector4a* tangent = nullptr, // return the surface tangent at the intersection point S32* primitive_hitp = nullptr // return the index of the primitive that was hit ); - + const Asset& operator=(const tinygltf::Model& src); - + }; } } diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 4e3439ea5c..7003eab6d0 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -129,7 +129,7 @@ void GLTFSceneManager::update() Asset* asset = mObjects[i]->mGLTFAsset; asset->update(); - + } } @@ -137,9 +137,9 @@ void GLTFSceneManager::render(bool opaque, bool rigged) { // for debugging, just render the whole scene as opaque // by traversing the whole scenegraph - // Assumes camera transform is already set and + // Assumes camera transform is already set and // appropriate shader is already bound - + gGL.matrixMode(LLRender::MM_MODELVIEW); for (U32 i = 0; i < mObjects.size(); ++i) @@ -281,10 +281,10 @@ LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, cons LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent) // return the surface tangent at the intersection point + LLVector4a* tangent) // return the surface tangent at the intersection point { LLDrawable* drawable = nullptr; - + LLVector4a local_end = end; LLVector4a position; @@ -314,8 +314,8 @@ LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, cons void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size); -extern LLVector4a gDebugRaycastStart; -extern LLVector4a gDebugRaycastEnd; +extern LLVector4a gDebugRaycastStart; +extern LLVector4a gDebugRaycastEnd; void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree); @@ -336,7 +336,7 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) agent_to_asset.affineTransform(gDebugRaycastStart, start); agent_to_asset.affineTransform(gDebugRaycastEnd, end); - + for (auto& node : asset->mNodes) { Mesh& mesh = asset->mMeshes[node.mMesh]; @@ -344,7 +344,7 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) if (node.mMesh != INVALID_INDEX) { gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix); - + // draw bounding box of mesh primitives if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { @@ -549,7 +549,7 @@ void GLTFSceneManager::renderDebug() gGL.loadMatrix((F32*) node->mRenderMatrix.mMatrix); - + auto* listener = (LLVolumeOctreeListener*) primitive->mOctree->getListener(0); drawBoxOutline(listener->mBounds[0], listener->mBounds[1]); diff --git a/indra/newview/gltfscenemanager.h b/indra/newview/gltfscenemanager.h index d286f335e4..7966606dfa 100644 --- a/indra/newview/gltfscenemanager.h +++ b/indra/newview/gltfscenemanager.h @@ -36,7 +36,7 @@ namespace LL public: ~GLTFSceneManager(); // load GLTF file from disk - + void load(); // open filepicker to choose asset void load(const std::string& filename); // load asset from filename @@ -55,7 +55,7 @@ namespace LL LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent); // return the surface tangent at the intersection point + LLVector4a* tangent); // return the surface tangent at the intersection point bool lineSegmentIntersect(LLVOVolume* obj, GLTF::Asset* asset, const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32* face_hitp, S32* primitive_hitp, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp index 0717d92ea7..4ac4d2136f 100644 --- a/indra/newview/llagentbenefits.cpp +++ b/indra/newview/llagentbenefits.cpp @@ -28,14 +28,14 @@ #include "llviewertexture.h" LLAgentBenefits::LLAgentBenefits(): - m_initalized(false), - m_animated_object_limit(-1), - m_animation_upload_cost(-1), - m_attachment_limit(-1), - m_group_membership_limit(-1), - m_picks_limit(-1), - m_sound_upload_cost(-1), - m_texture_upload_cost(-1) + m_initalized(false), + m_animated_object_limit(-1), + m_animation_upload_cost(-1), + m_attachment_limit(-1), + m_group_membership_limit(-1), + m_picks_limit(-1), + m_sound_upload_cost(-1), + m_texture_upload_cost(-1) { } @@ -48,53 +48,53 @@ LLAgentBenefits::~LLAgentBenefits() // the viewer cares about are integer. bool get_required_S32(const LLSD& sd, const LLSD::String& key, S32& value) { - value = -1; - if (sd.has(key)) - { - value = sd[key].asInteger(); - return true; - } - - LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL; - return false; + value = -1; + if (sd.has(key)) + { + value = sd[key].asInteger(); + return true; + } + + LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL; + return false; } bool LLAgentBenefits::init(const LLSD& benefits_sd) { - LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL; - - if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit)) - { - return false; - } - if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost)) - { - return false; - } - if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit)) - { - return false; - } - if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost)) - { - return false; - } - if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit)) - { - return false; - } - if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit)) - { - return false; - } - if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost)) - { - return false; - } - if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost)) - { - return false; - } + LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL; + + if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit)) + { + return false; + } + if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost)) + { + return false; + } + if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit)) + { + return false; + } + if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost)) + { + return false; + } + if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit)) + { + return false; + } + if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit)) + { + return false; + } + if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost)) + { + return false; + } + if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost)) + { + return false; + } if (benefits_sd.has("large_texture_upload_cost")) { @@ -116,49 +116,49 @@ bool LLAgentBenefits::init(const LLSD& benefits_sd) m_2k_texture_upload_cost.push_back(m_texture_upload_cost); } - // FIXME PREMIUM - either use this field or get rid of it - m_initalized = true; - return true; + // FIXME PREMIUM - either use this field or get rid of it + m_initalized = true; + return true; } S32 LLAgentBenefits::getAnimatedObjectLimit() const { - return m_animated_object_limit; + return m_animated_object_limit; } S32 LLAgentBenefits::getAnimationUploadCost() const { - return m_animation_upload_cost; + return m_animation_upload_cost; } S32 LLAgentBenefits::getAttachmentLimit() const { - return m_attachment_limit; + return m_attachment_limit; } S32 LLAgentBenefits::getCreateGroupCost() const { - return m_create_group_cost; + return m_create_group_cost; } S32 LLAgentBenefits::getGroupMembershipLimit() const { - return m_group_membership_limit; + return m_group_membership_limit; } S32 LLAgentBenefits::getPicksLimit() const { - return m_picks_limit; + return m_picks_limit; } S32 LLAgentBenefits::getSoundUploadCost() const { - return m_sound_upload_cost; + return m_sound_upload_cost; } S32 LLAgentBenefits::getTextureUploadCost() const { - return m_texture_upload_cost; + return m_texture_upload_cost; } S32 LLAgentBenefits::getTextureUploadCost(const LLViewerTexture* tex) const @@ -206,23 +206,23 @@ S32 LLAgentBenefits::get2KTextureUploadCost(S32 area) const bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const { - bool succ = false; - if (asset_type == LLAssetType::AT_TEXTURE) - { + bool succ = false; + if (asset_type == LLAssetType::AT_TEXTURE) + { cost = getTextureUploadCost(); - succ = true; - } - else if (asset_type == LLAssetType::AT_SOUND) - { - cost = getSoundUploadCost(); - succ = true; - } - else if (asset_type == LLAssetType::AT_ANIMATION) - { - cost = getAnimationUploadCost(); - succ = true; - } - return succ; + succ = true; + } + else if (asset_type == LLAssetType::AT_SOUND) + { + cost = getSoundUploadCost(); + succ = true; + } + else if (asset_type == LLAssetType::AT_ANIMATION) + { + cost = getAnimationUploadCost(); + succ = true; + } + return succ; } LLAgentBenefitsMgr::LLAgentBenefitsMgr() @@ -236,65 +236,65 @@ LLAgentBenefitsMgr::~LLAgentBenefitsMgr() // static const LLAgentBenefits& LLAgentBenefitsMgr::current() { - return instance().mCurrent; + return instance().mCurrent; } // static const LLAgentBenefits& LLAgentBenefitsMgr::get(const std::string& package) { - if (instance().mPackageMap.find(package) != instance().mPackageMap.end()) - { - return instance().mPackageMap[package]; - } - else - { - return instance().mDefault; - } + if (instance().mPackageMap.find(package) != instance().mPackageMap.end()) + { + return instance().mPackageMap[package]; + } + else + { + return instance().mDefault; + } } // static bool LLAgentBenefitsMgr::init(const std::string& package, const LLSD& benefits_sd) { - LLAgentBenefits benefits; - if (!benefits.init(benefits_sd)) - { - LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; - return false; - } - else - { - instance().mPackageMap[package] = benefits; - } - return true; + LLAgentBenefits benefits; + if (!benefits.init(benefits_sd)) + { + LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; + return false; + } + else + { + instance().mPackageMap[package] = benefits; + } + return true; } // static bool LLAgentBenefitsMgr::initCurrent(const std::string& package, const LLSD& benefits_sd) { - LLAgentBenefits benefits; - if (!benefits.init(benefits_sd)) - { - LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; - return false; - } - else - { - instance().mCurrent = benefits; - instance().mCurrentName = package; - } - return true; + LLAgentBenefits benefits; + if (!benefits.init(benefits_sd)) + { + LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL; + return false; + } + else + { + instance().mCurrent = benefits; + instance().mCurrentName = package; + } + return true; } // static bool LLAgentBenefitsMgr::has(const std::string& package) { - return instance().mPackageMap.find(package) != instance().mPackageMap.end(); + return instance().mPackageMap.find(package) != instance().mPackageMap.end(); } //static bool LLAgentBenefitsMgr::isCurrent(const std::string& package) { - return instance().mCurrentName == package; + return instance().mCurrentName == package; } diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h index 962d0f9371..ff23241aa9 100644 --- a/indra/newview/llagentbenefits.h +++ b/indra/newview/llagentbenefits.h @@ -38,59 +38,59 @@ class LLAgentBenefits public: static constexpr S32 MIN_2K_TEXTURE_AREA = 1024 * 1024 + 1; - LLAgentBenefits(); - ~LLAgentBenefits(); - LOG_CLASS(LLAgentBenefits); + LLAgentBenefits(); + ~LLAgentBenefits(); + LOG_CLASS(LLAgentBenefits); - bool init(const LLSD& benefits_sd); + bool init(const LLSD& benefits_sd); - S32 getAnimatedObjectLimit() const; - S32 getAnimationUploadCost() const; - S32 getAttachmentLimit() const; - S32 getCreateGroupCost() const; - S32 getGroupMembershipLimit() const; - S32 getPicksLimit() const; - S32 getSoundUploadCost() const; - S32 getTextureUploadCost() const; + S32 getAnimatedObjectLimit() const; + S32 getAnimationUploadCost() const; + S32 getAttachmentLimit() const; + S32 getCreateGroupCost() const; + S32 getGroupMembershipLimit() const; + S32 getPicksLimit() const; + S32 getSoundUploadCost() const; + S32 getTextureUploadCost() const; S32 getTextureUploadCost(const LLViewerTexture* tex) const; S32 getTextureUploadCost(const LLImageBase* tex) const; S32 get2KTextureUploadCost(S32 area) const; - bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const; - + bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const; + private: - S32 m_animated_object_limit; - S32 m_animation_upload_cost; - S32 m_attachment_limit; - S32 m_create_group_cost; - S32 m_group_membership_limit; - S32 m_picks_limit; - S32 m_sound_upload_cost; - S32 m_texture_upload_cost; + S32 m_animated_object_limit; + S32 m_animation_upload_cost; + S32 m_attachment_limit; + S32 m_create_group_cost; + S32 m_group_membership_limit; + S32 m_picks_limit; + S32 m_sound_upload_cost; + S32 m_texture_upload_cost; std::vector m_2k_texture_upload_cost; - bool m_initalized; + bool m_initalized; }; -class LLAgentBenefitsMgr: public LLSingleton +class LLAgentBenefitsMgr: public LLSingleton { - LLSINGLETON(LLAgentBenefitsMgr); - ~LLAgentBenefitsMgr(); - LOG_CLASS(LLAgentBenefitsMgr); + LLSINGLETON(LLAgentBenefitsMgr); + ~LLAgentBenefitsMgr(); + LOG_CLASS(LLAgentBenefitsMgr); public: - static const LLAgentBenefits& current(); - static const LLAgentBenefits& get(const std::string& package); - static bool init(const std::string& package, const LLSD& benefits_sd); - static bool initCurrent(const std::string& package, const LLSD& benefits_sd); - static bool has(const std::string& package); - static bool isCurrent(const std::string& package); + static const LLAgentBenefits& current(); + static const LLAgentBenefits& get(const std::string& package); + static bool init(const std::string& package, const LLSD& benefits_sd); + static bool initCurrent(const std::string& package, const LLSD& benefits_sd); + static bool has(const std::string& package); + static bool isCurrent(const std::string& package); private: - std::string mCurrentName; - LLAgentBenefits mCurrent; - LLAgentBenefits mDefault; - std::map mPackageMap; + std::string mCurrentName; + LLAgentBenefits mCurrent; + LLAgentBenefits mDefault; + std::map mPackageMap; }; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 1764acfc67..70ff7f1941 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1,31 +1,31 @@ -/** +/** * @file llagentcamera.cpp * @brief LLAgent class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" -#include "llagentcamera.h" +#include "llagentcamera.h" #include "pipeline.h" @@ -60,8 +60,8 @@ const F32 MIN_ZOOM_FRACTION = 0.25f; const F32 INITIAL_ZOOM_FRACTION = 1.f; const F32 MAX_ZOOM_FRACTION = 8.f; -const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f; // seconds -const F32 FOV_ZOOM_HALF_LIFE = 0.07f; // seconds +const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f; // seconds +const F32 FOV_ZOOM_HALF_LIFE = 0.07f; // seconds const F32 CAMERA_FOCUS_HALF_LIFE = 0.f;//0.02f; const F32 CAMERA_LAG_HALF_LIFE = 0.25f; @@ -102,8 +102,8 @@ const F32 OBJECT_EXTENTS_PADDING = 0.5f; static bool isDisableCameraConstraints() { - static LLCachedControl sDisableCameraConstraints(gSavedSettings, "DisableCameraConstraints", false); - return sDisableCameraConstraints; + static LLCachedControl sDisableCameraConstraints(gSavedSettings, "DisableCameraConstraints", false); + return sDisableCameraConstraints; } // The agent instance. @@ -113,84 +113,84 @@ LLAgentCamera gAgentCamera; // LLAgentCamera() //----------------------------------------------------------------------------- LLAgentCamera::LLAgentCamera() : - mInitialized(false), - - mDrawDistance( DEFAULT_FAR_PLANE ), - - mLookAt(NULL), - mPointAt(NULL), - - mHUDTargetZoom(1.f), - mHUDCurZoom(1.f), - - mForceMouselook(FALSE), - - mCameraMode( CAMERA_MODE_THIRD_PERSON ), - mLastCameraMode( CAMERA_MODE_THIRD_PERSON ), - - mCameraPreset(CAMERA_PRESET_REAR_VIEW), - - mCameraAnimating( FALSE ), - mAnimationCameraStartGlobal(), - mAnimationFocusStartGlobal(), - mAnimationTimer(), - mAnimationDuration(0.33f), - - mCameraFOVZoomFactor(0.f), - mCameraCurrentFOVZoomFactor(0.f), - mCameraFocusOffset(), - - mCameraCollidePlane(), - - mCurrentCameraDistance(2.f), // meters, set in init() - mTargetCameraDistance(2.f), - mCameraZoomFraction(1.f), // deprecated - mThirdPersonHeadOffset(0.f, 0.f, 1.f), - mSitCameraEnabled(FALSE), - mCameraSmoothingLastPositionGlobal(), - mCameraSmoothingLastPositionAgent(), - mCameraSmoothingStop(false), - - mCameraUpVector(LLVector3::z_axis), // default is straight up - - mFocusOnAvatar(TRUE), - mAllowChangeToFollow(FALSE), - mFocusGlobal(), - mFocusTargetGlobal(), - mFocusObject(NULL), - mFocusObjectDist(0.f), - mFocusObjectOffset(), - mTrackFocusObject(TRUE), - - mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed - mWalkKey(0), // like AtKey, but causes less forward thrust - mLeftKey(0), - mUpKey(0), - mYawKey(0.f), - mPitchKey(0.f), - - mOrbitLeftKey(0.f), - mOrbitRightKey(0.f), - mOrbitUpKey(0.f), - mOrbitDownKey(0.f), - mOrbitInKey(0.f), - mOrbitOutKey(0.f), - - mPanUpKey(0.f), - mPanDownKey(0.f), - mPanLeftKey(0.f), - mPanRightKey(0.f), - mPanInKey(0.f), - mPanOutKey(0.f) -{ - mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); - - clearGeneralKeys(); - clearOrbitKeys(); - clearPanKeys(); - - resetPanDiff(); - resetOrbitDiff(); + mInitialized(false), + + mDrawDistance( DEFAULT_FAR_PLANE ), + + mLookAt(NULL), + mPointAt(NULL), + + mHUDTargetZoom(1.f), + mHUDCurZoom(1.f), + + mForceMouselook(FALSE), + + mCameraMode( CAMERA_MODE_THIRD_PERSON ), + mLastCameraMode( CAMERA_MODE_THIRD_PERSON ), + + mCameraPreset(CAMERA_PRESET_REAR_VIEW), + + mCameraAnimating( FALSE ), + mAnimationCameraStartGlobal(), + mAnimationFocusStartGlobal(), + mAnimationTimer(), + mAnimationDuration(0.33f), + + mCameraFOVZoomFactor(0.f), + mCameraCurrentFOVZoomFactor(0.f), + mCameraFocusOffset(), + + mCameraCollidePlane(), + + mCurrentCameraDistance(2.f), // meters, set in init() + mTargetCameraDistance(2.f), + mCameraZoomFraction(1.f), // deprecated + mThirdPersonHeadOffset(0.f, 0.f, 1.f), + mSitCameraEnabled(FALSE), + mCameraSmoothingLastPositionGlobal(), + mCameraSmoothingLastPositionAgent(), + mCameraSmoothingStop(false), + + mCameraUpVector(LLVector3::z_axis), // default is straight up + + mFocusOnAvatar(TRUE), + mAllowChangeToFollow(FALSE), + mFocusGlobal(), + mFocusTargetGlobal(), + mFocusObject(NULL), + mFocusObjectDist(0.f), + mFocusObjectOffset(), + mTrackFocusObject(TRUE), + + mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed + mWalkKey(0), // like AtKey, but causes less forward thrust + mLeftKey(0), + mUpKey(0), + mYawKey(0.f), + mPitchKey(0.f), + + mOrbitLeftKey(0.f), + mOrbitRightKey(0.f), + mOrbitUpKey(0.f), + mOrbitDownKey(0.f), + mOrbitInKey(0.f), + mOrbitOutKey(0.f), + + mPanUpKey(0.f), + mPanDownKey(0.f), + mPanLeftKey(0.f), + mPanRightKey(0.f), + mPanInKey(0.f), + mPanOutKey(0.f) +{ + mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); + + clearGeneralKeys(); + clearOrbitKeys(); + clearPanKeys(); + + resetPanDiff(); + resetOrbitDiff(); } // Requires gSavedSettings to be initialized. @@ -199,28 +199,28 @@ LLAgentCamera::LLAgentCamera() : //----------------------------------------------------------------------------- void LLAgentCamera::init() { - // *Note: this is where LLViewerCamera::getInstance() used to be constructed. + // *Note: this is where LLViewerCamera::getInstance() used to be constructed. - mDrawDistance = gSavedSettings.getF32("RenderFarClip"); + mDrawDistance = gSavedSettings.getF32("RenderFarClip"); - LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW); - // Leave at 0.1 meters until we have real near clip management - LLViewerCamera::getInstance()->setNear(0.1f); - LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h - LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape - LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW); + // Leave at 0.1 meters until we have real near clip management + LLViewerCamera::getInstance()->setNear(0.1f); + LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h + LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape - mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); - - mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType"); + mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); - mCameraCollidePlane.clearVec(); - mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); - mTargetCameraDistance = mCurrentCameraDistance; - mCameraZoomFraction = 1.f; - mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); + mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType"); - mInitialized = true; + mCameraCollidePlane.clearVec(); + mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); + mTargetCameraDistance = mCurrentCameraDistance; + mCameraZoomFraction = 1.f; + mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); + + mInitialized = true; } //----------------------------------------------------------------------------- @@ -228,40 +228,40 @@ void LLAgentCamera::init() //----------------------------------------------------------------------------- void LLAgentCamera::cleanup() { - setSitCamera(LLUUID::null); + setSitCamera(LLUUID::null); - if(mLookAt) - { - mLookAt->markDead() ; - mLookAt = NULL; - } - if(mPointAt) - { - mPointAt->markDead() ; - mPointAt = NULL; - } - setFocusObject(NULL); + if(mLookAt) + { + mLookAt->markDead() ; + mLookAt = NULL; + } + if(mPointAt) + { + mPointAt->markDead() ; + mPointAt = NULL; + } + setFocusObject(NULL); } void LLAgentCamera::setAvatarObject(LLVOAvatarSelf* avatar) { - if (!mLookAt) - { - mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); - } - if (!mPointAt) - { - mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); - } - - if (!mLookAt.isNull()) - { - mLookAt->setSourceObject(avatar); - } - if (!mPointAt.isNull()) - { - mPointAt->setSourceObject(avatar); - } + if (!mLookAt) + { + mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); + } + if (!mPointAt) + { + mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); + } + + if (!mLookAt.isNull()) + { + mLookAt->setSourceObject(avatar); + } + if (!mPointAt.isNull()) + { + mPointAt->setSourceObject(avatar); + } } //----------------------------------------------------------------------------- @@ -269,9 +269,9 @@ void LLAgentCamera::setAvatarObject(LLVOAvatarSelf* avatar) //----------------------------------------------------------------------------- LLAgentCamera::~LLAgentCamera() { - cleanup(); + cleanup(); - // *Note: this is where LLViewerCamera::getInstance() used to be deleted. + // *Note: this is where LLViewerCamera::getInstance() used to be deleted. } // Change camera back to third person, stop the autopilot, @@ -281,80 +281,80 @@ LLAgentCamera::~LLAgentCamera() //----------------------------------------------------------------------------- void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) { - if (gDisconnected) - { - return; - } - - if (gAgent.getAutoPilot()) - { - gAgent.stopAutoPilot(TRUE); - } - - LLSelectMgr::getInstance()->unhighlightAll(); - - // By popular request, keep land selection while walking around. JC - // LLViewerParcelMgr::getInstance()->deselectLand(); - - // force deselect when walking and attachment is selected - // this is so people don't wig out when their avatar moves without animating - if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) - { - LLSelectMgr::getInstance()->deselectAll(); - } - - if (gMenuHolder != NULL) - { - // Hide all popup menus - gMenuHolder->hideMenus(); - } - - if (change_camera && !gSavedSettings.getBOOL("FreezeTime")) - { - changeCameraToDefault(); - - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - handle_toggle_flycam(); - } - - // reset avatar mode from eventual residual motion - if (LLToolMgr::getInstance()->inBuildMode()) - { - LLViewerJoystick::getInstance()->moveAvatar(true); - } - - //Camera Tool is needed for Free Camera Control Mode - if (!LLFloaterCamera::inFreeCameraMode()) - { - LLFloaterReg::hideInstance("build"); - - // Switch back to basic toolset - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - } - - gViewerWindow->showCursor(); - } - - - if (reset_camera && !gSavedSettings.getBOOL("FreezeTime")) - { - if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson()) - { - // leaving mouse-steer mode - LLVector3 agent_at_axis = gAgent.getAtAxis(); - agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector()); - agent_at_axis.normalize(); - gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f))); - } - - setFocusOnAvatar(TRUE, ANIMATE); - - mCameraFOVZoomFactor = 0.f; - } - resetPanDiff(); - resetOrbitDiff(); - mHUDTargetZoom = 1.f; + if (gDisconnected) + { + return; + } + + if (gAgent.getAutoPilot()) + { + gAgent.stopAutoPilot(TRUE); + } + + LLSelectMgr::getInstance()->unhighlightAll(); + + // By popular request, keep land selection while walking around. JC + // LLViewerParcelMgr::getInstance()->deselectLand(); + + // force deselect when walking and attachment is selected + // this is so people don't wig out when their avatar moves without animating + if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) + { + LLSelectMgr::getInstance()->deselectAll(); + } + + if (gMenuHolder != NULL) + { + // Hide all popup menus + gMenuHolder->hideMenus(); + } + + if (change_camera && !gSavedSettings.getBOOL("FreezeTime")) + { + changeCameraToDefault(); + + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + handle_toggle_flycam(); + } + + // reset avatar mode from eventual residual motion + if (LLToolMgr::getInstance()->inBuildMode()) + { + LLViewerJoystick::getInstance()->moveAvatar(true); + } + + //Camera Tool is needed for Free Camera Control Mode + if (!LLFloaterCamera::inFreeCameraMode()) + { + LLFloaterReg::hideInstance("build"); + + // Switch back to basic toolset + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } + + gViewerWindow->showCursor(); + } + + + if (reset_camera && !gSavedSettings.getBOOL("FreezeTime")) + { + if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson()) + { + // leaving mouse-steer mode + LLVector3 agent_at_axis = gAgent.getAtAxis(); + agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector()); + agent_at_axis.normalize(); + gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f))); + } + + setFocusOnAvatar(TRUE, ANIMATE); + + mCameraFOVZoomFactor = 0.f; + } + resetPanDiff(); + resetOrbitDiff(); + mHUDTargetZoom = 1.f; if (LLSelectMgr::getInstance()->mAllowSelectAvatar) { @@ -375,14 +375,14 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) //----------------------------------------------------------------------------- void LLAgentCamera::unlockView() { - if (getFocusOnAvatar()) - { - if (isAgentAvatarValid()) - { - setFocusGlobal(LLVector3d::zero, gAgentAvatarp->mID); - } - setFocusOnAvatar(FALSE, FALSE); // no animation - } + if (getFocusOnAvatar()) + { + if (isAgentAvatarValid()) + { + setFocusGlobal(LLVector3d::zero, gAgentAvatarp->mID); + } + setFocusOnAvatar(FALSE, FALSE); // no animation + } } //----------------------------------------------------------------------------- @@ -390,10 +390,10 @@ void LLAgentCamera::unlockView() //----------------------------------------------------------------------------- void LLAgentCamera::slamLookAt(const LLVector3 &look_at) { - LLVector3 look_at_norm = look_at; - look_at_norm.mV[VZ] = 0.f; - look_at_norm.normalize(); - gAgent.resetAxes(look_at_norm); + LLVector3 look_at_norm = look_at; + look_at_norm.mV[VZ] = 0.f; + look_at_norm.normalize(); + gAgent.resetAxes(look_at_norm); } //----------------------------------------------------------------------------- @@ -401,172 +401,172 @@ void LLAgentCamera::slamLookAt(const LLVector3 &look_at) //----------------------------------------------------------------------------- LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y) { - LLMatrix4 obj_matrix = object->getRenderMatrix(); - LLQuaternion obj_rot = object->getRenderRotation(); - LLVector3 obj_pos = object->getRenderPosition(); + LLMatrix4 obj_matrix = object->getRenderMatrix(); + LLQuaternion obj_rot = object->getRenderRotation(); + LLVector3 obj_pos = object->getRenderPosition(); - // if is avatar - don't do any funk heuristics to position the focal point - // see DEV-30589 - if ((object->isAvatar() && !object->isRoot()) || (object->isAnimatedObject() && object->getControlAvatar())) - { - return original_focus_point - obj_pos; - } + // if is avatar - don't do any funk heuristics to position the focal point + // see DEV-30589 + if ((object->isAvatar() && !object->isRoot()) || (object->isAnimatedObject() && object->getControlAvatar())) + { + return original_focus_point - obj_pos; + } if (object->isAvatar()) { LLVOAvatar* av = object->asAvatar(); return original_focus_point - av->getCharacterPosition(); } - - LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation - LLVector3 object_extents = object->getScale(); - - // make sure they object extents are non-zero - object_extents.clamp(0.001f, F32_MAX); - - // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object - LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin(); - obj_to_cam_ray.rotVec(inv_obj_rot); - obj_to_cam_ray.normalize(); - - // obj_to_cam_ray_proportions are the (positive) ratios of - // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions. - LLVector3 obj_to_cam_ray_proportions; - obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]); - obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]); - obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]); - - // find the largest ratio stored in obj_to_cam_ray_proportions - // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera - LLVector3 longest_object_axis; - // is x-axis longest? - if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] - && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ]) - { - // then grab it - longest_object_axis.setVec(obj_matrix.getFwdRow4()); - } - // is y-axis longest? - else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ]) - { - // then grab it - longest_object_axis.setVec(obj_matrix.getLeftRow4()); - } - // otherwise, use z axis - else - { - longest_object_axis.setVec(obj_matrix.getUpRow4()); - } - - // Use this axis as the normal to project mouse click on to plane with that normal, at the object center. - // This generates a point behind the mouse cursor that is approximately in the middle of the object in - // terms of depth. - // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera. - // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable - // eccentricity to the object orientation - LLVector3 focus_plane_normal(longest_object_axis); - focus_plane_normal.normalize(); - - LLVector3d focus_pt_global; - gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal); - LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global); - - // find vector from camera to focus point in object space - LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin(); - camera_to_focus_vec.rotVec(inv_obj_rot); - - // find vector from object origin to focus point in object coordinates - LLVector3 focus_offset_from_object_center = focus_pt - obj_pos; - // convert to object-local space - focus_offset_from_object_center.rotVec(inv_obj_rot); - - // We need to project the focus point back into the bounding box of the focused object. - // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis - LLVector3 clip_fraction; - - // for each axis... - for (U32 axis = VX; axis <= VZ; axis++) - { - //...calculate distance that focus offset sits outside of bounding box along that axis... - //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center - F32 dist_out_of_bounds; - if (focus_offset_from_object_center.mV[axis] > 0.f) - { - dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f)); - } - else - { - dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f)); - } - - //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis - if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f) - { - // don't divide by very small number - clip_fraction.mV[axis] = 0.f; - } - else - { - clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis]; - } - } - - LLVector3 abs_clip_fraction = clip_fraction; - abs_clip_fraction.abs(); - - // find axis of focus offset that is *most* outside the bounding box and use that to - // rescale focus offset to inside object extents - if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] - && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ]) - { - focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec; - } - else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ]) - { - focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec; - } - else - { - focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec; - } - - // convert back to world space - focus_offset_from_object_center.rotVec(obj_rot); - - // now, based on distance of camera from object relative to object size - // push the focus point towards the near surface of the object when (relatively) close to the objcet - // or keep the focus point in the object middle when (relatively) far - // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars - // is almost always "tumble about middle" and not "spin around surface point" - { - LLVector3 obj_rel = original_focus_point - object->getRenderPosition(); - - //now that we have the object relative position, we should bias toward the center of the object - //based on the distance of the camera to the focus point vs. the distance of the camera to the focus - - F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis()); - F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin()); - - - LLBBox obj_bbox = object->getBoundingBoxAgent(); - F32 bias = 0.f; - - // virtual_camera_pos is the camera position we are simulating by backing the camera off - // and adjusting the FOV - LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor)); - - // if the camera is inside the object (large, hollow objects, for example) - // leave focus point all the way to destination depth, away from object center - if(!obj_bbox.containsPointAgent(virtual_camera_pos)) - { - // perform magic number biasing of focus point towards surface vs. planar center - bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f); - obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias); - } - - focus_offset_from_object_center = obj_rel; - } - - return focus_offset_from_object_center; + + LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation + LLVector3 object_extents = object->getScale(); + + // make sure they object extents are non-zero + object_extents.clamp(0.001f, F32_MAX); + + // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object + LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin(); + obj_to_cam_ray.rotVec(inv_obj_rot); + obj_to_cam_ray.normalize(); + + // obj_to_cam_ray_proportions are the (positive) ratios of + // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions. + LLVector3 obj_to_cam_ray_proportions; + obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]); + obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]); + obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]); + + // find the largest ratio stored in obj_to_cam_ray_proportions + // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera + LLVector3 longest_object_axis; + // is x-axis longest? + if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] + && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ]) + { + // then grab it + longest_object_axis.setVec(obj_matrix.getFwdRow4()); + } + // is y-axis longest? + else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ]) + { + // then grab it + longest_object_axis.setVec(obj_matrix.getLeftRow4()); + } + // otherwise, use z axis + else + { + longest_object_axis.setVec(obj_matrix.getUpRow4()); + } + + // Use this axis as the normal to project mouse click on to plane with that normal, at the object center. + // This generates a point behind the mouse cursor that is approximately in the middle of the object in + // terms of depth. + // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera. + // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable + // eccentricity to the object orientation + LLVector3 focus_plane_normal(longest_object_axis); + focus_plane_normal.normalize(); + + LLVector3d focus_pt_global; + gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal); + LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global); + + // find vector from camera to focus point in object space + LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin(); + camera_to_focus_vec.rotVec(inv_obj_rot); + + // find vector from object origin to focus point in object coordinates + LLVector3 focus_offset_from_object_center = focus_pt - obj_pos; + // convert to object-local space + focus_offset_from_object_center.rotVec(inv_obj_rot); + + // We need to project the focus point back into the bounding box of the focused object. + // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis + LLVector3 clip_fraction; + + // for each axis... + for (U32 axis = VX; axis <= VZ; axis++) + { + //...calculate distance that focus offset sits outside of bounding box along that axis... + //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center + F32 dist_out_of_bounds; + if (focus_offset_from_object_center.mV[axis] > 0.f) + { + dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f)); + } + else + { + dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f)); + } + + //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis + if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f) + { + // don't divide by very small number + clip_fraction.mV[axis] = 0.f; + } + else + { + clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis]; + } + } + + LLVector3 abs_clip_fraction = clip_fraction; + abs_clip_fraction.abs(); + + // find axis of focus offset that is *most* outside the bounding box and use that to + // rescale focus offset to inside object extents + if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] + && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ]) + { + focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec; + } + else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ]) + { + focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec; + } + else + { + focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec; + } + + // convert back to world space + focus_offset_from_object_center.rotVec(obj_rot); + + // now, based on distance of camera from object relative to object size + // push the focus point towards the near surface of the object when (relatively) close to the objcet + // or keep the focus point in the object middle when (relatively) far + // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars + // is almost always "tumble about middle" and not "spin around surface point" + { + LLVector3 obj_rel = original_focus_point - object->getRenderPosition(); + + //now that we have the object relative position, we should bias toward the center of the object + //based on the distance of the camera to the focus point vs. the distance of the camera to the focus + + F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis()); + F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin()); + + + LLBBox obj_bbox = object->getBoundingBoxAgent(); + F32 bias = 0.f; + + // virtual_camera_pos is the camera position we are simulating by backing the camera off + // and adjusting the FOV + LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor)); + + // if the camera is inside the object (large, hollow objects, for example) + // leave focus point all the way to destination depth, away from object center + if(!obj_bbox.containsPointAgent(virtual_camera_pos)) + { + // perform magic number biasing of focus point towards surface vs. planar center + bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f); + obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias); + } + + focus_offset_from_object_center = obj_rel; + } + + return focus_offset_from_object_center; } //----------------------------------------------------------------------------- @@ -574,277 +574,277 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi //----------------------------------------------------------------------------- BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance) { - BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars) + BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars) - if (!mFocusObject || mFocusObject->isDead() || - mFocusObject->isMesh() || - isDisableCameraConstraints()) - { - obj_min_distance = 0.f; - return TRUE; - } + if (!mFocusObject || mFocusObject->isDead() || + mFocusObject->isMesh() || + isDisableCameraConstraints()) + { + obj_min_distance = 0.f; + return TRUE; + } - if (mFocusObject->mDrawable.isNull()) - { + if (mFocusObject->mDrawable.isNull()) + { #ifdef LL_RELEASE_FOR_DOWNLOAD - LL_WARNS() << "Focus object with no drawable!" << LL_ENDL; + LL_WARNS() << "Focus object with no drawable!" << LL_ENDL; #else - mFocusObject->dump(); - LL_ERRS() << "Focus object with no drawable!" << LL_ENDL; + mFocusObject->dump(); + LL_ERRS() << "Focus object with no drawable!" << LL_ENDL; #endif - obj_min_distance = 0.f; - return TRUE; - } - - LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation(); - LLVector3 target_offset_origin = mFocusObjectOffset; - LLVector3 camera_offset_target(getCameraPositionAgent() - gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); - - // convert offsets into object local space - camera_offset_target.rotVec(inv_object_rot); - target_offset_origin.rotVec(inv_object_rot); - - // push around object extents based on target offset - LLVector3 object_extents = mFocusObject->getScale(); - if (mFocusObject->isAvatar()) - { - // fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom) - object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR; - object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR; - object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR; - soft_limit = TRUE; - } - LLVector3 abs_target_offset = target_offset_origin; - abs_target_offset.abs(); - - LLVector3 target_offset_dir = target_offset_origin; - - BOOL target_outside_object_extents = FALSE; - - for (U32 i = VX; i <= VZ; i++) - { - if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING) - { - target_outside_object_extents = TRUE; - } - if (camera_offset_target.mV[i] > 0.f) - { - object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f; - } - else - { - object_extents.mV[i] += target_offset_origin.mV[i] * 2.f; - } - } - - // don't shrink the object extents so far that the object inverts - object_extents.clamp(0.001f, F32_MAX); - - // move into first octant - LLVector3 camera_offset_target_abs_norm = camera_offset_target; - camera_offset_target_abs_norm.abs(); - // make sure offset is non-zero - camera_offset_target_abs_norm.clamp(0.001f, F32_MAX); - camera_offset_target_abs_norm.normalize(); - - // find camera position relative to normalized object extents - LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm; - camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX]; - camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY]; - camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ]; - - if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] && - camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ]) - { - if (camera_offset_target_abs_norm.mV[VX] < 0.001f) - { - obj_min_distance = object_extents.mV[VX] * 0.5f; - } - else - { - obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX]; - } - } - else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ]) - { - if (camera_offset_target_abs_norm.mV[VY] < 0.001f) - { - obj_min_distance = object_extents.mV[VY] * 0.5f; - } - else - { - obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY]; - } - } - else - { - if (camera_offset_target_abs_norm.mV[VZ] < 0.001f) - { - obj_min_distance = object_extents.mV[VZ] * 0.5f; - } - else - { - obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ]; - } - } - - LLVector3 object_split_axis; - LLVector3 target_offset_scaled = target_offset_origin; - target_offset_scaled.abs(); - target_offset_scaled.normalize(); - target_offset_scaled.mV[VX] /= object_extents.mV[VX]; - target_offset_scaled.mV[VY] /= object_extents.mV[VY]; - target_offset_scaled.mV[VZ] /= object_extents.mV[VZ]; - - if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] && - target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ]) - { - object_split_axis = LLVector3::x_axis; - } - else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ]) - { - object_split_axis = LLVector3::y_axis; - } - else - { - object_split_axis = LLVector3::z_axis; - } - - LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent()); - - - F32 camera_offset_clip = camera_offset_object * object_split_axis; - F32 target_offset_clip = target_offset_dir * object_split_axis; - - // target has moved outside of object extents - // check to see if camera and target are on same side - if (target_outside_object_extents) - { - if (camera_offset_clip > 0.f && target_offset_clip > 0.f) - { - return FALSE; - } - else if (camera_offset_clip < 0.f && target_offset_clip < 0.f) - { - return FALSE; - } - } - - // clamp obj distance to diagonal of 10 by 10 cube - obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3); - - obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f); - - return TRUE; + obj_min_distance = 0.f; + return TRUE; + } + + LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation(); + LLVector3 target_offset_origin = mFocusObjectOffset; + LLVector3 camera_offset_target(getCameraPositionAgent() - gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); + + // convert offsets into object local space + camera_offset_target.rotVec(inv_object_rot); + target_offset_origin.rotVec(inv_object_rot); + + // push around object extents based on target offset + LLVector3 object_extents = mFocusObject->getScale(); + if (mFocusObject->isAvatar()) + { + // fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom) + object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR; + object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR; + object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR; + soft_limit = TRUE; + } + LLVector3 abs_target_offset = target_offset_origin; + abs_target_offset.abs(); + + LLVector3 target_offset_dir = target_offset_origin; + + BOOL target_outside_object_extents = FALSE; + + for (U32 i = VX; i <= VZ; i++) + { + if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING) + { + target_outside_object_extents = TRUE; + } + if (camera_offset_target.mV[i] > 0.f) + { + object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f; + } + else + { + object_extents.mV[i] += target_offset_origin.mV[i] * 2.f; + } + } + + // don't shrink the object extents so far that the object inverts + object_extents.clamp(0.001f, F32_MAX); + + // move into first octant + LLVector3 camera_offset_target_abs_norm = camera_offset_target; + camera_offset_target_abs_norm.abs(); + // make sure offset is non-zero + camera_offset_target_abs_norm.clamp(0.001f, F32_MAX); + camera_offset_target_abs_norm.normalize(); + + // find camera position relative to normalized object extents + LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm; + camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX]; + camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY]; + camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ]; + + if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] && + camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ]) + { + if (camera_offset_target_abs_norm.mV[VX] < 0.001f) + { + obj_min_distance = object_extents.mV[VX] * 0.5f; + } + else + { + obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX]; + } + } + else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ]) + { + if (camera_offset_target_abs_norm.mV[VY] < 0.001f) + { + obj_min_distance = object_extents.mV[VY] * 0.5f; + } + else + { + obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY]; + } + } + else + { + if (camera_offset_target_abs_norm.mV[VZ] < 0.001f) + { + obj_min_distance = object_extents.mV[VZ] * 0.5f; + } + else + { + obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ]; + } + } + + LLVector3 object_split_axis; + LLVector3 target_offset_scaled = target_offset_origin; + target_offset_scaled.abs(); + target_offset_scaled.normalize(); + target_offset_scaled.mV[VX] /= object_extents.mV[VX]; + target_offset_scaled.mV[VY] /= object_extents.mV[VY]; + target_offset_scaled.mV[VZ] /= object_extents.mV[VZ]; + + if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] && + target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ]) + { + object_split_axis = LLVector3::x_axis; + } + else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ]) + { + object_split_axis = LLVector3::y_axis; + } + else + { + object_split_axis = LLVector3::z_axis; + } + + LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent()); + + + F32 camera_offset_clip = camera_offset_object * object_split_axis; + F32 target_offset_clip = target_offset_dir * object_split_axis; + + // target has moved outside of object extents + // check to see if camera and target are on same side + if (target_outside_object_extents) + { + if (camera_offset_clip > 0.f && target_offset_clip > 0.f) + { + return FALSE; + } + else if (camera_offset_clip < 0.f && target_offset_clip < 0.f) + { + return FALSE; + } + } + + // clamp obj distance to diagonal of 10 by 10 cube + obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3); + + obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f); + + return TRUE; } F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person) { - // 0.f -> camera zoomed all the way out - // 1.f -> camera zoomed all the way in - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - // already [0,1] - return mHUDTargetZoom; - } - - if (isDisableCameraConstraints()) - { - return mCameraZoomFraction; - } - - if (get_third_person || (mFocusOnAvatar && cameraThirdPerson())) - { - return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f); - } - - if (cameraCustomizeAvatar()) - { - F32 distance = (F32)mCameraFocusOffsetTarget.magVec(); - return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f ); - } - - F32 min_zoom; - F32 max_zoom = getCameraMaxZoomDistance(); - - F32 distance = (F32)mCameraFocusOffsetTarget.magVec(); - if (mFocusObject.notNull()) - { - if (mFocusObject->isAvatar()) - { - min_zoom = AVATAR_MIN_ZOOM; - } - else - { - min_zoom = OBJECT_MIN_ZOOM; - } - } - else - { - min_zoom = LAND_MIN_ZOOM; - } - - return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f); + // 0.f -> camera zoomed all the way out + // 1.f -> camera zoomed all the way in + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + // already [0,1] + return mHUDTargetZoom; + } + + if (isDisableCameraConstraints()) + { + return mCameraZoomFraction; + } + + if (get_third_person || (mFocusOnAvatar && cameraThirdPerson())) + { + return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f); + } + + if (cameraCustomizeAvatar()) + { + F32 distance = (F32)mCameraFocusOffsetTarget.magVec(); + return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f ); + } + + F32 min_zoom; + F32 max_zoom = getCameraMaxZoomDistance(); + + F32 distance = (F32)mCameraFocusOffsetTarget.magVec(); + if (mFocusObject.notNull()) + { + if (mFocusObject->isAvatar()) + { + min_zoom = AVATAR_MIN_ZOOM; + } + else + { + min_zoom = OBJECT_MIN_ZOOM; + } + } + else + { + min_zoom = LAND_MIN_ZOOM; + } + + return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f); } void LLAgentCamera::setCameraZoomFraction(F32 fraction) { - // 0.f -> camera zoomed all the way out - // 1.f -> camera zoomed all the way in - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - mHUDTargetZoom = fraction; - } - else if (isDisableCameraConstraints()) - { - mCameraZoomFraction = fraction; - } - else if (mFocusOnAvatar && cameraThirdPerson()) - { - mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION); - } - else if (cameraCustomizeAvatar()) - { - LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; - camera_offset_dir.normalize(); - mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM); - } - else - { - F32 min_zoom = LAND_MIN_ZOOM; - F32 max_zoom = getCameraMaxZoomDistance(); - - if (mFocusObject.notNull()) - { - if (mFocusObject.notNull()) - { - if (mFocusObject->isAvatar()) - { - min_zoom = AVATAR_MIN_ZOOM; - } - else - { - min_zoom = OBJECT_MIN_ZOOM; - } - } - } - - LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; - camera_offset_dir.normalize(); - mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom); - } - - startCameraAnimation(); + // 0.f -> camera zoomed all the way out + // 1.f -> camera zoomed all the way in + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + mHUDTargetZoom = fraction; + } + else if (isDisableCameraConstraints()) + { + mCameraZoomFraction = fraction; + } + else if (mFocusOnAvatar && cameraThirdPerson()) + { + mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION); + } + else if (cameraCustomizeAvatar()) + { + LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; + camera_offset_dir.normalize(); + mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM); + } + else + { + F32 min_zoom = LAND_MIN_ZOOM; + F32 max_zoom = getCameraMaxZoomDistance(); + + if (mFocusObject.notNull()) + { + if (mFocusObject.notNull()) + { + if (mFocusObject->isAvatar()) + { + min_zoom = AVATAR_MIN_ZOOM; + } + else + { + min_zoom = OBJECT_MIN_ZOOM; + } + } + } + + LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; + camera_offset_dir.normalize(); + mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom); + } + + startCameraAnimation(); } F32 LLAgentCamera::getAgentHUDTargetZoom() { - static LLCachedControl hud_scale_factor(gSavedSettings, "HUDScaleFactor"); - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor; + static LLCachedControl hud_scale_factor(gSavedSettings, "HUDScaleFactor"); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor; } //----------------------------------------------------------------------------- @@ -852,22 +852,22 @@ F32 LLAgentCamera::getAgentHUDTargetZoom() //----------------------------------------------------------------------------- void LLAgentCamera::cameraOrbitAround(const F32 radians) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - // do nothing for hud selection - } - else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW)) - { - gAgent.yaw(radians); - } - else - { - mOrbitAroundRadians += radians; - mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f); - - cameraZoomIn(1.f); - } + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + // do nothing for hud selection + } + else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW)) + { + gAgent.yaw(radians); + } + else + { + mOrbitAroundRadians += radians; + mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f); + + cameraZoomIn(1.f); + } } @@ -876,51 +876,51 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians) //----------------------------------------------------------------------------- void LLAgentCamera::cameraOrbitOver(const F32 angle) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - // do nothing for hud selection - } - else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) - { - gAgent.pitch(angle); - } - else - { - LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); - camera_offset_unit.normalize(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + // do nothing for hud selection + } + else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) + { + gAgent.pitch(angle); + } + else + { + LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); + camera_offset_unit.normalize(); - F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() ); + F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() ); - LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); - F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD); - mOrbitOverAngle += angle_from_up - new_angle; - mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis); + LLVector3d left_axis; + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD); + mOrbitOverAngle += angle_from_up - new_angle; + mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis); - cameraZoomIn(1.f); - } + cameraZoomIn(1.f); + } } void LLAgentCamera::resetCameraOrbit() { - LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); - camera_offset_unit.normalize(); + LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); + camera_offset_unit.normalize(); + + LLVector3d left_axis; + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis); - LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); - mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis); - - mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f); + mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f); - cameraZoomIn(1.f); - resetOrbitDiff(); + cameraZoomIn(1.f); + resetOrbitDiff(); } void LLAgentCamera::resetOrbitDiff() { - mOrbitAroundRadians = 0; - mOrbitOverAngle = 0; + mOrbitAroundRadians = 0; + mOrbitOverAngle = 0; } //----------------------------------------------------------------------------- @@ -928,56 +928,56 @@ void LLAgentCamera::resetOrbitDiff() //----------------------------------------------------------------------------- void LLAgentCamera::cameraZoomIn(const F32 fraction) { - if (gDisconnected) - { - return; - } - - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - // just update hud zoom level - mHUDTargetZoom /= fraction; - return; - } + if (gDisconnected) + { + return; + } - LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); - F32 current_distance = (F32)camera_offset_unit.normalize(); - F32 new_distance = current_distance * fraction; + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + // just update hud zoom level + mHUDTargetZoom /= fraction; + return; + } - // Unless camera is unlocked - if (!isDisableCameraConstraints()) - { - F32 min_zoom = LAND_MIN_ZOOM; + LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); + F32 current_distance = (F32)camera_offset_unit.normalize(); + F32 new_distance = current_distance * fraction; - // Don't move through focus point - if (mFocusObject) - { - LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]); + // Unless camera is unlocked + if (!isDisableCameraConstraints()) + { + F32 min_zoom = LAND_MIN_ZOOM; - if (mFocusObject->isAvatar()) - { - calcCameraMinDistance(min_zoom); - } - else - { - min_zoom = OBJECT_MIN_ZOOM; - } - } + // Don't move through focus point + if (mFocusObject) + { + LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]); + + if (mFocusObject->isAvatar()) + { + calcCameraMinDistance(min_zoom); + } + else + { + min_zoom = OBJECT_MIN_ZOOM; + } + } - new_distance = llmax(new_distance, min_zoom); + new_distance = llmax(new_distance, min_zoom); - F32 max_distance = getCameraMaxZoomDistance(); - max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154 - new_distance = llmin(new_distance, max_distance); + F32 max_distance = getCameraMaxZoomDistance(); + max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154 + new_distance = llmin(new_distance, max_distance); - if (cameraCustomizeAvatar()) - { - new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM); - } - } + if (cameraCustomizeAvatar()) + { + new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM); + } + } - mCameraFocusOffsetTarget = new_distance * camera_offset_unit; + mCameraFocusOffsetTarget = new_distance * camera_offset_unit; } //----------------------------------------------------------------------------- @@ -985,80 +985,80 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction) //----------------------------------------------------------------------------- void LLAgentCamera::cameraOrbitIn(const F32 meters) { - if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) - { - F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale")); - - mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; - - if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f) - { - // No need to animate, camera is already there. - changeCameraToMouselook(FALSE); - } - - if (!isDisableCameraConstraints()) - { - mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION); - } - } - else - { - LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); - F32 current_distance = (F32)camera_offset_unit.normalize(); - F32 new_distance = current_distance - meters; - - // Unless camera is unlocked - if (!isDisableCameraConstraints()) - { - F32 min_zoom = LAND_MIN_ZOOM; - - // Don't move through focus point - if (mFocusObject.notNull()) - { - if (mFocusObject->isAvatar()) - { - min_zoom = AVATAR_MIN_ZOOM; - } - else - { - min_zoom = OBJECT_MIN_ZOOM; - } - } - - new_distance = llmax(new_distance, min_zoom); - - F32 max_distance = getCameraMaxZoomDistance(); - new_distance = llmin(new_distance, max_distance); - - if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) - { - new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM); - } - } - - // Compute new camera offset - mCameraFocusOffsetTarget = new_distance * camera_offset_unit; - cameraZoomIn(1.f); - } -} + if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) + { + F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale")); -//----------------------------------------------------------------------------- -// cameraPanIn() -//----------------------------------------------------------------------------- -void LLAgentCamera::cameraPanIn(F32 meters) -{ - LLVector3d at_axis; - at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis()); + mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; - mPanFocusDiff += meters * at_axis; + if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f) + { + // No need to animate, camera is already there. + changeCameraToMouselook(FALSE); + } + + if (!isDisableCameraConstraints()) + { + mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION); + } + } + else + { + LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); + F32 current_distance = (F32)camera_offset_unit.normalize(); + F32 new_distance = current_distance - meters; - mFocusTargetGlobal += meters * at_axis; - mFocusGlobal = mFocusTargetGlobal; - // don't enforce zoom constraints as this is the only way for users to get past them easily - updateFocusOffset(); - // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + // Unless camera is unlocked + if (!isDisableCameraConstraints()) + { + F32 min_zoom = LAND_MIN_ZOOM; + + // Don't move through focus point + if (mFocusObject.notNull()) + { + if (mFocusObject->isAvatar()) + { + min_zoom = AVATAR_MIN_ZOOM; + } + else + { + min_zoom = OBJECT_MIN_ZOOM; + } + } + + new_distance = llmax(new_distance, min_zoom); + + F32 max_distance = getCameraMaxZoomDistance(); + new_distance = llmin(new_distance, max_distance); + + if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) + { + new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM); + } + } + + // Compute new camera offset + mCameraFocusOffsetTarget = new_distance * camera_offset_unit; + cameraZoomIn(1.f); + } +} + +//----------------------------------------------------------------------------- +// cameraPanIn() +//----------------------------------------------------------------------------- +void LLAgentCamera::cameraPanIn(F32 meters) +{ + LLVector3d at_axis; + at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis()); + + mPanFocusDiff += meters * at_axis; + + mFocusTargetGlobal += meters * at_axis; + mFocusGlobal = mFocusTargetGlobal; + // don't enforce zoom constraints as this is the only way for users to get past them easily + updateFocusOffset(); + // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx + mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); } //----------------------------------------------------------------------------- @@ -1066,21 +1066,21 @@ void LLAgentCamera::cameraPanIn(F32 meters) //----------------------------------------------------------------------------- void LLAgentCamera::cameraPanLeft(F32 meters) { - LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + LLVector3d left_axis; + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + + mPanFocusDiff += meters * left_axis; - mPanFocusDiff += meters * left_axis; + mFocusTargetGlobal += meters * left_axis; + mFocusGlobal = mFocusTargetGlobal; - mFocusTargetGlobal += meters * left_axis; - mFocusGlobal = mFocusTargetGlobal; + // disable smoothing for camera pan, which causes some residents unhappiness + mCameraSmoothingStop = true; - // disable smoothing for camera pan, which causes some residents unhappiness - mCameraSmoothingStop = true; - - cameraZoomIn(1.f); - updateFocusOffset(); - // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + cameraZoomIn(1.f); + updateFocusOffset(); + // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx + mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); } //----------------------------------------------------------------------------- @@ -1088,41 +1088,41 @@ void LLAgentCamera::cameraPanLeft(F32 meters) //----------------------------------------------------------------------------- void LLAgentCamera::cameraPanUp(F32 meters) { - LLVector3d up_axis; - up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis()); + LLVector3d up_axis; + up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis()); - mPanFocusDiff += meters * up_axis; + mPanFocusDiff += meters * up_axis; - mFocusTargetGlobal += meters * up_axis; - mFocusGlobal = mFocusTargetGlobal; + mFocusTargetGlobal += meters * up_axis; + mFocusGlobal = mFocusTargetGlobal; - // disable smoothing for camera pan, which causes some residents unhappiness - mCameraSmoothingStop = true; + // disable smoothing for camera pan, which causes some residents unhappiness + mCameraSmoothingStop = true; - cameraZoomIn(1.f); - updateFocusOffset(); - // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + cameraZoomIn(1.f); + updateFocusOffset(); + // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx + mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); } void LLAgentCamera::resetCameraPan() { - mFocusTargetGlobal -= mPanFocusDiff; + mFocusTargetGlobal -= mPanFocusDiff; - mFocusGlobal = mFocusTargetGlobal; - mCameraSmoothingStop = true; + mFocusGlobal = mFocusTargetGlobal; + mCameraSmoothingStop = true; - cameraZoomIn(1.f); - updateFocusOffset(); + cameraZoomIn(1.f); + updateFocusOffset(); - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); - resetPanDiff(); + resetPanDiff(); } void LLAgentCamera::resetPanDiff() { - mPanFocusDiff.clear(); + mPanFocusDiff.clear(); } //----------------------------------------------------------------------------- @@ -1130,67 +1130,67 @@ void LLAgentCamera::resetPanDiff() //----------------------------------------------------------------------------- void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) { - static LLVector3 last_at_axis; - - if (!isAgentAvatarValid()) return; - - LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation(); - LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation(); - - if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f - && (root_at * last_at_axis > 0.95f)) - { - LLVector3 vel = gAgentAvatarp->getVelocity(); - if (vel.magVecSquared() > 4.f) - { - setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, vel * av_inv_rot); - } - else - { - // *FIX: rotate mframeagent by sit object's rotation? - LLQuaternion look_rotation = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation - LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot; - setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, look_offset); - } - last_at_axis = root_at; - return; - } - - last_at_axis = root_at; - - if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) - { - setLookAt(LOOKAT_TARGET_NONE, gAgentAvatarp, LLVector3(-2.f, 0.f, 0.f)); - } - else - { - // Move head based on cursor position - ELookAtType lookAtType = LOOKAT_TARGET_NONE; - LLVector3 headLookAxis; - LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance()); - - if (cameraMouselook()) - { - lookAtType = LOOKAT_TARGET_MOUSELOOK; - } - else if (cameraThirdPerson()) - { - // range from -.5 to .5 - F32 x_from_center = - ((F32) mouse_x / (F32) gViewerWindow->getWorldViewWidthScaled() ) - 0.5f; - F32 y_from_center = - ((F32) mouse_y / (F32) gViewerWindow->getWorldViewHeightScaled() ) - 0.5f; - - frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD); - frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD); - lookAtType = LOOKAT_TARGET_FREELOOK; - } - - headLookAxis = frameCamera.getAtAxis(); - // RN: we use world-space offset for mouselook and freelook - //headLookAxis = headLookAxis * av_inv_rot; - setLookAt(lookAtType, gAgentAvatarp, headLookAxis); - } + static LLVector3 last_at_axis; + + if (!isAgentAvatarValid()) return; + + LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation(); + LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation(); + + if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f + && (root_at * last_at_axis > 0.95f)) + { + LLVector3 vel = gAgentAvatarp->getVelocity(); + if (vel.magVecSquared() > 4.f) + { + setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, vel * av_inv_rot); + } + else + { + // *FIX: rotate mframeagent by sit object's rotation? + LLQuaternion look_rotation = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation + LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot; + setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, look_offset); + } + last_at_axis = root_at; + return; + } + + last_at_axis = root_at; + + if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) + { + setLookAt(LOOKAT_TARGET_NONE, gAgentAvatarp, LLVector3(-2.f, 0.f, 0.f)); + } + else + { + // Move head based on cursor position + ELookAtType lookAtType = LOOKAT_TARGET_NONE; + LLVector3 headLookAxis; + LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance()); + + if (cameraMouselook()) + { + lookAtType = LOOKAT_TARGET_MOUSELOOK; + } + else if (cameraThirdPerson()) + { + // range from -.5 to .5 + F32 x_from_center = + ((F32) mouse_x / (F32) gViewerWindow->getWorldViewWidthScaled() ) - 0.5f; + F32 y_from_center = + ((F32) mouse_y / (F32) gViewerWindow->getWorldViewHeightScaled() ) - 0.5f; + + frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD); + frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD); + lookAtType = LOOKAT_TARGET_FREELOOK; + } + + headLookAxis = frameCamera.getAtAxis(); + // RN: we use world-space offset for mouselook and freelook + //headLookAxis = headLookAxis * av_inv_rot; + setLookAt(lookAtType, gAgentAvatarp, headLookAxis); + } } static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera"); @@ -1202,377 +1202,377 @@ extern BOOL gCubeSnapshot; //----------------------------------------------------------------------------- void LLAgentCamera::updateCamera() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA); + LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA); if (gCubeSnapshot) { return; } - // - changed camera_skyward to the new global "mCameraUpVector" - mCameraUpVector = LLVector3::z_axis; - //LLVector3 camera_skyward(0.f, 0.f, 1.f); - - U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode; - - validateFocusObject(); - - if (isAgentAvatarValid() && - gAgentAvatarp->isSitting() && - camera_mode == CAMERA_MODE_MOUSELOOK) - { - //changed camera_skyward to the new global "mCameraUpVector" - mCameraUpVector = mCameraUpVector * gAgentAvatarp->getRenderRotation(); - } - - if (cameraThirdPerson() && (mFocusOnAvatar || mAllowChangeToFollow) && LLFollowCamMgr::getInstance()->getActiveFollowCamParams()) - { - mAllowChangeToFollow = FALSE; - mFocusOnAvatar = TRUE; - changeCameraToFollow(); - } - - //NOTE - this needs to be integrated into a general upVector system here within llAgent. - if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar ) - { - mCameraUpVector = mFollowCam.getUpVector(); - } - - if (mSitCameraEnabled) - { - if (mSitCameraReferenceObject->isDead()) - { - setSitCamera(LLUUID::null); - } - } - - // Update UI with our camera inputs - LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance("camera"); - if (camera_floater) - { - camera_floater->mRotate->setToggleState(gAgentCamera.getOrbitRightKey() > 0.f, // left - gAgentCamera.getOrbitUpKey() > 0.f, // top - gAgentCamera.getOrbitLeftKey() > 0.f, // right - gAgentCamera.getOrbitDownKey() > 0.f); // bottom - - camera_floater->mTrack->setToggleState(gAgentCamera.getPanLeftKey() > 0.f, // left - gAgentCamera.getPanUpKey() > 0.f, // top - gAgentCamera.getPanRightKey() > 0.f, // right - gAgentCamera.getPanDownKey() > 0.f); // bottom - } - - // Handle camera movement based on keyboard. - const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second - const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second - const F32 PAN_RATE = 5.f; // meters per second - - if (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey()) - { - F32 input_rate = gAgentCamera.getOrbitUpKey() - gAgentCamera.getOrbitDownKey(); - cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped ); - } - - if (gAgentCamera.getOrbitLeftKey() || gAgentCamera.getOrbitRightKey()) - { - F32 input_rate = gAgentCamera.getOrbitLeftKey() - gAgentCamera.getOrbitRightKey(); - cameraOrbitAround(input_rate * ORBIT_AROUND_RATE / gFPSClamped); - } - - if (gAgentCamera.getOrbitInKey() || gAgentCamera.getOrbitOutKey()) - { - F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey(); - - LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal(); - F32 distance_to_focus = (F32)to_focus.magVec(); - // Move at distance (in meters) meters per second - cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped ); - } - - if (gAgentCamera.getPanInKey() || gAgentCamera.getPanOutKey()) - { - F32 input_rate = gAgentCamera.getPanInKey() - gAgentCamera.getPanOutKey(); - cameraPanIn(input_rate * PAN_RATE / gFPSClamped); - } - - if (gAgentCamera.getPanRightKey() || gAgentCamera.getPanLeftKey()) - { - F32 input_rate = gAgentCamera.getPanRightKey() - gAgentCamera.getPanLeftKey(); - cameraPanLeft(input_rate * -PAN_RATE / gFPSClamped ); - } - - if (gAgentCamera.getPanUpKey() || gAgentCamera.getPanDownKey()) - { - F32 input_rate = gAgentCamera.getPanUpKey() - gAgentCamera.getPanDownKey(); - cameraPanUp(input_rate * PAN_RATE / gFPSClamped ); - } - - // Clear camera keyboard keys. - gAgentCamera.clearOrbitKeys(); - gAgentCamera.clearPanKeys(); - - // lerp camera focus offset - mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); - - if ( mCameraMode == CAMERA_MODE_FOLLOW ) - { - if (isAgentAvatarValid()) - { - //-------------------------------------------------------------------------------- - // this is where the avatar's position and rotation are given to followCam, and - // where it is updated. All three of its attributes are updated: (1) position, - // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent. - //-------------------------------------------------------------------------------- - // *TODO: use combined rotation of frameagent and sit object - LLQuaternion avatarRotationForFollowCam = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); - - LLFollowCamParams* current_cam = LLFollowCamMgr::getInstance()->getActiveFollowCamParams(); - if (current_cam) - { - mFollowCam.copyParams(*current_cam); - mFollowCam.setSubjectPositionAndRotation( gAgentAvatarp->getRenderPosition(), avatarRotationForFollowCam ); - mFollowCam.update(); - LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); - } - else - { - changeCameraToThirdPerson(TRUE); - } - } - } - - BOOL hit_limit; - LLVector3d camera_pos_global; - LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit); - mCameraVirtualPositionAgent = gAgent.getPosAgentFromGlobal(camera_target_global); - LLVector3d focus_target_global = calcFocusPositionTargetGlobal(); - - // perform field of view correction - mCameraFOVZoomFactor = calcCameraFOVZoomFactor(); - camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor); - - gAgent.setShowAvatar(TRUE); // can see avatar by default - - // Adjust position for animation - if (mCameraAnimating) - { - F32 time = mAnimationTimer.getElapsedTimeF32(); - - // yet another instance of critically damped motion, hooray! - // F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE); - - // linear interpolation - F32 fraction_of_animation = time / mAnimationDuration; - - BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK; - BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK; - F32 fraction_animation_to_skip; - - if (mAnimationCameraStartGlobal == camera_target_global) - { - fraction_animation_to_skip = 0.f; - } - else - { - LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global; - fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec(); - } - F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f; - F32 animation_finish_fraction = (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f; - - if (fraction_of_animation < animation_finish_fraction) - { - if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction ) - { - gAgent.setShowAvatar(FALSE); - } - - // ...adjust position for animation - F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation); - camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation); - mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation); - } - else - { - // ...animation complete - mCameraAnimating = FALSE; - - camera_pos_global = camera_target_global; - mFocusGlobal = focus_target_global; - - gAgent.endAnimationUpdateUI(); - gAgent.setShowAvatar(TRUE); - } - - if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK)) - { - gAgentAvatarp->updateAttachmentVisibility(mCameraMode); - } - } - else - { - camera_pos_global = camera_target_global; - mFocusGlobal = focus_target_global; - gAgent.setShowAvatar(TRUE); - } - - // smoothing - if (TRUE) - { - LLVector3d agent_pos = gAgent.getPositionGlobal(); - LLVector3d camera_pos_agent = camera_pos_global - agent_pos; - // Sitting on what you're manipulating can cause camera jitter with smoothing. - // This turns off smoothing while editing. -MG - bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); - mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode; - - if (cameraThirdPerson() && !mCameraSmoothingStop) - { - const F32 SMOOTHING_HALF_LIFE = 0.02f; - - F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); - - if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode - { - // for avatar-relative focus, we smooth in avatar space - - // the avatar moves too jerkily w/r/t global space to smooth there. - - LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent; - if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please - { - camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing); - camera_pos_global = camera_pos_agent + agent_pos; - } - } - else - { - LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal; - if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please - { - camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing); - } - } - } - - mCameraSmoothingLastPositionGlobal = camera_pos_global; - mCameraSmoothingLastPositionAgent = camera_pos_agent; - mCameraSmoothingStop = false; - } - - - mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE)); - -// LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL; - - LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal); - - mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global); - - // Move the camera - - LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent); - //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent); - - // Change FOV - LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor)); - - // follow camera when in customize mode - if (cameraCustomizeAvatar()) - { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent); - } - - // update the travel distance stat - // this isn't directly related to the camera - // but this seemed like the best place to do this - LLVector3d global_pos = gAgent.getPositionGlobal(); - if (!gAgent.getLastPositionGlobal().isExactlyZero()) - { - LLVector3d delta = global_pos - gAgent.getLastPositionGlobal(); - gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec()); - } - gAgent.setLastPositionGlobal(global_pos); - - if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook()) - { - LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() + - LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + - LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation(); - LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); - - LLJoint* torso_joint = gAgentAvatarp->mTorsop; - LLJoint* chest_joint = gAgentAvatarp->mChestp; - LLVector3 torso_scale = torso_joint->getScale(); - LLVector3 chest_scale = chest_joint->getScale(); - - // shorten avatar skeleton to avoid foot interpenetration - if (!gAgentAvatarp->mInAir) - { - LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation(); - F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f); - F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f); - torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor)); - - LLJoint* neck_joint = gAgentAvatarp->mNeckp; - LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation(); - scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f); - chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor)); - diff.mV[VZ] = 0.f; - } - - // SL-315 - gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); - - gAgentAvatarp->mRoot->updateWorldMatrixChildren(); - - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *attached_object = attachment_iter->get(); - if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull()) - { - // clear any existing "early" movements of attachment - attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE); - gPipeline.updateMoveNormalAsync(attached_object->mDrawable); - attached_object->updateText(); - } - } - } - - torso_joint->setScale(torso_scale); - chest_joint->setScale(chest_scale); - } + // - changed camera_skyward to the new global "mCameraUpVector" + mCameraUpVector = LLVector3::z_axis; + //LLVector3 camera_skyward(0.f, 0.f, 1.f); + + U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode; + + validateFocusObject(); + + if (isAgentAvatarValid() && + gAgentAvatarp->isSitting() && + camera_mode == CAMERA_MODE_MOUSELOOK) + { + //changed camera_skyward to the new global "mCameraUpVector" + mCameraUpVector = mCameraUpVector * gAgentAvatarp->getRenderRotation(); + } + + if (cameraThirdPerson() && (mFocusOnAvatar || mAllowChangeToFollow) && LLFollowCamMgr::getInstance()->getActiveFollowCamParams()) + { + mAllowChangeToFollow = FALSE; + mFocusOnAvatar = TRUE; + changeCameraToFollow(); + } + + //NOTE - this needs to be integrated into a general upVector system here within llAgent. + if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar ) + { + mCameraUpVector = mFollowCam.getUpVector(); + } + + if (mSitCameraEnabled) + { + if (mSitCameraReferenceObject->isDead()) + { + setSitCamera(LLUUID::null); + } + } + + // Update UI with our camera inputs + LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance("camera"); + if (camera_floater) + { + camera_floater->mRotate->setToggleState(gAgentCamera.getOrbitRightKey() > 0.f, // left + gAgentCamera.getOrbitUpKey() > 0.f, // top + gAgentCamera.getOrbitLeftKey() > 0.f, // right + gAgentCamera.getOrbitDownKey() > 0.f); // bottom + + camera_floater->mTrack->setToggleState(gAgentCamera.getPanLeftKey() > 0.f, // left + gAgentCamera.getPanUpKey() > 0.f, // top + gAgentCamera.getPanRightKey() > 0.f, // right + gAgentCamera.getPanDownKey() > 0.f); // bottom + } + + // Handle camera movement based on keyboard. + const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second + const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second + const F32 PAN_RATE = 5.f; // meters per second + + if (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey()) + { + F32 input_rate = gAgentCamera.getOrbitUpKey() - gAgentCamera.getOrbitDownKey(); + cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped ); + } + + if (gAgentCamera.getOrbitLeftKey() || gAgentCamera.getOrbitRightKey()) + { + F32 input_rate = gAgentCamera.getOrbitLeftKey() - gAgentCamera.getOrbitRightKey(); + cameraOrbitAround(input_rate * ORBIT_AROUND_RATE / gFPSClamped); + } + + if (gAgentCamera.getOrbitInKey() || gAgentCamera.getOrbitOutKey()) + { + F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey(); + + LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal(); + F32 distance_to_focus = (F32)to_focus.magVec(); + // Move at distance (in meters) meters per second + cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped ); + } + + if (gAgentCamera.getPanInKey() || gAgentCamera.getPanOutKey()) + { + F32 input_rate = gAgentCamera.getPanInKey() - gAgentCamera.getPanOutKey(); + cameraPanIn(input_rate * PAN_RATE / gFPSClamped); + } + + if (gAgentCamera.getPanRightKey() || gAgentCamera.getPanLeftKey()) + { + F32 input_rate = gAgentCamera.getPanRightKey() - gAgentCamera.getPanLeftKey(); + cameraPanLeft(input_rate * -PAN_RATE / gFPSClamped ); + } + + if (gAgentCamera.getPanUpKey() || gAgentCamera.getPanDownKey()) + { + F32 input_rate = gAgentCamera.getPanUpKey() - gAgentCamera.getPanDownKey(); + cameraPanUp(input_rate * PAN_RATE / gFPSClamped ); + } + + // Clear camera keyboard keys. + gAgentCamera.clearOrbitKeys(); + gAgentCamera.clearPanKeys(); + + // lerp camera focus offset + mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); + + if ( mCameraMode == CAMERA_MODE_FOLLOW ) + { + if (isAgentAvatarValid()) + { + //-------------------------------------------------------------------------------- + // this is where the avatar's position and rotation are given to followCam, and + // where it is updated. All three of its attributes are updated: (1) position, + // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent. + //-------------------------------------------------------------------------------- + // *TODO: use combined rotation of frameagent and sit object + LLQuaternion avatarRotationForFollowCam = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); + + LLFollowCamParams* current_cam = LLFollowCamMgr::getInstance()->getActiveFollowCamParams(); + if (current_cam) + { + mFollowCam.copyParams(*current_cam); + mFollowCam.setSubjectPositionAndRotation( gAgentAvatarp->getRenderPosition(), avatarRotationForFollowCam ); + mFollowCam.update(); + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); + } + else + { + changeCameraToThirdPerson(TRUE); + } + } + } + + BOOL hit_limit; + LLVector3d camera_pos_global; + LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit); + mCameraVirtualPositionAgent = gAgent.getPosAgentFromGlobal(camera_target_global); + LLVector3d focus_target_global = calcFocusPositionTargetGlobal(); + + // perform field of view correction + mCameraFOVZoomFactor = calcCameraFOVZoomFactor(); + camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor); + + gAgent.setShowAvatar(TRUE); // can see avatar by default + + // Adjust position for animation + if (mCameraAnimating) + { + F32 time = mAnimationTimer.getElapsedTimeF32(); + + // yet another instance of critically damped motion, hooray! + // F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE); + + // linear interpolation + F32 fraction_of_animation = time / mAnimationDuration; + + BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK; + BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK; + F32 fraction_animation_to_skip; + + if (mAnimationCameraStartGlobal == camera_target_global) + { + fraction_animation_to_skip = 0.f; + } + else + { + LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global; + fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec(); + } + F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f; + F32 animation_finish_fraction = (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f; + + if (fraction_of_animation < animation_finish_fraction) + { + if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction ) + { + gAgent.setShowAvatar(FALSE); + } + + // ...adjust position for animation + F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation); + camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation); + mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation); + } + else + { + // ...animation complete + mCameraAnimating = FALSE; + + camera_pos_global = camera_target_global; + mFocusGlobal = focus_target_global; + + gAgent.endAnimationUpdateUI(); + gAgent.setShowAvatar(TRUE); + } + + if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK)) + { + gAgentAvatarp->updateAttachmentVisibility(mCameraMode); + } + } + else + { + camera_pos_global = camera_target_global; + mFocusGlobal = focus_target_global; + gAgent.setShowAvatar(TRUE); + } + + // smoothing + if (TRUE) + { + LLVector3d agent_pos = gAgent.getPositionGlobal(); + LLVector3d camera_pos_agent = camera_pos_global - agent_pos; + // Sitting on what you're manipulating can cause camera jitter with smoothing. + // This turns off smoothing while editing. -MG + bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); + mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode; + + if (cameraThirdPerson() && !mCameraSmoothingStop) + { + const F32 SMOOTHING_HALF_LIFE = 0.02f; + + F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); + + if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode + { + // for avatar-relative focus, we smooth in avatar space - + // the avatar moves too jerkily w/r/t global space to smooth there. + + LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent; + if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please + { + camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing); + camera_pos_global = camera_pos_agent + agent_pos; + } + } + else + { + LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal; + if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please + { + camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing); + } + } + } + + mCameraSmoothingLastPositionGlobal = camera_pos_global; + mCameraSmoothingLastPositionAgent = camera_pos_agent; + mCameraSmoothingStop = false; + } + + + mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE)); + +// LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL; + + LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal); + + mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global); + + // Move the camera + + LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent); + //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent); + + // Change FOV + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor)); + + // follow camera when in customize mode + if (cameraCustomizeAvatar()) + { + setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent); + } + + // update the travel distance stat + // this isn't directly related to the camera + // but this seemed like the best place to do this + LLVector3d global_pos = gAgent.getPositionGlobal(); + if (!gAgent.getLastPositionGlobal().isExactlyZero()) + { + LLVector3d delta = global_pos - gAgent.getLastPositionGlobal(); + gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec()); + } + gAgent.setLastPositionGlobal(global_pos); + + if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook()) + { + LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() + + LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + + LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation(); + LLVector3 diff = mCameraPositionAgent - head_pos; + diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); + + LLJoint* torso_joint = gAgentAvatarp->mTorsop; + LLJoint* chest_joint = gAgentAvatarp->mChestp; + LLVector3 torso_scale = torso_joint->getScale(); + LLVector3 chest_scale = chest_joint->getScale(); + + // shorten avatar skeleton to avoid foot interpenetration + if (!gAgentAvatarp->mInAir) + { + LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation(); + F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f); + F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f); + torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor)); + + LLJoint* neck_joint = gAgentAvatarp->mNeckp; + LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation(); + scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f); + chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor)); + diff.mV[VZ] = 0.f; + } + + // SL-315 + gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); + + gAgentAvatarp->mRoot->updateWorldMatrixChildren(); + + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = attachment_iter->get(); + if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull()) + { + // clear any existing "early" movements of attachment + attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE); + gPipeline.updateMoveNormalAsync(attached_object->mDrawable); + attached_object->updateText(); + } + } + } + + torso_joint->setScale(torso_scale); + chest_joint->setScale(chest_scale); + } } void LLAgentCamera::updateLastCamera() { - mLastCameraMode = mCameraMode; + mLastCameraMode = mCameraMode; } void LLAgentCamera::updateFocusOffset() { - validateFocusObject(); - if (mFocusObject.notNull()) - { - LLVector3d obj_pos = gAgent.getPosGlobalFromAgent(mFocusObject->getRenderPosition()); - mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos); - } + validateFocusObject(); + if (mFocusObject.notNull()) + { + LLVector3d obj_pos = gAgent.getPosGlobalFromAgent(mFocusObject->getRenderPosition()); + mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos); + } } void LLAgentCamera::validateFocusObject() { - if (mFocusObject.notNull() && - mFocusObject->isDead()) - { - mFocusObjectOffset.clearVec(); - clearFocusObject(); - mCameraFOVZoomFactor = 0.f; - } + if (mFocusObject.notNull() && + mFocusObject->isDead()) + { + mFocusObjectOffset.clearVec(); + clearFocusObject(); + mCameraFOVZoomFactor = 0.f; + } } //----------------------------------------------------------------------------- @@ -1580,124 +1580,124 @@ void LLAgentCamera::validateFocusObject() //----------------------------------------------------------------------------- LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal() { - if (mFocusObject.notNull() && mFocusObject->isDead()) - { - clearFocusObject(); - } - - if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) - { - mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus()); - return mFocusTargetGlobal; - } - else if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - LLVector3d at_axis(1.0, 0.0, 0.0); - LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); - if (isAgentAvatarValid() && gAgentAvatarp->getParent()) - { - LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot(); - if (!root_object->flagCameraDecoupled()) - { - agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); - } - } - at_axis = at_axis * agent_rot; - mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis; - return mFocusTargetGlobal; - } - else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR) - { - if (mFocusOnAvatar) - { - LLVector3 focus_target = isAgentAvatarValid() - ? gAgentAvatarp->mHeadp->getWorldPosition() - : gAgent.getPositionAgent(); - LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); - mFocusTargetGlobal = focus_target_global; - } - return mFocusTargetGlobal; - } - else if (!mFocusOnAvatar) - { - if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull()) - { - LLDrawable* drawablep = mFocusObject->mDrawable; - - if (mTrackFocusObject && - drawablep && - drawablep->isActive()) - { - if (!mFocusObject->isAvatar()) - { - if (mFocusObject->isSelected()) - { - gPipeline.updateMoveNormalAsync(drawablep); - } - else - { - if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) - { - gPipeline.updateMoveNormalAsync(drawablep); - } - else - { - gPipeline.updateMoveDampedAsync(drawablep); - } - } - } - } - // if not tracking object, update offset based on new object position - else - { - updateFocusOffset(); - } - LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset; - mFocusTargetGlobal.setVec(gAgent.getPosGlobalFromAgent(focus_agent)); - } - return mFocusTargetGlobal; - } - else if (mSitCameraEnabled && isAgentAvatarValid() && gAgentAvatarp->isSitting() && mSitCameraReferenceObject.notNull()) - { - // sit camera - LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); - LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation(); - - LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot); - return gAgent.getPosGlobalFromAgent(target_pos); - } - else - { - return gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(); - } + if (mFocusObject.notNull() && mFocusObject->isDead()) + { + clearFocusObject(); + } + + if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus()); + return mFocusTargetGlobal; + } + else if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + LLVector3d at_axis(1.0, 0.0, 0.0); + LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); + if (isAgentAvatarValid() && gAgentAvatarp->getParent()) + { + LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot(); + if (!root_object->flagCameraDecoupled()) + { + agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); + } + } + at_axis = at_axis * agent_rot; + mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis; + return mFocusTargetGlobal; + } + else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR) + { + if (mFocusOnAvatar) + { + LLVector3 focus_target = isAgentAvatarValid() + ? gAgentAvatarp->mHeadp->getWorldPosition() + : gAgent.getPositionAgent(); + LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); + mFocusTargetGlobal = focus_target_global; + } + return mFocusTargetGlobal; + } + else if (!mFocusOnAvatar) + { + if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull()) + { + LLDrawable* drawablep = mFocusObject->mDrawable; + + if (mTrackFocusObject && + drawablep && + drawablep->isActive()) + { + if (!mFocusObject->isAvatar()) + { + if (mFocusObject->isSelected()) + { + gPipeline.updateMoveNormalAsync(drawablep); + } + else + { + if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) + { + gPipeline.updateMoveNormalAsync(drawablep); + } + else + { + gPipeline.updateMoveDampedAsync(drawablep); + } + } + } + } + // if not tracking object, update offset based on new object position + else + { + updateFocusOffset(); + } + LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset; + mFocusTargetGlobal.setVec(gAgent.getPosGlobalFromAgent(focus_agent)); + } + return mFocusTargetGlobal; + } + else if (mSitCameraEnabled && isAgentAvatarValid() && gAgentAvatarp->isSitting() && mSitCameraReferenceObject.notNull()) + { + // sit camera + LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); + LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation(); + + LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot); + return gAgent.getPosGlobalFromAgent(target_pos); + } + else + { + return gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(); + } } LLVector3d LLAgentCamera::calcThirdPersonFocusOffset() { - // ...offset from avatar - LLVector3d focus_offset; - LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); - if (isAgentAvatarValid() && gAgentAvatarp->getParent()) - { - agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); - } + // ...offset from avatar + LLVector3d focus_offset; + LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); + if (isAgentAvatarValid() && gAgentAvatarp->getParent()) + { + agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); + } static LLCachedControl focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d()); - return focus_offset_initial * agent_rot; + return focus_offset_initial * agent_rot; } void LLAgentCamera::setupSitCamera() { - // agent frame entering this function is in world coordinates - if (isAgentAvatarValid() && gAgentAvatarp->getParent()) - { - LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation(); - // slam agent coordinate frame to proper parent local version - LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - gAgent.resetAxes(at_axis * ~parent_rot); - } + // agent frame entering this function is in world coordinates + if (isAgentAvatarValid() && gAgentAvatarp->getParent()) + { + LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation(); + // slam agent coordinate frame to proper parent local version + LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~parent_rot); + } } //----------------------------------------------------------------------------- @@ -1705,7 +1705,7 @@ void LLAgentCamera::setupSitCamera() //----------------------------------------------------------------------------- const LLVector3 &LLAgentCamera::getCameraPositionAgent() const { - return LLViewerCamera::getInstance()->getOrigin(); + return LLViewerCamera::getInstance()->getOrigin(); } //----------------------------------------------------------------------------- @@ -1713,39 +1713,39 @@ const LLVector3 &LLAgentCamera::getCameraPositionAgent() const //----------------------------------------------------------------------------- LLVector3d LLAgentCamera::getCameraPositionGlobal() const { - return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); + return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); } //----------------------------------------------------------------------------- // calcCameraFOVZoomFactor() //----------------------------------------------------------------------------- -F32 LLAgentCamera::calcCameraFOVZoomFactor() +F32 LLAgentCamera::calcCameraFOVZoomFactor() { - LLVector3 camera_offset_dir; - camera_offset_dir.setVec(mCameraFocusOffset); + LLVector3 camera_offset_dir; + camera_offset_dir.setVec(mCameraFocusOffset); - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - return 0.f; - } - else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar) - { - // don't FOV zoom on mostly transparent objects - F32 obj_min_dist = 0.f; - calcCameraMinDistance(obj_min_dist); - F32 current_distance = llmax(0.001f, camera_offset_dir.magVec()); + if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + return 0.f; + } + else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar) + { + // don't FOV zoom on mostly transparent objects + F32 obj_min_dist = 0.f; + calcCameraMinDistance(obj_min_dist); + F32 current_distance = llmax(0.001f, camera_offset_dir.magVec()); - mFocusObjectDist = obj_min_dist - current_distance; + mFocusObjectDist = obj_min_dist - current_distance; - F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f); - return new_fov_zoom; - } - else // focusing on land or avatar - { - // keep old field of view until user changes focus explicitly - return mCameraFOVZoomFactor; - //return 0.f; - } + F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f); + return new_fov_zoom; + } + else // focusing on land or avatar + { + // keep old field of view until user changes focus explicitly + return mCameraFOVZoomFactor; + //return 0.f; + } } //----------------------------------------------------------------------------- @@ -1753,307 +1753,307 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor() //----------------------------------------------------------------------------- LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) { - // Compute base camera position and look-at points. - F32 camera_land_height; - LLVector3d frame_center_global = !isAgentAvatarValid() ? - gAgent.getPositionGlobal() : - gAgent.getPosGlobalFromAgent(getAvatarRootPosition()); - - BOOL isConstrained = FALSE; - LLVector3d head_offset; - head_offset.setVec(mThirdPersonHeadOffset); - - LLVector3d camera_position_global; - - if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) - { - camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition()); - } - else if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - if (!isAgentAvatarValid() || gAgentAvatarp->mDrawable.isNull()) - { - LL_WARNS() << "Null avatar drawable!" << LL_ENDL; - return LLVector3d::zero; - } - - head_offset.clearVec(); - F32 fixup; + // Compute base camera position and look-at points. + F32 camera_land_height; + LLVector3d frame_center_global = !isAgentAvatarValid() ? + gAgent.getPositionGlobal() : + gAgent.getPosGlobalFromAgent(getAvatarRootPosition()); + + BOOL isConstrained = FALSE; + LLVector3d head_offset; + head_offset.setVec(mThirdPersonHeadOffset); + + LLVector3d camera_position_global; + + if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) + { + camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition()); + } + else if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + if (!isAgentAvatarValid() || gAgentAvatarp->mDrawable.isNull()) + { + LL_WARNS() << "Null avatar drawable!" << LL_ENDL; + return LLVector3d::zero; + } + + head_offset.clearVec(); + F32 fixup; if (gAgentAvatarp->hasPelvisFixup(fixup) && !gAgentAvatarp->isSitting()) - { - head_offset[VZ] -= fixup; - } - if (gAgentAvatarp->isSitting()) - { - head_offset.mdV[VZ] += 0.1; - } - - if (gAgentAvatarp->isSitting() && gAgentAvatarp->getParent()) - { - gAgentAvatarp->updateHeadOffset(); - head_offset.mdV[VX] += gAgentAvatarp->mHeadOffset.mV[VX]; - head_offset.mdV[VY] += gAgentAvatarp->mHeadOffset.mV[VY]; - head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ]; - const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix(); - camera_position_global = gAgent.getPosGlobalFromAgent - ((gAgentAvatarp->getPosition()+ - LLVector3(head_offset)*gAgentAvatarp->getRotation()) * mat); - } - else - { - head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ]; - camera_position_global = gAgent.getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());//frame_center_global; - head_offset = head_offset * gAgentAvatarp->getRenderRotation(); - camera_position_global = camera_position_global + head_offset; - } - } - else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar) - { - LLVector3 local_camera_offset; - F32 camera_distance = 0.f; - - if (mSitCameraEnabled - && isAgentAvatarValid() - && gAgentAvatarp->isSitting() - && mSitCameraReferenceObject.notNull()) - { - // sit camera - LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); - LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation(); - - LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot); - - camera_position_global = gAgent.getPosGlobalFromAgent(target_pos); - } - else - { + { + head_offset[VZ] -= fixup; + } + if (gAgentAvatarp->isSitting()) + { + head_offset.mdV[VZ] += 0.1; + } + + if (gAgentAvatarp->isSitting() && gAgentAvatarp->getParent()) + { + gAgentAvatarp->updateHeadOffset(); + head_offset.mdV[VX] += gAgentAvatarp->mHeadOffset.mV[VX]; + head_offset.mdV[VY] += gAgentAvatarp->mHeadOffset.mV[VY]; + head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ]; + const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix(); + camera_position_global = gAgent.getPosGlobalFromAgent + ((gAgentAvatarp->getPosition()+ + LLVector3(head_offset)*gAgentAvatarp->getRotation()) * mat); + } + else + { + head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ]; + camera_position_global = gAgent.getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());//frame_center_global; + head_offset = head_offset * gAgentAvatarp->getRenderRotation(); + camera_position_global = camera_position_global + head_offset; + } + } + else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar) + { + LLVector3 local_camera_offset; + F32 camera_distance = 0.f; + + if (mSitCameraEnabled + && isAgentAvatarValid() + && gAgentAvatarp->isSitting() + && mSitCameraReferenceObject.notNull()) + { + // sit camera + LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); + LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation(); + + LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot); + + camera_position_global = gAgent.getPosGlobalFromAgent(target_pos); + } + else + { static LLCachedControl camera_offset_scale(gSavedSettings, "CameraOffsetScale"); local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * camera_offset_scale; - // are we sitting down? - if (isAgentAvatarValid() && gAgentAvatarp->getParent()) - { - LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation(); - // slam agent coordinate frame to proper parent local version - LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot; - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - gAgent.resetAxes(at_axis * ~parent_rot); - - local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot; - } - else - { - local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset ); - } - - if (!isDisableCameraConstraints() && !mCameraCollidePlane.isExactlyZero() && - (!isAgentAvatarValid() || !gAgentAvatarp->isSitting())) - { - LLVector3 plane_normal; - plane_normal.setVec(mCameraCollidePlane.mV); - - F32 offset_dot_norm = local_camera_offset * plane_normal; - if (llabs(offset_dot_norm) < 0.001f) - { - offset_dot_norm = 0.001f; - } - - camera_distance = local_camera_offset.normalize(); - - F32 pos_dot_norm = gAgent.getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal; - - // if agent is outside the colliding half-plane - if (pos_dot_norm > mCameraCollidePlane.mV[VW]) - { - // check to see if camera is on the opposite side (inside) the half-plane - if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW]) - { - // diminish offset by factor to push it back outside the half-plane - camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm; - } - } - else - { - if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW]) - { - camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm; - } - } - } - else - { - camera_distance = local_camera_offset.normalize(); - } - - mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE); - - if (mTargetCameraDistance != mCurrentCameraDistance) - { - F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE); - - mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt); - } - - // Make the camera distance current - local_camera_offset *= mCurrentCameraDistance; - - // set the global camera position - LLVector3d camera_offset; - - camera_offset.setVec( local_camera_offset ); - camera_position_global = frame_center_global + head_offset + camera_offset; - - if (isAgentAvatarValid()) - { - LLVector3d camera_lag_d; - F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE); - LLVector3 target_lag; - LLVector3 vel = gAgent.getVelocity(); - - // lag by appropriate amount for flying - F32 time_in_air = gAgentAvatarp->mTimeInAir.getElapsedTimeF32(); - if(!mCameraAnimating && gAgentAvatarp->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) - { - LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis(); - frame_at_axis -= projected_vec(frame_at_axis, gAgent.getReferenceUpVector()); - frame_at_axis.normalize(); - - //transition smoothly in air mode, to avoid camera pop - F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME; - u = llclamp(u, 0.f, 1.f); - - lag_interp *= u; - - if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgentAvatarp->getID()) - { - // disable camera lag when using mouse-directed steering - target_lag.clearVec(); - } - else - { - target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f; - } - - mCameraLag = lerp(mCameraLag, target_lag, lag_interp); - - F32 lag_dist = mCameraLag.magVec(); - if (lag_dist > MAX_CAMERA_LAG) - { - mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist; - } - - // clamp camera lag so that avatar is always in front - F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis; - if (dot < -(MIN_CAMERA_LAG * u)) - { - mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis; - } - } - else - { - mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f)); - } - - camera_lag_d.setVec(mCameraLag); - camera_position_global = camera_position_global - camera_lag_d; - } - } - } - else - { - LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal(); - // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value - camera_position_global = focusPosGlobal + mCameraFocusOffset; - } - - if (!isDisableCameraConstraints() && !gAgent.isGodlike()) - { - LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global); - bool constrain = true; - if(regionp && regionp->canManageEstate()) - { - constrain = false; - } - if(constrain) - { - F32 max_dist = (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) ? APPEARANCE_MAX_ZOOM : mDrawDistance; - - LLVector3d camera_offset = camera_position_global - gAgent.getPositionGlobal(); - F32 camera_distance = (F32)camera_offset.magVec(); - - if(camera_distance > max_dist) - { - camera_position_global = gAgent.getPositionGlobal() + (max_dist/camera_distance)*camera_offset; - isConstrained = TRUE; - } - } + // are we sitting down? + if (isAgentAvatarValid() && gAgentAvatarp->getParent()) + { + LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation(); + // slam agent coordinate frame to proper parent local version + LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot; + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~parent_rot); + + local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot; + } + else + { + local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset ); + } + + if (!isDisableCameraConstraints() && !mCameraCollidePlane.isExactlyZero() && + (!isAgentAvatarValid() || !gAgentAvatarp->isSitting())) + { + LLVector3 plane_normal; + plane_normal.setVec(mCameraCollidePlane.mV); + + F32 offset_dot_norm = local_camera_offset * plane_normal; + if (llabs(offset_dot_norm) < 0.001f) + { + offset_dot_norm = 0.001f; + } + + camera_distance = local_camera_offset.normalize(); + + F32 pos_dot_norm = gAgent.getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal; + + // if agent is outside the colliding half-plane + if (pos_dot_norm > mCameraCollidePlane.mV[VW]) + { + // check to see if camera is on the opposite side (inside) the half-plane + if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW]) + { + // diminish offset by factor to push it back outside the half-plane + camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm; + } + } + else + { + if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW]) + { + camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm; + } + } + } + else + { + camera_distance = local_camera_offset.normalize(); + } + + mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE); + + if (mTargetCameraDistance != mCurrentCameraDistance) + { + F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE); + + mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt); + } + + // Make the camera distance current + local_camera_offset *= mCurrentCameraDistance; + + // set the global camera position + LLVector3d camera_offset; + + camera_offset.setVec( local_camera_offset ); + camera_position_global = frame_center_global + head_offset + camera_offset; + + if (isAgentAvatarValid()) + { + LLVector3d camera_lag_d; + F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE); + LLVector3 target_lag; + LLVector3 vel = gAgent.getVelocity(); + + // lag by appropriate amount for flying + F32 time_in_air = gAgentAvatarp->mTimeInAir.getElapsedTimeF32(); + if(!mCameraAnimating && gAgentAvatarp->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) + { + LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis(); + frame_at_axis -= projected_vec(frame_at_axis, gAgent.getReferenceUpVector()); + frame_at_axis.normalize(); + + //transition smoothly in air mode, to avoid camera pop + F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME; + u = llclamp(u, 0.f, 1.f); + + lag_interp *= u; + + if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgentAvatarp->getID()) + { + // disable camera lag when using mouse-directed steering + target_lag.clearVec(); + } + else + { + target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f; + } + + mCameraLag = lerp(mCameraLag, target_lag, lag_interp); + + F32 lag_dist = mCameraLag.magVec(); + if (lag_dist > MAX_CAMERA_LAG) + { + mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist; + } + + // clamp camera lag so that avatar is always in front + F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis; + if (dot < -(MIN_CAMERA_LAG * u)) + { + mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis; + } + } + else + { + mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f)); + } + + camera_lag_d.setVec(mCameraLag); + camera_position_global = camera_position_global - camera_lag_d; + } + } + } + else + { + LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal(); + // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value + camera_position_global = focusPosGlobal + mCameraFocusOffset; + } + + if (!isDisableCameraConstraints() && !gAgent.isGodlike()) + { + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global); + bool constrain = true; + if(regionp && regionp->canManageEstate()) + { + constrain = false; + } + if(constrain) + { + F32 max_dist = (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) ? APPEARANCE_MAX_ZOOM : mDrawDistance; + + LLVector3d camera_offset = camera_position_global - gAgent.getPositionGlobal(); + F32 camera_distance = (F32)camera_offset.magVec(); + + if(camera_distance > max_dist) + { + camera_position_global = gAgent.getPositionGlobal() + (max_dist/camera_distance)*camera_offset; + isConstrained = TRUE; + } + } // JC - Could constrain camera based on parcel stuff here. -// LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global); -// -// if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global))) -// { -// camera_position_global = last_position_global; +// LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global); // -// isConstrained = TRUE; -// } - } +// if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global))) +// { +// camera_position_global = last_position_global; +// +// isConstrained = TRUE; +// } + } - // Don't let camera go underground - F32 camera_min_off_ground = getCameraMinOffGround(); - camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); - F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground); - if (camera_position_global.mdV[VZ] < minZ) - { - camera_position_global.mdV[VZ] = minZ; - isConstrained = TRUE; - } + // Don't let camera go underground + F32 camera_min_off_ground = getCameraMinOffGround(); + camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); + F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground); + if (camera_position_global.mdV[VZ] < minZ) + { + camera_position_global.mdV[VZ] = minZ; + isConstrained = TRUE; + } - if (hit_limit) - { - *hit_limit = isConstrained; - } + if (hit_limit) + { + *hit_limit = isConstrained; + } - return camera_position_global; + return camera_position_global; } LLVector3 LLAgentCamera::getCurrentCameraOffset() { - return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation(); + return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation(); } LLVector3d LLAgentCamera::getCurrentFocusOffset() { - return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation(); + return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation(); } LLQuaternion LLAgentCamera::getCurrentAvatarRotation() { - LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent(); - - LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); - LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; - return av_rot * obj_rot; + LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent(); + + LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); + LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; + return av_rot * obj_rot; } bool LLAgentCamera::isJoystickCameraUsed() { - return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull()); + return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull()); } LLVector3 LLAgentCamera::getCameraOffsetInitial() { // getCameraOffsetInitial and getFocusOffsetInitial can be called on update from idle before init() static LLCachedControl camera_offset_initial (gSavedSettings, "CameraOffsetRearView", LLVector3()); - return camera_offset_initial; + return camera_offset_initial; } LLVector3d LLAgentCamera::getFocusOffsetInitial() { static LLCachedControl focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d()); - return focus_offset_initial; + return focus_offset_initial; } F32 LLAgentCamera::getCameraMaxZoomDistance() @@ -2082,48 +2082,48 @@ LLVector3 LLAgentCamera::getAvatarRootPosition() //----------------------------------------------------------------------------- void LLAgentCamera::handleScrollWheel(S32 clicks) { - if (mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar()) - { - if (!mFollowCam.getPositionLocked()) // not if the followCam position is locked in place - { - mFollowCam.zoom(clicks); - if (mFollowCam.isZoomedToMinimumDistance()) - { - changeCameraToMouselook(FALSE); - } - } - } - else - { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2); - - // Block if camera is animating - if (mCameraAnimating) - { - return; - } - - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - F32 zoom_factor = (F32)pow(0.8, -clicks); - cameraZoomIn(zoom_factor); - } - else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON)) - { - F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec(); - - F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); - current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); - - cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); - } - else - { - F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec(); - cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks))); - } - } + if (mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar()) + { + if (!mFollowCam.getPositionLocked()) // not if the followCam position is locked in place + { + mFollowCam.zoom(clicks); + if (mFollowCam.isZoomedToMinimumDistance()) + { + changeCameraToMouselook(FALSE); + } + } + } + else + { + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2); + + // Block if camera is animating + if (mCameraAnimating) + { + return; + } + + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + F32 zoom_factor = (F32)pow(0.8, -clicks); + cameraZoomIn(zoom_factor); + } + else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON)) + { + F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec(); + + F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); + current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); + + cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); + } + else + { + F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec(); + cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks))); + } + } } @@ -2132,17 +2132,17 @@ void LLAgentCamera::handleScrollWheel(S32 clicks) //----------------------------------------------------------------------------- F32 LLAgentCamera::getCameraMinOffGround() { - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - return 0.f; - } + if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + return 0.f; + } - if (isDisableCameraConstraints()) - { - return -1000.f; - } + if (isDisableCameraConstraints()) + { + return -1000.f; + } - return 0.5f; + return 0.5f; } @@ -2151,15 +2151,15 @@ F32 LLAgentCamera::getCameraMinOffGround() //----------------------------------------------------------------------------- void LLAgentCamera::resetCamera() { - // Remove any pitch from the avatar - LLVector3 at = gAgent.getFrameAgent().getAtAxis(); - at.mV[VZ] = 0.f; - at.normalize(); - gAgent.resetAxes(at); - // have to explicitly clear field of view zoom now - mCameraFOVZoomFactor = 0.f; + // Remove any pitch from the avatar + LLVector3 at = gAgent.getFrameAgent().getAtAxis(); + at.mV[VZ] = 0.f; + at.normalize(); + gAgent.resetAxes(at); + // have to explicitly clear field of view zoom now + mCameraFOVZoomFactor = 0.f; - updateCamera(); + updateCamera(); } //----------------------------------------------------------------------------- @@ -2167,58 +2167,58 @@ void LLAgentCamera::resetCamera() //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToMouselook(BOOL animate) { - if (!gSavedSettings.getBOOL("EnableMouselook") - || LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - // visibility changes at end of animation - gViewerWindow->getWindow()->resetBusyCount(); - - // Menus should not remain open on switching to mouselook... - LLMenuGL::sMenuContainer->hideMenus(); - LLUI::getInstance()->clearPopups(); - - // unpause avatar animation - gAgent.unpauseAnimation(); - - LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); - - if (isAgentAvatarValid()) - { - gAgentAvatarp->stopMotion(ANIM_AGENT_BODY_NOISE); - gAgentAvatarp->stopMotion(ANIM_AGENT_BREATHE_ROT); - } - - //gViewerWindow->stopGrab(); - LLSelectMgr::getInstance()->deselectAll(); - gViewerWindow->hideCursor(); - gViewerWindow->moveCursorToCenter(); - - if (mCameraMode != CAMERA_MODE_MOUSELOOK) - { - gFocusMgr.setKeyboardFocus(NULL); - - updateLastCamera(); - mCameraMode = CAMERA_MODE_MOUSELOOK; - const U32 old_flags = gAgent.getControlFlags(); - gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != gAgent.getControlFlags()) - { - gAgent.setFlagsDirty(); - } - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - gAgent.endAnimationUpdateUI(); - } - } + if (!gSavedSettings.getBOOL("EnableMouselook") + || LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + // visibility changes at end of animation + gViewerWindow->getWindow()->resetBusyCount(); + + // Menus should not remain open on switching to mouselook... + LLMenuGL::sMenuContainer->hideMenus(); + LLUI::getInstance()->clearPopups(); + + // unpause avatar animation + gAgent.unpauseAnimation(); + + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); + + if (isAgentAvatarValid()) + { + gAgentAvatarp->stopMotion(ANIM_AGENT_BODY_NOISE); + gAgentAvatarp->stopMotion(ANIM_AGENT_BREATHE_ROT); + } + + //gViewerWindow->stopGrab(); + LLSelectMgr::getInstance()->deselectAll(); + gViewerWindow->hideCursor(); + gViewerWindow->moveCursorToCenter(); + + if (mCameraMode != CAMERA_MODE_MOUSELOOK) + { + gFocusMgr.setKeyboardFocus(NULL); + + updateLastCamera(); + mCameraMode = CAMERA_MODE_MOUSELOOK; + const U32 old_flags = gAgent.getControlFlags(); + gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK); + if (old_flags != gAgent.getControlFlags()) + { + gAgent.setFlagsDirty(); + } + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + } } @@ -2227,24 +2227,24 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToDefault() { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } - if (LLFollowCamMgr::getInstance()->getActiveFollowCamParams()) - { - changeCameraToFollow(); - } - else - { - changeCameraToThirdPerson(); - } - if (gSavedSettings.getBOOL("HideUIControls")) - { - gViewerWindow->setUIVisibility(false); - LLPanelStandStopFlying::getInstance()->setVisible(false); - } + if (LLFollowCamMgr::getInstance()->getActiveFollowCamParams()) + { + changeCameraToFollow(); + } + else + { + changeCameraToThirdPerson(); + } + if (gSavedSettings.getBOOL("HideUIControls")) + { + gViewerWindow->setUIVisibility(false); + LLPanelStandStopFlying::getInstance()->setVisible(false); + } } @@ -2253,53 +2253,53 @@ void LLAgentCamera::changeCameraToDefault() //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToFollow(BOOL animate) { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - if(mCameraMode != CAMERA_MODE_FOLLOW) - { - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - animate = FALSE; - } - startCameraAnimation(); - - updateLastCamera(); - mCameraMode = CAMERA_MODE_FOLLOW; - - // bang-in the current focus, position, and up vector of the follow cam - mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis); - - if (gBasicToolset) - { - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - } - - if (isAgentAvatarValid()) - { - // SL-315 - gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); - gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); - gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT ); - } - - // unpause avatar animation - gAgent.unpauseAnimation(); - - gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - gAgent.endAnimationUpdateUI(); - } - } + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + if(mCameraMode != CAMERA_MODE_FOLLOW) + { + if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + animate = FALSE; + } + startCameraAnimation(); + + updateLastCamera(); + mCameraMode = CAMERA_MODE_FOLLOW; + + // bang-in the current focus, position, and up vector of the follow cam + mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis); + + if (gBasicToolset) + { + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } + + if (isAgentAvatarValid()) + { + // SL-315 + gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); + gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); + gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT ); + } + + // unpause avatar animation + gAgent.unpauseAnimation(); + + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + } } //----------------------------------------------------------------------------- @@ -2307,69 +2307,69 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - gViewerWindow->getWindow()->resetBusyCount(); - - mCameraZoomFraction = INITIAL_ZOOM_FRACTION; - - if (isAgentAvatarValid()) - { - if (!gAgentAvatarp->isSitting()) - { - // SL-315 - gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); - } - gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE); - gAgentAvatarp->startMotion(ANIM_AGENT_BREATHE_ROT); - } - - LLVector3 at_axis; - - // unpause avatar animation - gAgent.unpauseAnimation(); - - if (mCameraMode != CAMERA_MODE_THIRD_PERSON) - { - if (gBasicToolset) - { - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - } - - mCameraLag.clearVec(); - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - mCurrentCameraDistance = MIN_CAMERA_DISTANCE; - mTargetCameraDistance = MIN_CAMERA_DISTANCE; - animate = FALSE; - } - updateLastCamera(); - mCameraMode = CAMERA_MODE_THIRD_PERSON; - gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); - } - - // Remove any pitch from the avatar - if (!isAgentAvatarValid() || !gAgentAvatarp->getParent()) - { - at_axis = gAgent.getFrameAgent().getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - gAgent.resetAxes(at_axis); - } - - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - gAgent.endAnimationUpdateUI(); - } + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + gViewerWindow->getWindow()->resetBusyCount(); + + mCameraZoomFraction = INITIAL_ZOOM_FRACTION; + + if (isAgentAvatarValid()) + { + if (!gAgentAvatarp->isSitting()) + { + // SL-315 + gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); + } + gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE); + gAgentAvatarp->startMotion(ANIM_AGENT_BREATHE_ROT); + } + + LLVector3 at_axis; + + // unpause avatar animation + gAgent.unpauseAnimation(); + + if (mCameraMode != CAMERA_MODE_THIRD_PERSON) + { + if (gBasicToolset) + { + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } + + mCameraLag.clearVec(); + if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + mCurrentCameraDistance = MIN_CAMERA_DISTANCE; + mTargetCameraDistance = MIN_CAMERA_DISTANCE; + animate = FALSE; + } + updateLastCamera(); + mCameraMode = CAMERA_MODE_THIRD_PERSON; + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + } + + // Remove any pitch from the avatar + if (!isAgentAvatarValid() || !gAgentAvatarp->getParent()) + { + at_axis = gAgent.getFrameAgent().getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis); + } + + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } } //----------------------------------------------------------------------------- @@ -2377,89 +2377,89 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToCustomizeAvatar() { - if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid()) - { - return; - } + if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid()) + { + return; + } - gAgent.standUp(); // force stand up - gViewerWindow->getWindow()->resetBusyCount(); + gAgent.standUp(); // force stand up + gViewerWindow->getWindow()->resetBusyCount(); if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) { LLSelectMgr::getInstance()->deselectAll(); } - if (gFaceEditToolset) - { - LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); - } - - startCameraAnimation(); - - if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR) - { - updateLastCamera(); - mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR; - gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); - - gFocusMgr.setKeyboardFocus( NULL ); - gFocusMgr.setMouseCapture( NULL ); - if( gMorphView ) - { - gMorphView->setVisible( TRUE ); - } - // Remove any pitch or rotation from the avatar - LLVector3 at = gAgent.getAtAxis(); - at.mV[VZ] = 0.f; - at.normalize(); - gAgent.resetAxes(at); - - gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); - gAgent.setCustomAnim(TRUE); - gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); - LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); - - if (turn_motion) - { - // delay camera animation long enough to play through turn animation - setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); - } - } - - LLVector3 agent_at = gAgent.getAtAxis(); - agent_at.mV[VZ] = 0.f; - agent_at.normalize(); - - // default focus point for customize avatar - LLVector3 focus_target = isAgentAvatarValid() - ? gAgentAvatarp->mHeadp->getWorldPosition() - : gAgent.getPositionAgent(); - - LLVector3d camera_offset(agent_at * -1.0); - // push camera up and out from avatar - camera_offset.mdV[VZ] = 0.1f; - camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST; - LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); - setAnimationDuration(gSavedSettings.getF32("ZoomTime")); - setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID()); + if (gFaceEditToolset) + { + LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); + } + + startCameraAnimation(); + + if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR) + { + updateLastCamera(); + mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR; + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + + gFocusMgr.setKeyboardFocus( NULL ); + gFocusMgr.setMouseCapture( NULL ); + if( gMorphView ) + { + gMorphView->setVisible( TRUE ); + } + // Remove any pitch or rotation from the avatar + LLVector3 at = gAgent.getAtAxis(); + at.mV[VZ] = 0.f; + at.normalize(); + gAgent.resetAxes(at); + + gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); + gAgent.setCustomAnim(TRUE); + gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); + LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); + + if (turn_motion) + { + // delay camera animation long enough to play through turn animation + setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); + } + } + + LLVector3 agent_at = gAgent.getAtAxis(); + agent_at.mV[VZ] = 0.f; + agent_at.normalize(); + + // default focus point for customize avatar + LLVector3 focus_target = isAgentAvatarValid() + ? gAgentAvatarp->mHeadp->getWorldPosition() + : gAgent.getPositionAgent(); + + LLVector3d camera_offset(agent_at * -1.0); + // push camera up and out from avatar + camera_offset.mdV[VZ] = 0.1f; + camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST; + LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); + setAnimationDuration(gSavedSettings.getF32("ZoomTime")); + setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID()); } void LLAgentCamera::switchCameraPreset(ECameraPreset preset) { - //zoom is supposed to be reset for the front and group views - mCameraZoomFraction = 1.f; + //zoom is supposed to be reset for the front and group views + mCameraZoomFraction = 1.f; - //focusing on avatar in that case means following him on movements - mFocusOnAvatar = TRUE; + //focusing on avatar in that case means following him on movements + mFocusOnAvatar = TRUE; - mCameraPreset = preset; + mCameraPreset = preset; - resetPanDiff(); - resetOrbitDiff(); + resetPanDiff(); + resetOrbitDiff(); - gSavedSettings.setU32("CameraPresetType", mCameraPreset); + gSavedSettings.setU32("CameraPresetType", mCameraPreset); } @@ -2468,17 +2468,17 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset) // void LLAgentCamera::setAnimationDuration(F32 duration) -{ - if (mCameraAnimating) - { - // do not cut any existing camera animation short - F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32()); - mAnimationDuration = llmax(duration, animation_left); - } - else - { - mAnimationDuration = duration; - } +{ + if (mCameraAnimating) + { + // do not cut any existing camera animation short + F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32()); + mAnimationDuration = llmax(duration, animation_left); + } + else + { + mAnimationDuration = duration; + } } //----------------------------------------------------------------------------- @@ -2486,11 +2486,11 @@ void LLAgentCamera::setAnimationDuration(F32 duration) //----------------------------------------------------------------------------- void LLAgentCamera::startCameraAnimation() { - mAnimationCameraStartGlobal = getCameraPositionGlobal(); - mAnimationFocusStartGlobal = mFocusGlobal; - setAnimationDuration(gSavedSettings.getF32("ZoomTime")); - mAnimationTimer.reset(); - mCameraAnimating = TRUE; + mAnimationCameraStartGlobal = getCameraPositionGlobal(); + mAnimationFocusStartGlobal = mFocusGlobal; + setAnimationDuration(gSavedSettings.getF32("ZoomTime")); + mAnimationTimer.reset(); + mCameraAnimating = TRUE; } //----------------------------------------------------------------------------- @@ -2498,23 +2498,23 @@ void LLAgentCamera::startCameraAnimation() //----------------------------------------------------------------------------- void LLAgentCamera::stopCameraAnimation() { - mCameraAnimating = FALSE; + mCameraAnimating = FALSE; } void LLAgentCamera::clearFocusObject() { - if (mFocusObject.notNull()) - { - startCameraAnimation(); + if (mFocusObject.notNull()) + { + startCameraAnimation(); - setFocusObject(NULL); - mFocusObjectOffset.clearVec(); - } + setFocusObject(NULL); + mFocusObjectOffset.clearVec(); + } } void LLAgentCamera::setFocusObject(LLViewerObject* object) { - mFocusObject = object; + mFocusObject = object; } // Focus on a point, but try to keep camera position stable. @@ -2523,104 +2523,104 @@ void LLAgentCamera::setFocusObject(LLViewerObject* object) //----------------------------------------------------------------------------- void LLAgentCamera::setFocusGlobal(const LLPickInfo& pick) { - LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID); + LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID); - if (objectp && pick.mGLTFNodeIndex == -1) - { - // focus on object plus designated offset - // which may or may not be same as pick.mPosGlobal - setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID); - } - else - { - // focus directly on point where user clicked - setFocusGlobal(pick.mPosGlobal, pick.mObjectID); - } + if (objectp && pick.mGLTFNodeIndex == -1) + { + // focus on object plus designated offset + // which may or may not be same as pick.mPosGlobal + setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID); + } + else + { + // focus directly on point where user clicked + setFocusGlobal(pick.mPosGlobal, pick.mObjectID); + } } void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id) { - setFocusObject(gObjectList.findObject(object_id)); - LLVector3d old_focus = mFocusTargetGlobal; - LLViewerObject *focus_obj = mFocusObject; - - // if focus has changed - if (old_focus != focus) - { - if (focus.isExactlyZero()) - { - if (isAgentAvatarValid()) - { - mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition()); - } - else - { - mFocusTargetGlobal = gAgent.getPositionGlobal(); - } - mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal; - mCameraFocusOffset = mCameraFocusOffsetTarget; - setLookAt(LOOKAT_TARGET_CLEAR); - } - else - { - mFocusTargetGlobal = focus; - if (!focus_obj) - { - mCameraFOVZoomFactor = 0.f; - } - - mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal; - - startCameraAnimation(); - - if (focus_obj) - { - if (focus_obj->isAvatar()) - { - setLookAt(LOOKAT_TARGET_FOCUS, focus_obj); - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (gAgent.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation()); - } - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); - } - } - } - else // focus == mFocusTargetGlobal - { - if (focus.isExactlyZero()) - { - if (isAgentAvatarValid()) - { - mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition()); - } - else - { - mFocusTargetGlobal = gAgent.getPositionGlobal(); - } - } - mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);; - mCameraFocusOffset = mCameraFocusOffsetTarget; - } - - if (mFocusObject.notNull()) - { - // for attachments, make offset relative to avatar, not the attachment - if (mFocusObject->isAttachment()) - { - while (mFocusObject.notNull() && !mFocusObject->isAvatar()) - { - mFocusObject = (LLViewerObject*) mFocusObject->getParent(); - } - setFocusObject((LLViewerObject*)mFocusObject); - } - updateFocusOffset(); - } + setFocusObject(gObjectList.findObject(object_id)); + LLVector3d old_focus = mFocusTargetGlobal; + LLViewerObject *focus_obj = mFocusObject; + + // if focus has changed + if (old_focus != focus) + { + if (focus.isExactlyZero()) + { + if (isAgentAvatarValid()) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition()); + } + else + { + mFocusTargetGlobal = gAgent.getPositionGlobal(); + } + mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal; + mCameraFocusOffset = mCameraFocusOffsetTarget; + setLookAt(LOOKAT_TARGET_CLEAR); + } + else + { + mFocusTargetGlobal = focus; + if (!focus_obj) + { + mCameraFOVZoomFactor = 0.f; + } + + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal; + + startCameraAnimation(); + + if (focus_obj) + { + if (focus_obj->isAvatar()) + { + setLookAt(LOOKAT_TARGET_FOCUS, focus_obj); + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (gAgent.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation()); + } + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); + } + } + } + else // focus == mFocusTargetGlobal + { + if (focus.isExactlyZero()) + { + if (isAgentAvatarValid()) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition()); + } + else + { + mFocusTargetGlobal = gAgent.getPositionGlobal(); + } + } + mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);; + mCameraFocusOffset = mCameraFocusOffsetTarget; + } + + if (mFocusObject.notNull()) + { + // for attachments, make offset relative to avatar, not the attachment + if (mFocusObject->isAttachment()) + { + while (mFocusObject.notNull() && !mFocusObject->isAvatar()) + { + mFocusObject = (LLViewerObject*) mFocusObject->getParent(); + } + setFocusObject((LLViewerObject*)mFocusObject); + } + updateFocusOffset(); + } } // Used for avatar customization @@ -2629,48 +2629,48 @@ void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object //----------------------------------------------------------------------------- void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id) { - LLVector3d old_focus = mFocusTargetGlobal.isExactlyZero() ? focus : mFocusTargetGlobal; - - F64 focus_delta_squared = (old_focus - focus).magVecSquared(); - const F64 ANIM_EPSILON_SQUARED = 0.0001; - if (focus_delta_squared > ANIM_EPSILON_SQUARED) - { - startCameraAnimation(); - } - - //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) ); - setFocusObject(gObjectList.findObject(object_id)); - mFocusTargetGlobal = focus; - mCameraFocusOffsetTarget = camera_pos - focus; - mCameraFocusOffset = mCameraFocusOffsetTarget; - - if (mFocusObject) - { - if (mFocusObject->isAvatar()) - { - setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject); - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (gAgent.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation()); - } - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); - } - - if (mCameraAnimating) - { - const F64 ANIM_METERS_PER_SECOND = 10.0; - const F64 MIN_ANIM_SECONDS = 0.5; - const F64 MAX_ANIM_SECONDS = 10.0; - F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND ); - anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS ); - setAnimationDuration( (F32)anim_duration ); - } - - updateFocusOffset(); + LLVector3d old_focus = mFocusTargetGlobal.isExactlyZero() ? focus : mFocusTargetGlobal; + + F64 focus_delta_squared = (old_focus - focus).magVecSquared(); + const F64 ANIM_EPSILON_SQUARED = 0.0001; + if (focus_delta_squared > ANIM_EPSILON_SQUARED) + { + startCameraAnimation(); + } + + //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) ); + setFocusObject(gObjectList.findObject(object_id)); + mFocusTargetGlobal = focus; + mCameraFocusOffsetTarget = camera_pos - focus; + mCameraFocusOffset = mCameraFocusOffsetTarget; + + if (mFocusObject) + { + if (mFocusObject->isAvatar()) + { + setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject); + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (gAgent.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation()); + } + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); + } + + if (mCameraAnimating) + { + const F64 ANIM_METERS_PER_SECOND = 10.0; + const F64 MIN_ANIM_SECONDS = 0.5; + const F64 MAX_ANIM_SECONDS = 10.0; + F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND ); + anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS ); + setAnimationDuration( (F32)anim_duration ); + } + + updateFocusOffset(); } //----------------------------------------------------------------------------- @@ -2678,27 +2678,27 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con //----------------------------------------------------------------------------- void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus) { - BOOL camera_enabled = !object_id.isNull(); - - if (camera_enabled) - { - LLViewerObject *reference_object = gObjectList.findObject(object_id); - if (reference_object) - { - //convert to root object relative? - mSitCameraPos = camera_pos; - mSitCameraFocus = camera_focus; - mSitCameraReferenceObject = reference_object; - mSitCameraEnabled = TRUE; - } - } - else - { - mSitCameraPos.clearVec(); - mSitCameraFocus.clearVec(); - mSitCameraReferenceObject = NULL; - mSitCameraEnabled = FALSE; - } + BOOL camera_enabled = !object_id.isNull(); + + if (camera_enabled) + { + LLViewerObject *reference_object = gObjectList.findObject(object_id); + if (reference_object) + { + //convert to root object relative? + mSitCameraPos = camera_pos; + mSitCameraFocus = camera_focus; + mSitCameraReferenceObject = reference_object; + mSitCameraEnabled = TRUE; + } + } + else + { + mSitCameraPos.clearVec(); + mSitCameraFocus.clearVec(); + mSitCameraReferenceObject = NULL; + mSitCameraEnabled = FALSE; + } } //----------------------------------------------------------------------------- @@ -2706,30 +2706,30 @@ void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camer //----------------------------------------------------------------------------- void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL reset_axes) { - if (focus_on_avatar != mFocusOnAvatar) - { - if (animate) - { - startCameraAnimation(); - } - else - { - stopCameraAnimation(); - } - } - - //RN: when focused on the avatar, we're not "looking" at it - // looking implies intent while focusing on avatar means - // you're just walking around with a camera on you...eesh. - if (!mFocusOnAvatar && focus_on_avatar && reset_axes) - { - setFocusGlobal(LLVector3d::zero); - mCameraFOVZoomFactor = 0.f; - if (mCameraMode == CAMERA_MODE_THIRD_PERSON) - { - LLVector3 at_axis; - if (!isAgentAvatarValid() || !gAgentAvatarp->getParent()) - { + if (focus_on_avatar != mFocusOnAvatar) + { + if (animate) + { + startCameraAnimation(); + } + else + { + stopCameraAnimation(); + } + } + + //RN: when focused on the avatar, we're not "looking" at it + // looking implies intent while focusing on avatar means + // you're just walking around with a camera on you...eesh. + if (!mFocusOnAvatar && focus_on_avatar && reset_axes) + { + setFocusGlobal(LLVector3d::zero); + mCameraFOVZoomFactor = 0.f; + if (mCameraMode == CAMERA_MODE_THIRD_PERSON) + { + LLVector3 at_axis; + if (!isAgentAvatarValid() || !gAgentAvatarp->getParent()) + { // In case of front view rotate agent to look into direction opposite to camera // In case of rear view rotate agent into diraction same as camera, e t c LLVector3 vect = getCameraOffsetInitial(); @@ -2743,44 +2743,44 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL re at_axis.normalize(); gAgent.resetAxes(at_axis); gAgent.yaw(0); - } - } - } - // unlocking camera from avatar - else if (mFocusOnAvatar && !focus_on_avatar) - { - // keep camera focus point consistent, even though it is now unlocked - setFocusGlobal(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID()); - mAllowChangeToFollow = FALSE; - } - - mFocusOnAvatar = focus_on_avatar; + } + } + } + // unlocking camera from avatar + else if (mFocusOnAvatar && !focus_on_avatar) + { + // keep camera focus point consistent, even though it is now unlocked + setFocusGlobal(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID()); + mAllowChangeToFollow = FALSE; + } + + mFocusOnAvatar = focus_on_avatar; } BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) { - if(object && object->isAttachment()) - { - LLViewerObject* parent = object; - while(parent) - { - if (parent == gAgentAvatarp) - { - // looking at an attachment on ourselves, which we don't want to do - object = gAgentAvatarp; - position.clearVec(); - } - parent = (LLViewerObject*)parent->getParent(); - } - } - if(!mLookAt || mLookAt->isDead()) - { - mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); - mLookAt->setSourceObject(gAgentAvatarp); - } - - return mLookAt->setLookAt(target_type, object, position); + if(object && object->isAttachment()) + { + LLViewerObject* parent = object; + while(parent) + { + if (parent == gAgentAvatarp) + { + // looking at an attachment on ourselves, which we don't want to do + object = gAgentAvatarp; + position.clearVec(); + } + parent = (LLViewerObject*)parent->getParent(); + } + } + if(!mLookAt || mLookAt->isDead()) + { + mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); + mLookAt->setSourceObject(gAgentAvatarp); + } + + return mLookAt->setLookAt(target_type, object, position); } //----------------------------------------------------------------------------- @@ -2788,168 +2788,168 @@ BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, L //----------------------------------------------------------------------------- void LLAgentCamera::lookAtLastChat() { - // Block if camera is animating or not in normal third person camera mode - if (mCameraAnimating || !cameraThirdPerson()) - { - return; - } - - LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter()); - if (!chatter) - { - return; - } - - LLVector3 delta_pos; - if (chatter->isAvatar()) - { - LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; - if (isAgentAvatarValid() && chatter_av->mHeadp) - { - delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgentAvatarp->mHeadp->getWorldPosition(); - } - else - { - delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent(); - } - delta_pos.normalize(); - - gAgent.setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normalize(); - LLVector3 up = left % delta_pos; - up.normalize(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - - setFocusOnAvatar(FALSE, FALSE); - - if (chatter_av->mHeadp) - { - setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter()); - mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); - } - else - { - setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); - mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - } - } - else - { - delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent(); - delta_pos.normalize(); - - gAgent.setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normalize(); - LLVector3 up = left % delta_pos; - up.normalize(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - - setFocusOnAvatar(FALSE, FALSE); - - setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); - mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - } + // Block if camera is animating or not in normal third person camera mode + if (mCameraAnimating || !cameraThirdPerson()) + { + return; + } + + LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter()); + if (!chatter) + { + return; + } + + LLVector3 delta_pos; + if (chatter->isAvatar()) + { + LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; + if (isAgentAvatarValid() && chatter_av->mHeadp) + { + delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgentAvatarp->mHeadp->getWorldPosition(); + } + else + { + delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent(); + } + delta_pos.normalize(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normalize(); + LLVector3 up = left % delta_pos; + up.normalize(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + setFocusOnAvatar(FALSE, FALSE); + + if (chatter_av->mHeadp) + { + setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); + } + else + { + setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + } + } + else + { + delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent(); + delta_pos.normalize(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normalize(); + LLVector3 up = left % delta_pos; + up.normalize(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + setFocusOnAvatar(FALSE, FALSE); + + setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + } } bool LLAgentCamera::isfollowCamLocked() { - return mFollowCam.getPositionLocked(); + return mFollowCam.getPositionLocked(); } BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position) { - // disallow pointing at attachments and avatars - if (object && (object->isAttachment() || object->isAvatar())) - { - return FALSE; - } - if (!mPointAt || mPointAt->isDead()) - { - mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); - mPointAt->setSourceObject(gAgentAvatarp); - } - return mPointAt->setPointAt(target_type, object, position); + // disallow pointing at attachments and avatars + if (object && (object->isAttachment() || object->isAvatar())) + { + return FALSE; + } + if (!mPointAt || mPointAt->isDead()) + { + mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); + mPointAt->setSourceObject(gAgentAvatarp); + } + return mPointAt->setPointAt(target_type, object, position); } void LLAgentCamera::rotateToInitSitRot() { - gAgent.rotate(~gAgent.getFrameAgent().getQuaternion()); - gAgent.rotate(mInitSitRot); + gAgent.rotate(~gAgent.getFrameAgent().getQuaternion()); + gAgent.rotate(mInitSitRot); } void LLAgentCamera::resetCameraZoomFraction() -{ - mCameraZoomFraction = INITIAL_ZOOM_FRACTION; +{ + mCameraZoomFraction = INITIAL_ZOOM_FRACTION; } ELookAtType LLAgentCamera::getLookAtType() { - if (mLookAt) - { - return mLookAt->getLookAtType(); - } - return LOOKAT_TARGET_NONE; + if (mLookAt) + { + return mLookAt->getLookAtType(); + } + return LOOKAT_TARGET_NONE; } EPointAtType LLAgentCamera::getPointAtType() -{ - if (mPointAt) - { - return mPointAt->getPointAtType(); - } - return POINTAT_TARGET_NONE; +{ + if (mPointAt) + { + return mPointAt->getPointAtType(); + } + return POINTAT_TARGET_NONE; } void LLAgentCamera::clearGeneralKeys() { - mAtKey = 0; - mWalkKey = 0; - mLeftKey = 0; - mUpKey = 0; - mYawKey = 0.f; - mPitchKey = 0.f; + mAtKey = 0; + mWalkKey = 0; + mLeftKey = 0; + mUpKey = 0; + mYawKey = 0.f; + mPitchKey = 0.f; } void LLAgentCamera::clearOrbitKeys() { - mOrbitLeftKey = 0.f; - mOrbitRightKey = 0.f; - mOrbitUpKey = 0.f; - mOrbitDownKey = 0.f; - mOrbitInKey = 0.f; - mOrbitOutKey = 0.f; + mOrbitLeftKey = 0.f; + mOrbitRightKey = 0.f; + mOrbitUpKey = 0.f; + mOrbitDownKey = 0.f; + mOrbitInKey = 0.f; + mOrbitOutKey = 0.f; } void LLAgentCamera::clearPanKeys() { - mPanRightKey = 0.f; - mPanLeftKey = 0.f; - mPanUpKey = 0.f; - mPanDownKey = 0.f; - mPanInKey = 0.f; - mPanOutKey = 0.f; + mPanRightKey = 0.f; + mPanLeftKey = 0.f; + mPanUpKey = 0.f; + mPanDownKey = 0.f; + mPanInKey = 0.f; + mPanOutKey = 0.f; } // static S32 LLAgentCamera::directionToKey(S32 direction) { - if (direction > 0) return 1; - if (direction < 0) return -1; - return 0; + if (direction > 0) return 1; + if (direction < 0) return -1; + return 0; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 90f9b38f2d..617cd18e9f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -108,7 +108,7 @@ #include "llscenemonitor.h" #include "llavatarrenderinfoaccountant.h" #include "lllocalbitmaps.h" -#include "llperfstats.h" +#include "llperfstats.h" #include "llgltfmateriallist.h" // Linden library includes @@ -148,7 +148,7 @@ #include #if LL_WINDOWS -# include // For _SH_DENYWR in processMarkerFiles +# include // For _SH_DENYWR in processMarkerFiles #else # include // For processMarkerFiles #endif @@ -319,16 +319,16 @@ const char* gPlatform = LL_PLATFORM_KEY; LLSD gDebugInfo; -U32 gFrameCount = 0; +U32 gFrameCount = 0; U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground LLPumpIO* gServicePump = NULL; U64MicrosecondsImplicit gFrameTime = 0; F32SecondsImplicit gFrameTimeSeconds = 0.f; F32SecondsImplicit gFrameIntervalSeconds = 0.f; -F32 gFPSClamped = 10.f; // Pretend we start at target rate. -F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets -U64MicrosecondsImplicit gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds +F32 gFPSClamped = 10.f; // Pretend we start at target rate. +F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets +U64MicrosecondsImplicit gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds LLTimer gRenderStartTime; LLFrameTimer gForegroundTime; @@ -341,24 +341,24 @@ F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; S32 gPendingMetricsUploads = 0; -BOOL gDisconnected = FALSE; +BOOL gDisconnected = FALSE; // used to restore texture state after a mode switch -LLFrameTimer gRestoreGLTimer; -BOOL gRestoreGL = FALSE; -bool gUseWireframe = FALSE; +LLFrameTimer gRestoreGLTimer; +BOOL gRestoreGL = FALSE; +bool gUseWireframe = FALSE; LLMemoryInfo gSysMemory; U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp std::string gLastVersionChannel; -LLVector3 gWindVec(3.0, 3.0, 0.0); -LLVector3 gRelativeWindVec(0.0, 0.0, 0.0); +LLVector3 gWindVec(3.0, 3.0, 0.0); +LLVector3 gRelativeWindVec(0.0, 0.0, 0.0); -U32 gPacketsIn = 0; +U32 gPacketsIn = 0; -BOOL gPrintMessagesThisFrame = FALSE; +BOOL gPrintMessagesThisFrame = FALSE; BOOL gRandomizeFramerate = FALSE; BOOL gPeriodicSlowFrame = FALSE; @@ -393,53 +393,53 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; static std::set default_trans_args; void init_default_trans_args() { - default_trans_args.insert("SECOND_LIFE"); // World - default_trans_args.insert("APP_NAME"); - default_trans_args.insert("CAPITALIZED_APP_NAME"); - default_trans_args.insert("SECOND_LIFE_GRID"); - default_trans_args.insert("SUPPORT_SITE"); - // This URL shows up in a surprising number of places in various skin - // files. We really only want to have to maintain a single copy of it. - default_trans_args.insert("create_account_url"); + default_trans_args.insert("SECOND_LIFE"); // World + default_trans_args.insert("APP_NAME"); + default_trans_args.insert("CAPITALIZED_APP_NAME"); + default_trans_args.insert("SECOND_LIFE_GRID"); + default_trans_args.insert("SUPPORT_SITE"); + // This URL shows up in a surprising number of places in various skin + // files. We really only want to have to maintain a single copy of it. + default_trans_args.insert("create_account_url"); } struct SettingsFile : public LLInitParam::Block { - Mandatory name; - Optional file_name; - Optional required, - persistent; - Optional file_name_setting; - - SettingsFile() - : name("name"), - file_name("file_name"), - required("required", false), - persistent("persistent", true), - file_name_setting("file_name_setting") - {} + Mandatory name; + Optional file_name; + Optional required, + persistent; + Optional file_name_setting; + + SettingsFile() + : name("name"), + file_name("file_name"), + required("required", false), + persistent("persistent", true), + file_name_setting("file_name_setting") + {} }; struct SettingsGroup : public LLInitParam::Block { - Mandatory name; - Mandatory path_index; - Multiple files; - - SettingsGroup() - : name("name"), - path_index("path_index"), - files("file") - {} + Mandatory name; + Mandatory path_index; + Multiple files; + + SettingsGroup() + : name("name"), + path_index("path_index"), + files("file") + {} }; struct SettingsFiles : public LLInitParam::Block { - Multiple groups; + Multiple groups; - SettingsFiles() - : groups("group") - {} + SettingsFiles() + : groups("group") + {} }; static std::string gWindowTitle; @@ -454,122 +454,122 @@ static bool app_metrics_qa_mode = false; void idle_afk_check() { - // check idle timers - F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32(); - F32 afk_timeout = gSavedSettings.getS32("AFKTimeout"); - if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK()) - { - LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL; - gAgent.setAFK(); - } + // check idle timers + F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32(); + F32 afk_timeout = gSavedSettings.getS32("AFKTimeout"); + if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK()) + { + LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL; + gAgent.setAFK(); + } } // A callback set in LLAppViewer::init() static void ui_audio_callback(const LLUUID& uuid) { - if (gAudiop) - { - SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); - gAudiop->triggerSound(soundData); - } + if (gAudiop) + { + SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + gAudiop->triggerSound(soundData); + } } // A callback set in LLAppViewer::init() static void deferred_ui_audio_callback(const LLUUID& uuid) { - if (gAudiop) - { - SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); - LLDeferredSounds::instance().deferSound(soundData); - } + if (gAudiop) + { + SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + LLDeferredSounds::instance().deferSound(soundData); + } } -bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) +bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) { - if(!match || !base || base->getPlainText()) - return false; - - LLUUID match_id = match->getID(); - - LLIconCtrl* icon; - - if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor - || gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group - { - LLGroupIconCtrl::Params icon_params; - icon_params.group_id = match_id; - icon_params.rect = LLRect(0, 16, 16, 0); - icon_params.visible = true; - icon = LLUICtrlFactory::instance().create(icon_params); - } - else - { - LLAvatarIconCtrl::Params icon_params; - icon_params.avatar_id = match_id; - icon_params.rect = LLRect(0, 16, 16, 0); - icon_params.visible = true; - icon = LLUICtrlFactory::instance().create(icon_params); - } - - LLInlineViewSegment::Params params; - params.force_newline = false; - params.view = icon; - params.left_pad = 4; - params.right_pad = 4; - params.top_pad = -2; - params.bottom_pad = 2; - - base->appendWidget(params," ",false); - - return true; + if(!match || !base || base->getPlainText()) + return false; + + LLUUID match_id = match->getID(); + + LLIconCtrl* icon; + + if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor + || gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group + { + LLGroupIconCtrl::Params icon_params; + icon_params.group_id = match_id; + icon_params.rect = LLRect(0, 16, 16, 0); + icon_params.visible = true; + icon = LLUICtrlFactory::instance().create(icon_params); + } + else + { + LLAvatarIconCtrl::Params icon_params; + icon_params.avatar_id = match_id; + icon_params.rect = LLRect(0, 16, 16, 0); + icon_params.visible = true; + icon = LLUICtrlFactory::instance().create(icon_params); + } + + LLInlineViewSegment::Params params; + params.force_newline = false; + params.view = icon; + params.left_pad = 4; + params.right_pad = 4; + params.top_pad = -2; + params.bottom_pad = 2; + + base->appendWidget(params," ",false); + + return true; } // Use these strictly for things that are constructed at startup, // or for things that are performance critical. JC static void settings_to_globals() { - LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad"); - BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall"); - BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight"); + LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad"); + BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall"); + BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight"); - MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight"); - MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); + MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight"); + MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); - LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); + LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); #if LL_DARWIN LLRender::sGLCoreProfile = true; #else LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); #endif - LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); - LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); - LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); - LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); - LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; - LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); - LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor"); - LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); - LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); - LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors")); - LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible"); - // clamp auto-open time to some minimum usable value - LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); - LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); - LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); - LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); - - gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns")); - gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns")); - gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); - - gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); - gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); + LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); + LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); + LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); + LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); + LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; + LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); + LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor"); + LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); + LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); + LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors")); + LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible"); + // clamp auto-open time to some minimum usable value + LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); + LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); + LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); + LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); + + gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns")); + gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns")); + gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); + + gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); + gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); - + #if LL_DARWIN LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); - gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); + gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } @@ -587,41 +587,41 @@ static void settings_modify() class LLFastTimerLogThread : public LLThread { public: - std::string mFile; - - LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log") - { - std::string file_name = test_name + std::string(".slp"); - mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name); - } - - void run() - { - llofstream os(mFile.c_str()); - - while (!LLAppViewer::instance()->isQuitting()) - { - LLTrace::BlockTimer::writeLog(os); - os.flush(); - ms_sleep(32); - } - - os.close(); - } + std::string mFile; + + LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log") + { + std::string file_name = test_name + std::string(".slp"); + mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name); + } + + void run() + { + llofstream os(mFile.c_str()); + + while (!LLAppViewer::instance()->isQuitting()) + { + LLTrace::BlockTimer::writeLog(os); + os.flush(); + ms_sleep(32); + } + + os.close(); + } }; //virtual bool LLAppViewer::initSLURLHandler() { - // does nothing unless subclassed - return false; + // does nothing unless subclassed + return false; } //virtual bool LLAppViewer::sendURLToOtherInstance(const std::string& url) { - // does nothing unless subclassed - return false; + // does nothing unless subclassed + return false; } //---------------------------------------------------------------------------- @@ -637,402 +637,402 @@ LLPurgeDiskCacheThread* LLAppViewer::sPurgeDiskCacheThread = NULL; std::string getRuntime() { - return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value()); + return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value()); } LLAppViewer::LLAppViewer() -: mMarkerFile(), - mLogoutMarkerFile(), - mReportedCrash(false), - mNumSessions(0), +: mMarkerFile(), + mLogoutMarkerFile(), + mReportedCrash(false), + mNumSessions(0), mGeneralThreadPool(nullptr), - mPurgeCache(false), - mPurgeCacheOnExit(false), - mPurgeUserDataOnExit(false), - mSecondInstance(false), - mUpdaterNotFound(false), - mSavedFinalSnapshot(false), - mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded. - mQuitRequested(false), - mLogoutRequestSent(false), - mLastAgentControlFlags(0), - mLastAgentForceUpdate(0), - mMainloopTimeout(NULL), - mAgentRegionLastAlive(false), - mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", FALSE)), - mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), - mFastTimerLogThread(NULL), - mSettingsLocationList(NULL), - mIsFirstRun(false) + mPurgeCache(false), + mPurgeCacheOnExit(false), + mPurgeUserDataOnExit(false), + mSecondInstance(false), + mUpdaterNotFound(false), + mSavedFinalSnapshot(false), + mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded. + mQuitRequested(false), + mLogoutRequestSent(false), + mLastAgentControlFlags(0), + mLastAgentForceUpdate(0), + mMainloopTimeout(NULL), + mAgentRegionLastAlive(false), + mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", FALSE)), + mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), + mFastTimerLogThread(NULL), + mSettingsLocationList(NULL), + mIsFirstRun(false) { - if(NULL != sInstance) - { - LL_ERRS() << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << LL_ENDL; - } + if(NULL != sInstance) + { + LL_ERRS() << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << LL_ENDL; + } mDumpPath =""; - // Need to do this initialization before we do anything else, since anything - // that touches files should really go through the lldir API - gDirUtilp->initAppDirs("SecondLife"); - // - // IMPORTANT! Do NOT put anything that will write - // into the log files during normal startup until AFTER - // we run the "program crashed last time" error handler below. - // - sInstance = this; - - gLoggedInTime.stop(); - - processMarkerFiles(); - // - // OK to write stuff to logs now, we've now crash reported if necessary - // - - LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple()); - - // Under some circumstances we want to read the static_debug_info.log file - // from the previous viewer run between this constructor call and the - // init() call, which will overwrite the static_debug_info.log file for - // THIS run. So setDebugFileNames() early. + // Need to do this initialization before we do anything else, since anything + // that touches files should really go through the lldir API + gDirUtilp->initAppDirs("SecondLife"); + // + // IMPORTANT! Do NOT put anything that will write + // into the log files during normal startup until AFTER + // we run the "program crashed last time" error handler below. + // + sInstance = this; + + gLoggedInTime.stop(); + + processMarkerFiles(); + // + // OK to write stuff to logs now, we've now crash reported if necessary + // + + LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple()); + + // Under some circumstances we want to read the static_debug_info.log file + // from the previous viewer run between this constructor call and the + // init() call, which will overwrite the static_debug_info.log file for + // THIS run. So setDebugFileNames() early. # ifdef LL_BUGSPLAT - // MAINT-8917: don't create a dump directory just for the - // static_debug_info.log file - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + // MAINT-8917: don't create a dump directory just for the + // static_debug_info.log file + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); # else // ! LL_BUGSPLAT - // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues. - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues. + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); # endif // ! LL_BUGSPLAT - mDumpPath = logdir; + mDumpPath = logdir; - setDebugFileNames(logdir); + setDebugFileNames(logdir); } LLAppViewer::~LLAppViewer() { - delete mSettingsLocationList; + delete mSettingsLocationList; - destroyMainloopTimeout(); + destroyMainloopTimeout(); - // If we got to this destructor somehow, the app didn't hang. - removeMarkerFiles(); + // If we got to this destructor somehow, the app didn't hang. + removeMarkerFiles(); } class LLUITranslationBridge : public LLTranslationBridge { public: - virtual std::string getString(const std::string &xml_desc) - { - return LLTrans::getString(xml_desc); - } + virtual std::string getString(const std::string &xml_desc) + { + return LLTrans::getString(xml_desc); + } }; bool LLAppViewer::init() { - setupErrorHandling(mSecondInstance); + setupErrorHandling(mSecondInstance); - // - // Start of the application - // + // + // Start of the application + // // initialize the LLSettingsType translation bridge. LLTranslationBridge::ptr_t trans = std::make_shared(); LLSettingsType::initParamSingleton(trans); - // initialize SSE options - LLVector4a::initClass(); + // initialize SSE options + LLVector4a::initClass(); - //initialize particle index pool - LLVOPartGroup::initClass(); + //initialize particle index pool + LLVOPartGroup::initClass(); - // set skin search path to default, will be overridden later - // this allows simple skinned file lookups to work - gDirUtilp->setSkinFolder("default", "en"); + // set skin search path to default, will be overridden later + // this allows simple skinned file lookups to work + gDirUtilp->setSkinFolder("default", "en"); -// initLoggingAndGetLastDuration(); +// initLoggingAndGetLastDuration(); - // - // OK to write stuff to logs now, we've now crash reported if necessary - // - init_default_trans_args(); + // + // OK to write stuff to logs now, we've now crash reported if necessary + // + init_default_trans_args(); // inits from settings.xml and from strings.xml - if (!initConfiguration()) - return false; + if (!initConfiguration()) + return false; - LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; + LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; - //set the max heap size. - initMaxHeapSize() ; - LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); + //set the max heap size. + initMaxHeapSize() ; + LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); - // Although initLoggingAndGetLastDuration() is the right place to mess with - // setFatalFunction(), we can't query gSavedSettings until after - // initConfiguration(). - S32 rc(gSavedSettings.getS32("QAModeTermCode")); - if (rc >= 0) - { - // QAModeTermCode set, terminate with that rc on LL_ERRS. Use - // _exit() rather than exit() because normal cleanup depends too - // much on successful startup! - LLError::setFatalFunction([rc](const std::string&){ _exit(rc); }); - } + // Although initLoggingAndGetLastDuration() is the right place to mess with + // setFatalFunction(), we can't query gSavedSettings until after + // initConfiguration(). + S32 rc(gSavedSettings.getS32("QAModeTermCode")); + if (rc >= 0) + { + // QAModeTermCode set, terminate with that rc on LL_ERRS. Use + // _exit() rather than exit() because normal cleanup depends too + // much on successful startup! + LLError::setFatalFunction([rc](const std::string&){ _exit(rc); }); + } mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); - // Initialize the non-LLCurl libcurl library. Should be called - // before consumers (LLTextureFetch). - mAppCoreHttp.init(); + // Initialize the non-LLCurl libcurl library. Should be called + // before consumers (LLTextureFetch). + mAppCoreHttp.init(); - LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ; + LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ; LLMachineID::init(); - { - if (gSavedSettings.getBOOL("QAModeMetrics")) - { - app_metrics_qa_mode = true; - app_metrics_interval = METRICS_INTERVAL_QA; - } - LLViewerAssetStatsFF::init(); - } - - initThreads(); - LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ; - - // Initialize settings early so that the defaults for ignorable dialogs are - // picked up and then correctly re-saved after launching the updater (STORM-1268). - LLUI::settings_map_t settings_map; - settings_map["config"] = &gSavedSettings; - settings_map["ignores"] = &gWarningSettings; - settings_map["floater"] = &gSavedSettings; // *TODO: New settings file - settings_map["account"] = &gSavedPerAccountSettings; - - LLUI::initParamSingleton(settings_map, - LLUIImageList::getInstance(), - ui_audio_callback, - deferred_ui_audio_callback); - LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ; - - // NOW LLUI::getLanguage() should work. gDirUtilp must know the language - // for this session ASAP so all the file-loading commands that follow, - // that use findSkinnedFilenames(), will include the localized files. - gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage()); - - // Setup LLTrans after LLUI::initClass has been called. - initStrings(); + { + if (gSavedSettings.getBOOL("QAModeMetrics")) + { + app_metrics_qa_mode = true; + app_metrics_interval = METRICS_INTERVAL_QA; + } + LLViewerAssetStatsFF::init(); + } + + initThreads(); + LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ; + + // Initialize settings early so that the defaults for ignorable dialogs are + // picked up and then correctly re-saved after launching the updater (STORM-1268). + LLUI::settings_map_t settings_map; + settings_map["config"] = &gSavedSettings; + settings_map["ignores"] = &gWarningSettings; + settings_map["floater"] = &gSavedSettings; // *TODO: New settings file + settings_map["account"] = &gSavedPerAccountSettings; + + LLUI::initParamSingleton(settings_map, + LLUIImageList::getInstance(), + ui_audio_callback, + deferred_ui_audio_callback); + LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ; + + // NOW LLUI::getLanguage() should work. gDirUtilp must know the language + // for this session ASAP so all the file-loading commands that follow, + // that use findSkinnedFilenames(), will include the localized files. + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage()); + + // Setup LLTrans after LLUI::initClass has been called. + initStrings(); // initialize LLWearableType translation bridge. // Will immediately use LLTranslationBridge to init LLWearableDictionary LLWearableType::initParamSingleton(trans); - // Setup notifications after LLUI::initClass() has been called. - LLNotifications::instance(); - LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; + // Setup notifications after LLUI::initClass() has been called. + LLNotifications::instance(); + LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; - ////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - // *FIX: The following code isn't grouped into functions yet. + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // *FIX: The following code isn't grouped into functions yet. - // - // Various introspection concerning the libs we're using - particularly - // the libs involved in getting to a full login screen. - // - LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL; - LL_INFOS("InitInfo") << "libcurl version is: " << LLCore::LLHttp::getCURLVersion() << LL_ENDL; + // + // Various introspection concerning the libs we're using - particularly + // the libs involved in getting to a full login screen. + // + LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL; + LL_INFOS("InitInfo") << "libcurl version is: " << LLCore::LLHttp::getCURLVersion() << LL_ENDL; - ///////////////////////////////////////////////// - // OS-specific login dialogs - ///////////////////////////////////////////////// + ///////////////////////////////////////////////// + // OS-specific login dialogs + ///////////////////////////////////////////////// - //test_cached_control(); + //test_cached_control(); - // track number of times that app has run - mNumSessions = gSavedSettings.getS32("NumSessions"); - mNumSessions++; - gSavedSettings.setS32("NumSessions", mNumSessions); + // track number of times that app has run + mNumSessions = gSavedSettings.getS32("NumSessions"); + mNumSessions++; + gSavedSettings.setS32("NumSessions", mNumSessions); - // LLKeyboard relies on LLUI to know what some accelerator keys are called. - LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString ); + // LLKeyboard relies on LLUI to know what some accelerator keys are called. + LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString ); - // Provide the text fields with callbacks for opening Urls - LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null)); - LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false)); - LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null)); - LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor); + // Provide the text fields with callbacks for opening Urls + LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null)); + LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false)); + LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null)); + LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor); - // Let code in llui access the viewer help floater - LLUI::getInstance()->mHelpImpl = LLViewerHelp::getInstance(); + // Let code in llui access the viewer help floater + LLUI::getInstance()->mHelpImpl = LLViewerHelp::getInstance(); - LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ; + LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ; - // Load translations for tooltips - LLFloater::initClass(); - LLUrlFloaterDispatchHandler::registerInDispatcher(); + // Load translations for tooltips + LLFloater::initClass(); + LLUrlFloaterDispatchHandler::registerInDispatcher(); - ///////////////////////////////////////////////// + ///////////////////////////////////////////////// - LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated + LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated - LLViewerFloaterReg::registerFloaters(); + LLViewerFloaterReg::registerFloaters(); - ///////////////////////////////////////////////// - // - // Load settings files - // - // - LLGroupMgr::parseRoleActions("role_actions.xml"); + ///////////////////////////////////////////////// + // + // Load settings files + // + // + LLGroupMgr::parseRoleActions("role_actions.xml"); - LLAgent::parseTeleportMessages("teleport_strings.xml"); + LLAgent::parseTeleportMessages("teleport_strings.xml"); - // load MIME type -> media impl mappings - std::string mime_types_name; + // load MIME type -> media impl mappings + std::string mime_types_name; #if LL_DARWIN - mime_types_name = "mime_types_mac.xml"; + mime_types_name = "mime_types_mac.xml"; #elif LL_LINUX - mime_types_name = "mime_types_linux.xml"; + mime_types_name = "mime_types_linux.xml"; #else - mime_types_name = "mime_types.xml"; + mime_types_name = "mime_types.xml"; #endif - LLMIMETypes::parseMIMETypes( mime_types_name ); - - // Copy settings to globals. *TODO: Remove or move to appropriage class initializers - settings_to_globals(); - // Setup settings listeners - settings_setup_listeners(); - // Modify settings based on system configuration and compile options - settings_modify(); - - // Find partition serial number (Windows) or hardware serial (Mac) - mSerialNumber = generateSerialNumber(); - - // do any necessary set-up for accepting incoming SLURLs from apps - initSLURLHandler(); - - if(false == initHardwareTest()) - { - // Early out from user choice. - return false; - } - LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ; - - // Prepare for out-of-memory situations, during which we will crash on - // purpose and save a dump. + LLMIMETypes::parseMIMETypes( mime_types_name ); + + // Copy settings to globals. *TODO: Remove or move to appropriage class initializers + settings_to_globals(); + // Setup settings listeners + settings_setup_listeners(); + // Modify settings based on system configuration and compile options + settings_modify(); + + // Find partition serial number (Windows) or hardware serial (Mac) + mSerialNumber = generateSerialNumber(); + + // do any necessary set-up for accepting incoming SLURLs from apps + initSLURLHandler(); + + if(false == initHardwareTest()) + { + // Early out from user choice. + return false; + } + LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ; + + // Prepare for out-of-memory situations, during which we will crash on + // purpose and save a dump. #if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP - MemSetErrorHandler(first_mem_error_handler); + MemSetErrorHandler(first_mem_error_handler); #endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP - // *Note: this is where gViewerStats used to be created. + // *Note: this is where gViewerStats used to be created. - if (!initCache()) - { - LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL; - std::ostringstream msg; - msg << LLTrans::getString("MBUnableToAccessFile"); - OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); - return 0; - } - LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ; + if (!initCache()) + { + LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL; + std::ostringstream msg; + msg << LLTrans::getString("MBUnableToAccessFile"); + OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); + return 0; + } + LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ; // Initialize event recorder LLViewerEventRecorder::createInstance(); - // - // Initialize the window - // - gGLActive = TRUE; - initWindow(); - LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ; + // + // Initialize the window + // + gGLActive = TRUE; + initWindow(); + LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ; // writeSystemInfo can be called after window is initialized (gViewerWindow non-null) writeSystemInfo(); - // initWindow also initializes the Feature List, so now we can initialize this global. - LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); + // initWindow also initializes the Feature List, so now we can initialize this global. + LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); - // call all self-registered classes - LLInitClassList::instance().fireCallbacks(); + // call all self-registered classes + LLInitClassList::instance().fireCallbacks(); - LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts + LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts - gGLManager.getGLInfo(gDebugInfo); - gGLManager.printGLInfoString(); + gGLManager.getGLInfo(gDebugInfo); + gGLManager.printGLInfoString(); - // If we don't have the right GL requirements, exit. - if (!gGLManager.mHasRequirements) - { + // If we don't have the right GL requirements, exit. + if (!gGLManager.mHasRequirements) + { // already handled with a MBVideoDrvErr - return 0; - } - - // Without SSE2 support we will crash almost immediately, warn here. - if (!gSysCPU.hasSSE2()) - { - // can't use an alert here since we're exiting and - // all hell breaks lose. - OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"), - LLStringUtil::null, - OSMB_OK); - return 0; - } - - // alert the user if they are using unsupported hardware - if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware")) - { - bool unsupported = false; - LLSD args; - std::string minSpecs; - - // get cpu data from xml - std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount")); - S32 minCPU = 0; - minCPUString >> minCPU; - - // get RAM data from XML - std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount")); - U64Bytes minRAM; - minRAMString >> minRAM; - - if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN) - { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU"); - minSpecs += "\n"; - unsupported = true; - } - if(gSysCPU.getMHz() < minCPU) - { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU"); - minSpecs += "\n"; - unsupported = true; - } - if(gSysMemory.getPhysicalMemoryKB() < minRAM) - { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM"); - minSpecs += "\n"; - unsupported = true; - } - - if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN) - { - LLNotificationsUtil::add("UnknownGPU"); - } - - if(unsupported) - { - if(!gSavedSettings.controlExists("WarnUnsupportedHardware") - || gSavedSettings.getBOOL("WarnUnsupportedHardware")) - { - args["MINSPECS"] = minSpecs; - LLNotificationsUtil::add("UnsupportedHardware", args ); - } - - } - } + return 0; + } + + // Without SSE2 support we will crash almost immediately, warn here. + if (!gSysCPU.hasSSE2()) + { + // can't use an alert here since we're exiting and + // all hell breaks lose. + OSMessageBox( + LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"), + LLStringUtil::null, + OSMB_OK); + return 0; + } + + // alert the user if they are using unsupported hardware + if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware")) + { + bool unsupported = false; + LLSD args; + std::string minSpecs; + + // get cpu data from xml + std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount")); + S32 minCPU = 0; + minCPUString >> minCPU; + + // get RAM data from XML + std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount")); + U64Bytes minRAM; + minRAMString >> minRAM; + + if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN) + { + minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU"); + minSpecs += "\n"; + unsupported = true; + } + if(gSysCPU.getMHz() < minCPU) + { + minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU"); + minSpecs += "\n"; + unsupported = true; + } + if(gSysMemory.getPhysicalMemoryKB() < minRAM) + { + minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM"); + minSpecs += "\n"; + unsupported = true; + } + + if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN) + { + LLNotificationsUtil::add("UnknownGPU"); + } + + if(unsupported) + { + if(!gSavedSettings.controlExists("WarnUnsupportedHardware") + || gSavedSettings.getBOOL("WarnUnsupportedHardware")) + { + args["MINSPECS"] = minSpecs; + LLNotificationsUtil::add("UnsupportedHardware", args ); + } + + } + } #if LL_WINDOWS && ADDRESS_SIZE == 64 if (gGLManager.mIsIntel) @@ -1083,54 +1083,54 @@ bool LLAppViewer::init() // Obsolete? mExpectedGLVersion is always zero #if LL_WINDOWS - if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) - { - std::string url; - if (gGLManager.mIsIntel) - { - url = LLTrans::getString("IntelDriverPage"); - } - else if (gGLManager.mIsNVIDIA) - { - url = LLTrans::getString("NvidiaDriverPage"); - } - else if (gGLManager.mIsAMD) - { - url = LLTrans::getString("AMDDriverPage"); - } - - if (!url.empty()) - { - LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url)); - } - } + if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) + { + std::string url; + if (gGLManager.mIsIntel) + { + url = LLTrans::getString("IntelDriverPage"); + } + else if (gGLManager.mIsNVIDIA) + { + url = LLTrans::getString("NvidiaDriverPage"); + } + else if (gGLManager.mIsAMD) + { + url = LLTrans::getString("AMDDriverPage"); + } + + if (!url.empty()) + { + LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url)); + } + } #endif - // save the graphics card - gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); + // save the graphics card + gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); - // Save the current version to the prefs file - gSavedSettings.setString("LastRunVersion", - LLVersionInfo::instance().getChannelAndVersion()); + // Save the current version to the prefs file + gSavedSettings.setString("LastRunVersion", + LLVersionInfo::instance().getChannelAndVersion()); - gSimLastTime = gRenderStartTime.getElapsedTimeF32(); - gSimFrames = (F32)gFrameCount; + gSimLastTime = gRenderStartTime.getElapsedTimeF32(); + gSimFrames = (F32)gFrameCount; if (gSavedSettings.getBOOL("JoystickEnabled")) { LLViewerJoystick::getInstance()->init(false); } - try { - initializeSecHandler(); - } - catch (LLProtectedDataException&) - { - LLNotificationsUtil::add("CorruptedProtectedDataStore"); - } + try { + initializeSecHandler(); + } + catch (LLProtectedDataException&) + { + LLNotificationsUtil::add("CorruptedProtectedDataStore"); + } - gGLActive = FALSE; + gGLActive = FALSE; #if LL_RELEASE_FOR_DOWNLOAD // Skip updater if this is a non-interactive instance @@ -1228,25 +1228,25 @@ bool LLAppViewer::init() << LL_ENDL; } - LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; + LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; - //EXT-7013 - On windows for some locale (Japanese) standard - //datetime formatting functions didn't support some parameters such as "weekday". - //Names for days and months localized in xml are also useful for Polish locale(STORM-107). - std::string language = gSavedSettings.getString("Language"); - if(language == "ja" || language == "pl") - { - LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames")); - LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames")); - LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames")); - LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames")); - LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat")); - - LLStringOps::sAM = LLTrans::getString("dateTimeAM"); - LLStringOps::sPM = LLTrans::getString("dateTimePM"); - } + //EXT-7013 - On windows for some locale (Japanese) standard + //datetime formatting functions didn't support some parameters such as "weekday". + //Names for days and months localized in xml are also useful for Polish locale(STORM-107). + std::string language = gSavedSettings.getString("Language"); + if(language == "ja" || language == "pl") + { + LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames")); + LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames")); + LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames")); + LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames")); + LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat")); + + LLStringOps::sAM = LLTrans::getString("dateTimeAM"); + LLStringOps::sPM = LLTrans::getString("dateTimePM"); + } - LLAgentLanguage::init(); + LLAgentLanguage::init(); /// Tell the Coprocedure manager how to discover and store the pool sizes // what I wanted @@ -1254,27 +1254,27 @@ bool LLAppViewer::init() boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1), boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS)); - // TODO: consider moving proxy initialization here or LLCopocedureManager after proxy initialization, may be implement - // some other protection to make sure we don't use network before initializng proxy + // TODO: consider moving proxy initialization here or LLCopocedureManager after proxy initialization, may be implement + // some other protection to make sure we don't use network before initializng proxy - /*----------------------------------------------------------------------*/ - // nat 2016-06-29 moved the following here from the former mainLoop(). - mMainloopTimeout = new LLWatchdogTimeout(); + /*----------------------------------------------------------------------*/ + // nat 2016-06-29 moved the following here from the former mainLoop(). + mMainloopTimeout = new LLWatchdogTimeout(); - // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO(gAPRPoolp); + // Create IO Pump to use for HTTP Requests. + gServicePump = new LLPumpIO(gAPRPoolp); - // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. - LLVoiceChannel::initClass(); - LLVoiceClient::initParamSingleton(gServicePump); - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + LLVoiceChannel::initClass(); + LLVoiceClient::initParamSingleton(gServicePump); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); - joystick = LLViewerJoystick::getInstance(); - joystick->setNeedsReset(true); - /*----------------------------------------------------------------------*/ - // Load User's bindings - loadKeyBindings(); + joystick = LLViewerJoystick::getInstance(); + joystick->setNeedsReset(true); + /*----------------------------------------------------------------------*/ + // Load User's bindings + loadKeyBindings(); //LLSimpleton creations LLEnvironment::createInstance(); @@ -1291,23 +1291,23 @@ bool LLAppViewer::init() } #endif - return true; + return true; } void LLAppViewer::initMaxHeapSize() { - //set the max heap size. - //here is some info regarding to the max heap size: - //------------------------------------------------------------------------------------------ - // OS | setting | SL address bits | max manageable memory space | max heap size - // Win 32 | default | 32-bit | 2GB | < 1.7GB - // Win 32 | /3G | 32-bit | 3GB | < 1.7GB or 2.7GB - //Linux 32 | default | 32-bit | 3GB | < 2.7GB - //Linux 32 |HUGEMEM | 32-bit | 4GB | < 3.7GB - //64-bit OS |default | 32-bit | 4GB | < 3.7GB - //64-bit OS |default | 64-bit | N/A (> 4GB) | N/A (> 4GB) - //------------------------------------------------------------------------------------------ - //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. + //set the max heap size. + //here is some info regarding to the max heap size: + //------------------------------------------------------------------------------------------ + // OS | setting | SL address bits | max manageable memory space | max heap size + // Win 32 | default | 32-bit | 2GB | < 1.7GB + // Win 32 | /3G | 32-bit | 3GB | < 1.7GB or 2.7GB + //Linux 32 | default | 32-bit | 3GB | < 2.7GB + //Linux 32 |HUGEMEM | 32-bit | 4GB | < 3.7GB + //64-bit OS |default | 32-bit | 4GB | < 3.7GB + //64-bit OS |default | 64-bit | N/A (> 4GB) | N/A (> 4GB) + //------------------------------------------------------------------------------------------ + //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. #ifndef LL_X86_64 F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; @@ -1324,42 +1324,42 @@ LLTrace::BlockTimerStatHandle FTM_FRAME("Frame"); bool LLAppViewer::frame() { - bool ret = false; - - if (gSimulateMemLeak) - { - try - { - ret = doFrame(); - } - catch (const LLContinueError&) - { - LOG_UNHANDLED_EXCEPTION(""); - } - catch (std::bad_alloc&) - { - LLMemory::logMemoryInfo(TRUE); - LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance("mem_leaking"); - if (mem_leak_instance) - { - mem_leak_instance->stop(); - } - LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL; - } - } - else - { - try - { - ret = doFrame(); - } - catch (const LLContinueError&) - { - LOG_UNHANDLED_EXCEPTION(""); - } - } - - return ret; + bool ret = false; + + if (gSimulateMemLeak) + { + try + { + ret = doFrame(); + } + catch (const LLContinueError&) + { + LOG_UNHANDLED_EXCEPTION(""); + } + catch (std::bad_alloc&) + { + LLMemory::logMemoryInfo(TRUE); + LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance("mem_leaking"); + if (mem_leak_instance) + { + mem_leak_instance->stop(); + } + LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL; + } + } + else + { + try + { + ret = doFrame(); + } + catch (const LLContinueError&) + { + LOG_UNHANDLED_EXCEPTION(""); + } + } + + return ret; } bool LLAppViewer::doFrame() @@ -1452,63 +1452,63 @@ bool LLAppViewer::doFrame() } } - if (!LLApp::isExiting()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" ) - pingMainloopTimeout("Main:JoystickKeyboard"); - - // Scan keyboard for movement keys. Command keys and typing - // are handled by windows callbacks. Don't do this until we're - // done initializing. JC - if (gViewerWindow - && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) - && gViewerWindow->getActive() - && !gViewerWindow->getWindow()->getMinimized() - && LLStartUp::getStartupState() == STATE_STARTED - && (gHeadlessClient || !gViewerWindow->getShowProgress()) - && !gFocusMgr.focusLocked()) - { + if (!LLApp::isExiting()) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" ) + pingMainloopTimeout("Main:JoystickKeyboard"); + + // Scan keyboard for movement keys. Command keys and typing + // are handled by windows callbacks. Don't do this until we're + // done initializing. JC + if (gViewerWindow + && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) + && gViewerWindow->getActive() + && !gViewerWindow->getWindow()->getMinimized() + && LLStartUp::getStartupState() == STATE_STARTED + && (gHeadlessClient || !gViewerWindow->getShowProgress()) + && !gFocusMgr.focusLocked()) + { LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); - joystick->scanJoystick(); - gKeyboard->scanKeyboard(); + joystick->scanJoystick(); + gKeyboard->scanKeyboard(); gViewerInput.scanMouse(); - } + } - // Update state based on messages, user input, object idle. - { - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) - pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! - } + // Update state based on messages, user input, object idle. + { + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) + pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + } - { + { LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); - idle(); - } + idle(); + } - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) - resumeMainloopTimeout(); - } - } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } + } - if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) - { - pauseMainloopTimeout(); - saveFinalSnapshot(); + if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) + { + pauseMainloopTimeout(); + saveFinalSnapshot(); if (LLVoiceClient::instanceExists()) { LLVoiceClient::getInstance()->terminate(); } - disconnectViewer(); - resumeMainloopTimeout(); - } + disconnectViewer(); + resumeMainloopTimeout(); + } - // Render scene. - // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 + // Render scene. + // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display"); @@ -1532,159 +1532,159 @@ bool LLAppViewer::doFrame() LLViewerStatsRecorder::instance().idle(); } } - } + } - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) - pingMainloopTimeout("Main:Sleep"); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) + pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); - } + pauseMainloopTimeout(); + } - // Sleep and run background threads - { - //LL_RECORD_BLOCK_TIME(SLEEP2); - LL_PROFILE_ZONE_WARN( "Sleep2" ) + // Sleep and run background threads + { + //LL_RECORD_BLOCK_TIME(SLEEP2); + LL_PROFILE_ZONE_WARN( "Sleep2" ) - // yield some time to the os based on command line option - static LLCachedControl yield_time(gSavedSettings, "YieldTime", -1); - if(yield_time >= 0) - { + // yield some time to the os based on command line option + static LLCachedControl yield_time(gSavedSettings, "YieldTime", -1); + if(yield_time >= 0) + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Yield"); - LL_PROFILE_ZONE_NUM( yield_time ) - ms_sleep(yield_time); - } - - if (gNonInteractive) - { - S32 non_interactive_ms_sleep_time = 100; - LLAppViewer::getTextureCache()->pause(); - ms_sleep(non_interactive_ms_sleep_time); - } - - // yield cooperatively when not running as foreground window - // and when not quiting (causes trouble at mac's cleanup stage) - if (!LLApp::isExiting() - && ((gViewerWindow && !gViewerWindow->getWindow()->getVisible()) - || !gFocusMgr.getAppHasFocus())) - { - // Sleep if we're not rendering, or the window is minimized. - static LLCachedControl s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40); - S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000); - // don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads - // of equal priority on Windows - if (milliseconds_to_sleep > 0) - { + LL_PROFILE_ZONE_NUM( yield_time ) + ms_sleep(yield_time); + } + + if (gNonInteractive) + { + S32 non_interactive_ms_sleep_time = 100; + LLAppViewer::getTextureCache()->pause(); + ms_sleep(non_interactive_ms_sleep_time); + } + + // yield cooperatively when not running as foreground window + // and when not quiting (causes trouble at mac's cleanup stage) + if (!LLApp::isExiting() + && ((gViewerWindow && !gViewerWindow->getWindow()->getVisible()) + || !gFocusMgr.getAppHasFocus())) + { + // Sleep if we're not rendering, or the window is minimized. + static LLCachedControl s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40); + S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000); + // don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads + // of equal priority on Windows + if (milliseconds_to_sleep > 0) + { LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP ); ms_sleep(milliseconds_to_sleep); - // also pause worker threads during this wait period - LLAppViewer::getTextureCache()->pause(); - } - } - - if (mRandomizeFramerate) - { - ms_sleep(rand() % 200); - } - - if (mPeriodicSlowFrame - && (gFrameCount % 10 == 0)) - { - LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; - ms_sleep(500); - } - - S32 total_work_pending = 0; - S32 total_io_pending = 0; - { - S32 work_pending = 0; - S32 io_pending = 0; - F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); - - work_pending += updateTextureThreads(max_time); - - { + // also pause worker threads during this wait period + LLAppViewer::getTextureCache()->pause(); + } + } + + if (mRandomizeFramerate) + { + ms_sleep(rand() % 200); + } + + if (mPeriodicSlowFrame + && (gFrameCount % 10 == 0)) + { + LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; + ms_sleep(500); + } + + S32 total_work_pending = 0; + S32 total_io_pending = 0; + { + S32 work_pending = 0; + S32 io_pending = 0; + F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); + + work_pending += updateTextureThreads(max_time); + + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("LFS Thread"); - io_pending += LLLFSThread::updateClass(1); - } - - if (io_pending > 1000) - { - ms_sleep(llmin(io_pending/100,100)); // give the lfs some time to catch up - } - - total_work_pending += work_pending ; - total_io_pending += io_pending ; - - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" ) - gMeshRepo.update() ; - } - - if(!total_work_pending) //pause texture fetching threads if nothing to process. - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" ) - LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getTextureFetch()->pause(); - } - if(!total_io_pending) //pause file threads if nothing to process. - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df LLVFSThread" ) - LLLFSThread::sLocal->pause(); - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) - resumeMainloopTimeout(); - } - pingMainloopTimeout("Main:End"); - } - } - - if (LLApp::isExiting()) - { - // Save snapshot for next time, if we made it through initialization - if (STATE_STARTED == LLStartUp::getStartupState()) - { - saveFinalSnapshot(); - } - - if (LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->terminate(); - } - - delete gServicePump; - gServicePump = NULL; - - destroyMainloopTimeout(); - - LL_INFOS() << "Exiting main_loop" << LL_ENDL; - } + io_pending += LLLFSThread::updateClass(1); + } + + if (io_pending > 1000) + { + ms_sleep(llmin(io_pending/100,100)); // give the lfs some time to catch up + } + + total_work_pending += work_pending ; + total_io_pending += io_pending ; + + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" ) + gMeshRepo.update() ; + } + + if(!total_work_pending) //pause texture fetching threads if nothing to process. + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" ) + LLAppViewer::getTextureCache()->pause(); + LLAppViewer::getTextureFetch()->pause(); + } + if(!total_io_pending) //pause file threads if nothing to process. + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df LLVFSThread" ) + LLLFSThread::sLocal->pause(); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } + pingMainloopTimeout("Main:End"); + } + } + + if (LLApp::isExiting()) + { + // Save snapshot for next time, if we made it through initialization + if (STATE_STARTED == LLStartUp::getStartupState()) + { + saveFinalSnapshot(); + } + + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->terminate(); + } + + delete gServicePump; + gServicePump = NULL; + + destroyMainloopTimeout(); + + LL_INFOS() << "Exiting main_loop" << LL_ENDL; + } }LLPerfStats::StatsRecorder::endFrame(); LL_PROFILER_FRAME_END - return ! LLApp::isRunning(); + return ! LLApp::isRunning(); } S32 LLAppViewer::updateTextureThreads(F32 max_time) { - S32 work_pending = 0; - { + S32 work_pending = 0; + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Texture Cache"); - work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - } - { + work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread + } + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Decode"); - work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - } - { + work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread + } + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Fetch"); - work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - } - return work_pending; + work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread + } + return work_pending; } void LLAppViewer::flushLFSIO() @@ -1709,200 +1709,200 @@ bool LLAppViewer::cleanup() { LLAtmosphere::cleanupClass(); - //ditch LLVOAvatarSelf instance - gAgentAvatarp = NULL; + //ditch LLVOAvatarSelf instance + gAgentAvatarp = NULL; LLNotifications::instance().clear(); - // workaround for DEV-35406 crash on shutdown - LLEventPumps::instance().reset(true); + // workaround for DEV-35406 crash on shutdown + LLEventPumps::instance().reset(true); - //dump scene loading monitor results - if (LLSceneMonitor::instanceExists()) - { - if (!isSecondInstance()) - { + //dump scene loading monitor results + if (LLSceneMonitor::instanceExists()) + { + if (!isSecondInstance()) + { std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"); - LLSceneMonitor::instance().dumpToFile(dump_path); - } - LLSceneMonitor::deleteSingleton(); - } - - // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block - // here, completely redundant with the one that occurs later in this same - // function. Presumably the duplication was due to an automated merge gone - // bad. Not knowing which instance to prefer, we chose to retain the later - // one because it happens just after mFastTimerLogThread is deleted. This - // comment is in case we guessed wrong, so we can move it here instead. + LLSceneMonitor::instance().dumpToFile(dump_path); + } + LLSceneMonitor::deleteSingleton(); + } + + // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block + // here, completely redundant with the one that occurs later in this same + // function. Presumably the duplication was due to an automated merge gone + // bad. Not knowing which instance to prefer, we chose to retain the later + // one because it happens just after mFastTimerLogThread is deleted. This + // comment is in case we guessed wrong, so we can move it here instead. #if LL_LINUX - // remove any old breakpad minidump files from the log directory - if (! isError()) - { - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); - gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp"); - } + // remove any old breakpad minidump files from the log directory + if (! isError()) + { + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp"); + } #endif - // Kill off LLLeap objects. We can find them all because LLLeap is derived - // from LLInstanceTracker. - LLLeap::instance_snapshot().deleteAll(); + // Kill off LLLeap objects. We can find them all because LLLeap is derived + // from LLInstanceTracker. + LLLeap::instance_snapshot().deleteAll(); - //flag all elements as needing to be destroyed immediately - // to ensure shutdown order - LLMortician::setZealous(TRUE); + //flag all elements as needing to be destroyed immediately + // to ensure shutdown order + LLMortician::setZealous(TRUE); // Give any remaining SLPlugin instances a chance to exit cleanly. LLPluginProcessParent::shutdown(); - disconnectViewer(); - LLViewerCamera::deleteSingleton(); + disconnectViewer(); + LLViewerCamera::deleteSingleton(); + + LL_INFOS() << "Viewer disconnected" << LL_ENDL; - LL_INFOS() << "Viewer disconnected" << LL_ENDL; - - if (gKeyboard) - { - gKeyboard->resetKeys(); - } + if (gKeyboard) + { + gKeyboard->resetKeys(); + } - display_cleanup(); + display_cleanup(); - release_start_screen(); // just in case + release_start_screen(); // just in case - LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder + LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder - LL_INFOS() << "Cleaning Up" << LL_ENDL; + LL_INFOS() << "Cleaning Up" << LL_ENDL; - // shut down mesh streamer - gMeshRepo.shutdown(); + // shut down mesh streamer + gMeshRepo.shutdown(); - // shut down Havok - LLPhysicsExtensions::quitSystem(); + // shut down Havok + LLPhysicsExtensions::quitSystem(); - // Must clean up texture references before viewer window is destroyed. - if(LLHUDManager::instanceExists()) - { - LLHUDManager::getInstance()->updateEffects(); - LLHUDObject::updateAll(); - LLHUDManager::getInstance()->cleanupEffects(); - LLHUDObject::cleanupHUDObjects(); - LL_INFOS() << "HUD Objects cleaned up" << LL_ENDL; - } + // Must clean up texture references before viewer window is destroyed. + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->updateEffects(); + LLHUDObject::updateAll(); + LLHUDManager::getInstance()->cleanupEffects(); + LLHUDObject::cleanupHUDObjects(); + LL_INFOS() << "HUD Objects cleaned up" << LL_ENDL; + } - LLKeyframeDataCache::clear(); + LLKeyframeDataCache::clear(); - // End TransferManager before deleting systems it depends on (Audio, AssetStorage) + // End TransferManager before deleting systems it depends on (Audio, AssetStorage) #if 0 // this seems to get us stuck in an infinite loop... - gTransferManager.cleanup(); + gTransferManager.cleanup(); #endif - // Note: this is where gWorldMap used to be deleted. + // Note: this is where gWorldMap used to be deleted. - // Note: this is where gHUDManager used to be deleted. - if(LLHUDManager::instanceExists()) - { - LLHUDManager::getInstance()->shutdownClass(); - } + // Note: this is where gHUDManager used to be deleted. + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->shutdownClass(); + } - delete gAssetStorage; - gAssetStorage = NULL; + delete gAssetStorage; + gAssetStorage = NULL; - LLPolyMesh::freeAllMeshes(); + LLPolyMesh::freeAllMeshes(); - LLStartUp::cleanupNameCache(); + LLStartUp::cleanupNameCache(); - // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. - if (LLWorldMap::instanceExists()) - { - LLWorldMap::getInstance()->reset(); // release any images - } + if (LLWorldMap::instanceExists()) + { + LLWorldMap::getInstance()->reset(); // release any images + } - LLCalc::cleanUp(); + LLCalc::cleanUp(); - LL_INFOS() << "Global stuff deleted" << LL_ENDL; + LL_INFOS() << "Global stuff deleted" << LL_ENDL; - if (gAudiop) - { + if (gAudiop) + { LL_INFOS() << "Shutting down audio" << LL_ENDL; // be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it. gAudiop->stopInternetStream(); // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem. LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl(); - delete sai; - gAudiop->setStreamingAudioImpl(NULL); + delete sai; + gAudiop->setStreamingAudioImpl(NULL); // shut down the audio subsystem gAudiop->shutdown(); - delete gAudiop; - gAudiop = NULL; - } - - // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. + delete gAudiop; + gAudiop = NULL; + } - // Patch up settings for next time - // Must do this before we delete the viewer window, - // such that we can suck rectangle information out of - // it. - cleanupSavedSettings(); - LL_INFOS() << "Settings patched up" << LL_ENDL; + // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. - // delete some of the files left around in the cache. - removeCacheFiles("*.wav"); - removeCacheFiles("*.tmp"); - removeCacheFiles("*.lso"); - removeCacheFiles("*.out"); - removeCacheFiles("*.dsf"); - removeCacheFiles("*.bodypart"); - removeCacheFiles("*.clothing"); + // Patch up settings for next time + // Must do this before we delete the viewer window, + // such that we can suck rectangle information out of + // it. + cleanupSavedSettings(); + LL_INFOS() << "Settings patched up" << LL_ENDL; - LL_INFOS() << "Cache files removed" << LL_ENDL; + // delete some of the files left around in the cache. + removeCacheFiles("*.wav"); + removeCacheFiles("*.tmp"); + removeCacheFiles("*.lso"); + removeCacheFiles("*.out"); + removeCacheFiles("*.dsf"); + removeCacheFiles("*.bodypart"); + removeCacheFiles("*.clothing"); - LL_INFOS() << "Shutting down Views" << LL_ENDL; + LL_INFOS() << "Cache files removed" << LL_ENDL; - // Destroy the UI - if( gViewerWindow) - gViewerWindow->shutdownViews(); + LL_INFOS() << "Shutting down Views" << LL_ENDL; - LL_INFOS() << "Cleaning up Inventory" << LL_ENDL; + // Destroy the UI + if( gViewerWindow) + gViewerWindow->shutdownViews(); - // Cleanup Inventory after the UI since it will delete any remaining observers - // (Deleted observers should have already removed themselves) - gInventory.cleanupInventory(); + LL_INFOS() << "Cleaning up Inventory" << LL_ENDL; - LLCoros::getInstance()->printActiveCoroutines(); + // Cleanup Inventory after the UI since it will delete any remaining observers + // (Deleted observers should have already removed themselves) + gInventory.cleanupInventory(); - LL_INFOS() << "Cleaning up Selections" << LL_ENDL; + LLCoros::getInstance()->printActiveCoroutines(); - // Clean up selection managers after UI is destroyed, as UI may be observing them. - // Clean up before GL is shut down because we might be holding on to objects with texture references - LLSelectMgr::cleanupGlobals(); + LL_INFOS() << "Cleaning up Selections" << LL_ENDL; - LL_INFOS() << "Shutting down OpenGL" << LL_ENDL; + // Clean up selection managers after UI is destroyed, as UI may be observing them. + // Clean up before GL is shut down because we might be holding on to objects with texture references + LLSelectMgr::cleanupGlobals(); - // Shut down OpenGL - if( gViewerWindow) - { - gViewerWindow->shutdownGL(); + LL_INFOS() << "Shutting down OpenGL" << LL_ENDL; - // Destroy window, and make sure we're not fullscreen - // This may generate window reshape and activation events. - // Therefore must do this before destroying the message system. - delete gViewerWindow; - gViewerWindow = NULL; - LL_INFOS() << "ViewerWindow deleted" << LL_ENDL; - } + // Shut down OpenGL + if( gViewerWindow) + { + gViewerWindow->shutdownGL(); + + // Destroy window, and make sure we're not fullscreen + // This may generate window reshape and activation events. + // Therefore must do this before destroying the message system. + delete gViewerWindow; + gViewerWindow = NULL; + LL_INFOS() << "ViewerWindow deleted" << LL_ENDL; + } LLSplashScreen::show(); LLSplashScreen::update(LLTrans::getString("ShuttingDown")); - LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL; + LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL; - // viewer UI relies on keyboard so keep it aound until viewer UI isa gone - delete gKeyboard; - gKeyboard = NULL; + // viewer UI relies on keyboard so keep it aound until viewer UI isa gone + delete gKeyboard; + gKeyboard = NULL; if (LLViewerJoystick::instanceExists()) { @@ -1910,280 +1910,280 @@ bool LLAppViewer::cleanup() LLViewerJoystick::getInstance()->terminate(); } - LL_INFOS() << "Cleaning up Objects" << LL_ENDL; + LL_INFOS() << "Cleaning up Objects" << LL_ENDL; - LLViewerObject::cleanupVOClasses(); + LLViewerObject::cleanupVOClasses(); - SUBSYSTEM_CLEANUP(LLAvatarAppearance); + SUBSYSTEM_CLEANUP(LLAvatarAppearance); - SUBSYSTEM_CLEANUP(LLPostProcess); + SUBSYSTEM_CLEANUP(LLPostProcess); - LLTracker::cleanupInstance(); + LLTracker::cleanupInstance(); - // *FIX: This is handled in LLAppViewerWin32::cleanup(). - // I'm keeping the comment to remember its order in cleanup, - // in case of unforseen dependency. - //#if LL_WINDOWS - // gDXHardware.cleanup(); - //#endif // LL_WINDOWS + // *FIX: This is handled in LLAppViewerWin32::cleanup(). + // I'm keeping the comment to remember its order in cleanup, + // in case of unforseen dependency. + //#if LL_WINDOWS + // gDXHardware.cleanup(); + //#endif // LL_WINDOWS - LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager(); - if (!volume_manager->cleanup()) - { - LL_WARNS() << "Remaining references in the volume manager!" << LL_ENDL; - } - LLPrimitive::cleanupVolumeManager(); + LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager(); + if (!volume_manager->cleanup()) + { + LL_WARNS() << "Remaining references in the volume manager!" << LL_ENDL; + } + LLPrimitive::cleanupVolumeManager(); - LL_INFOS() << "Additional Cleanup..." << LL_ENDL; + LL_INFOS() << "Additional Cleanup..." << LL_ENDL; - LLViewerParcelMgr::cleanupGlobals(); + LLViewerParcelMgr::cleanupGlobals(); - // *Note: this is where gViewerStats used to be deleted. + // *Note: this is where gViewerStats used to be deleted. - //end_messaging_system(); + //end_messaging_system(); - LLPrimitive::cleanupVolumeManager(); - SUBSYSTEM_CLEANUP(LLWorldMapView); - SUBSYSTEM_CLEANUP(LLFolderViewItem); + LLPrimitive::cleanupVolumeManager(); + SUBSYSTEM_CLEANUP(LLWorldMapView); + SUBSYSTEM_CLEANUP(LLFolderViewItem); - LL_INFOS() << "Saving Data" << LL_ENDL; + LL_INFOS() << "Saving Data" << LL_ENDL; - // Store the time of our current logoff - gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); + // Store the time of our current logoff + gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); if (LLEnvironment::instanceExists()) { - //Store environment settings if necessary + //Store environment settings if necessary LLEnvironment::getInstance()->saveToSettings(); } - // Must do this after all panels have been deleted because panels that have persistent rects - // save their rects on delete. - gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - - LLUIColorTable::instance().saveUserSettings(); - - // PerAccountSettingsFile should be empty if no user has been logged on. - // *FIX:Mani This should get really saved in a "logoff" mode. - if (gSavedSettings.getString("PerAccountSettingsFile").empty()) - { - LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL; - } - // Only save per account settings if the previous login succeeded, otherwise - // we might end up with a cleared out settings file in case a previous login - // failed after loading per account settings. - else if (!mSavePerAccountSettings) - { - LL_INFOS() << "Not saving per-account settings; last login was not successful." << LL_ENDL; - } - else - { - gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); - LL_INFOS() << "Saved settings" << LL_ENDL; - - if (LLViewerParcelAskPlay::instanceExists()) - { - LLViewerParcelAskPlay::getInstance()->saveSettings(); - } - } - - std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings")); - gWarningSettings.saveToFile(warnings_settings_filename, TRUE); - - // Save URL history file - LLURLHistory::saveFile("url_history.xml"); - - // save mute list. gMuteList used to also be deleted here too. - if (gAgent.isInitialized() && LLMuteList::instanceExists()) - { - LLMuteList::getInstance()->cache(gAgent.getID()); - } - - //save call log list - if (LLConversationLog::instanceExists()) - { - LLConversationLog::instance().cache(); - } - - clearSecHandler(); + // Must do this after all panels have been deleted because panels that have persistent rects + // save their rects on delete. + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - if (mPurgeCacheOnExit) - { - LL_INFOS() << "Purging all cache files on exit" << LL_ENDL; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); - } - - writeDebugInfo(); - - LLLocationHistory::getInstance()->save(); - - LLAvatarIconIDCache::getInstance()->save(); - - // Stop the plugin read thread if it's running. - LLPluginProcessParent::setUseReadThread(false); - - LL_INFOS() << "Shutting down Threads" << LL_ENDL; - - // Let threads finish - LLTimer idleTimer; - idleTimer.reset(); - const F64 max_idle_time = 5.f; // 5 seconds - while(1) - { - S32 pending = 0; - pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread - pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread - pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread - pending += LLLFSThread::updateClass(0); - F64 idle_time = idleTimer.getElapsedTimeF64(); - if(!pending) - { - break ; //done - } - else if(idle_time >= max_idle_time) - { - LL_WARNS() << "Quitting with pending background tasks." << LL_ENDL; - break; - } - } + LLUIColorTable::instance().saveUserSettings(); - if (mPurgeUserDataOnExit) + // PerAccountSettingsFile should be empty if no user has been logged on. + // *FIX:Mani This should get really saved in a "logoff" mode. + if (gSavedSettings.getString("PerAccountSettingsFile").empty()) { - // Ideally we should not save anything from this session since it is going to be purged now, - // but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code - std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId(); - gDirUtilp->deleteDirAndContents(user_path); + LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL; } + // Only save per account settings if the previous login succeeded, otherwise + // we might end up with a cleared out settings file in case a previous login + // failed after loading per account settings. + else if (!mSavePerAccountSettings) + { + LL_INFOS() << "Not saving per-account settings; last login was not successful." << LL_ENDL; + } + else + { + gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); + LL_INFOS() << "Saved settings" << LL_ENDL; - // Delete workers first - // shotdown all worker threads before deleting them in case of co-dependencies - mAppCoreHttp.requestStop(); - sTextureFetch->shutdown(); - sTextureCache->shutdown(); - sImageDecodeThread->shutdown(); - sPurgeDiskCacheThread->shutdown(); - if (mGeneralThreadPool) - { - mGeneralThreadPool->close(); - } - - sTextureFetch->shutDownTextureCacheThread() ; - LLLFSThread::sLocal->shutdown(); + if (LLViewerParcelAskPlay::instanceExists()) + { + LLViewerParcelAskPlay::getInstance()->saveSettings(); + } + } - LL_INFOS() << "Shutting down message system" << LL_ENDL; - end_messaging_system(); + std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings")); + gWarningSettings.saveToFile(warnings_settings_filename, TRUE); - // Non-LLCurl libcurl library - mAppCoreHttp.cleanup(); + // Save URL history file + LLURLHistory::saveFile("url_history.xml"); - SUBSYSTEM_CLEANUP(LLFilePickerThread); - SUBSYSTEM_CLEANUP(LLDirPickerThread); + // save mute list. gMuteList used to also be deleted here too. + if (gAgent.isInitialized() && LLMuteList::instanceExists()) + { + LLMuteList::getInstance()->cache(gAgent.getID()); + } - //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl) - delete sTextureCache; - sTextureCache = NULL; - if (sTextureFetch) + //save call log list + if (LLConversationLog::instanceExists()) + { + LLConversationLog::instance().cache(); + } + + clearSecHandler(); + + if (mPurgeCacheOnExit) + { + LL_INFOS() << "Purging all cache files on exit" << LL_ENDL; + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); + } + + writeDebugInfo(); + + LLLocationHistory::getInstance()->save(); + + LLAvatarIconIDCache::getInstance()->save(); + + // Stop the plugin read thread if it's running. + LLPluginProcessParent::setUseReadThread(false); + + LL_INFOS() << "Shutting down Threads" << LL_ENDL; + + // Let threads finish + LLTimer idleTimer; + idleTimer.reset(); + const F64 max_idle_time = 5.f; // 5 seconds + while(1) + { + S32 pending = 0; + pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread + pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread + pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread + pending += LLLFSThread::updateClass(0); + F64 idle_time = idleTimer.getElapsedTimeF64(); + if(!pending) + { + break ; //done + } + else if(idle_time >= max_idle_time) + { + LL_WARNS() << "Quitting with pending background tasks." << LL_ENDL; + break; + } + } + + if (mPurgeUserDataOnExit) + { + // Ideally we should not save anything from this session since it is going to be purged now, + // but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code + std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId(); + gDirUtilp->deleteDirAndContents(user_path); + } + + // Delete workers first + // shotdown all worker threads before deleting them in case of co-dependencies + mAppCoreHttp.requestStop(); + sTextureFetch->shutdown(); + sTextureCache->shutdown(); + sImageDecodeThread->shutdown(); + sPurgeDiskCacheThread->shutdown(); + if (mGeneralThreadPool) + { + mGeneralThreadPool->close(); + } + + sTextureFetch->shutDownTextureCacheThread() ; + LLLFSThread::sLocal->shutdown(); + + LL_INFOS() << "Shutting down message system" << LL_ENDL; + end_messaging_system(); + + // Non-LLCurl libcurl library + mAppCoreHttp.cleanup(); + + SUBSYSTEM_CLEANUP(LLFilePickerThread); + SUBSYSTEM_CLEANUP(LLDirPickerThread); + + //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl) + delete sTextureCache; + sTextureCache = NULL; + if (sTextureFetch) { sTextureFetch->shutdown(); sTextureFetch->waitOnPending(); delete sTextureFetch; sTextureFetch = NULL; } - delete sImageDecodeThread; + delete sImageDecodeThread; sImageDecodeThread = NULL; - delete mFastTimerLogThread; - mFastTimerLogThread = NULL; - delete sPurgeDiskCacheThread; - sPurgeDiskCacheThread = NULL; + delete mFastTimerLogThread; + mFastTimerLogThread = NULL; + delete sPurgeDiskCacheThread; + sPurgeDiskCacheThread = NULL; delete mGeneralThreadPool; mGeneralThreadPool = NULL; - if (LLFastTimerView::sAnalyzePerformance) - { - LL_INFOS() << "Analyzing performance" << LL_ENDL; + if (LLFastTimerView::sAnalyzePerformance) + { + LL_INFOS() << "Analyzing performance" << LL_ENDL; - std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; - std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; - std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; + std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; + std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; + std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; - LLFastTimerView::doAnalysis( - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); - } + LLFastTimerView::doAnalysis( + gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), + gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), + gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); + } - SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; + SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; - LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL; + LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL; - //Note: - //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown() - //because some new image might be generated during cleaning up media. --bao - gTextureList.shutdown(); // shutdown again in case a callback added something - LLUIImageList::getInstance()->cleanUp(); + //Note: + //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown() + //because some new image might be generated during cleaning up media. --bao + gTextureList.shutdown(); // shutdown again in case a callback added something + LLUIImageList::getInstance()->cleanUp(); - SUBSYSTEM_CLEANUP(LLImage); - SUBSYSTEM_CLEANUP(LLLFSThread); + SUBSYSTEM_CLEANUP(LLImage); + SUBSYSTEM_CLEANUP(LLLFSThread); - LL_INFOS() << "Misc Cleanup" << LL_ENDL; + LL_INFOS() << "Misc Cleanup" << LL_ENDL; - gSavedSettings.cleanup(); - LLUIColorTable::instance().clear(); + gSavedSettings.cleanup(); + LLUIColorTable::instance().clear(); - LLWatchdog::getInstance()->cleanup(); + LLWatchdog::getInstance()->cleanup(); - LLViewerAssetStatsFF::cleanup(); + LLViewerAssetStatsFF::cleanup(); - // If we're exiting to launch an URL, do that here so the screen - // is at the right resolution before we launch IE. - if (!gLaunchFileOnQuit.empty()) - { - LL_INFOS() << "Launch file on quit." << LL_ENDL; + // If we're exiting to launch an URL, do that here so the screen + // is at the right resolution before we launch IE. + if (!gLaunchFileOnQuit.empty()) + { + LL_INFOS() << "Launch file on quit." << LL_ENDL; #if LL_WINDOWS - // Indicate an application is starting. - SetCursor(LoadCursor(NULL, IDC_WAIT)); + // Indicate an application is starting. + SetCursor(LoadCursor(NULL, IDC_WAIT)); #endif - // HACK: Attempt to wait until the screen res. switch is complete. - ms_sleep(1000); + // HACK: Attempt to wait until the screen res. switch is complete. + ms_sleep(1000); - LLWeb::loadURLExternal( gLaunchFileOnQuit, false ); - LL_INFOS() << "File launched." << LL_ENDL; - } - // make sure nothing uses applyProxySettings by this point. - LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL; - SUBSYSTEM_CLEANUP(LLProxy); + LLWeb::loadURLExternal( gLaunchFileOnQuit, false ); + LL_INFOS() << "File launched." << LL_ENDL; + } + // make sure nothing uses applyProxySettings by this point. + LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL; + SUBSYSTEM_CLEANUP(LLProxy); LLCore::LLHttp::cleanup(); - ll_close_fail_log(); + ll_close_fail_log(); - LLError::LLCallStacks::cleanup(); + LLError::LLCallStacks::cleanup(); LL::GLTFSceneManager::deleteSingleton(); - LLEnvironment::deleteSingleton(); - LLSelectMgr::deleteSingleton(); - LLViewerEventRecorder::deleteSingleton(); + LLEnvironment::deleteSingleton(); + LLSelectMgr::deleteSingleton(); + LLViewerEventRecorder::deleteSingleton(); LLWorld::deleteSingleton(); LLVoiceClient::deleteSingleton(); - // It's not at first obvious where, in this long sequence, a generic cleanup - // call OUGHT to go. So let's say this: as we migrate cleanup from - // explicit hand-placed calls into the generic mechanism, eventually - // all cleanup will get subsumed into the generic call. So the calls you - // still see above are calls that MUST happen before the generic cleanup - // kicks in. + // It's not at first obvious where, in this long sequence, a generic cleanup + // call OUGHT to go. So let's say this: as we migrate cleanup from + // explicit hand-placed calls into the generic mechanism, eventually + // all cleanup will get subsumed into the generic call. So the calls you + // still see above are calls that MUST happen before the generic cleanup + // kicks in. - // This calls every remaining LLSingleton's cleanupSingleton() and - // deleteSingleton() methods. - LLSingletonBase::deleteAll(); + // This calls every remaining LLSingleton's cleanupSingleton() and + // deleteSingleton() methods. + LLSingletonBase::deleteAll(); LLSplashScreen::hide(); LL_INFOS() << "Goodbye!" << LL_ENDL; - removeDumpDir(); + removeDumpDir(); - // return 0; - return true; + // return 0; + return true; } void LLAppViewer::initGeneralThread() @@ -2199,11 +2199,11 @@ void LLAppViewer::initGeneralThread() bool LLAppViewer::initThreads() { - static const bool enable_threads = true; + static const bool enable_threads = true; - LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); + LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); - LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo + LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo //auto configure thread count LLSD threadCounts = gSavedSettings.getLLSD("ThreadPoolSizes"); @@ -2218,39 +2218,39 @@ bool LLAppViewer::initThreads() } // The only configurable thread count right now is ImageDecode - // The viewer typically starts around 8 threads not including image decode, + // The viewer typically starts around 8 threads not including image decode, // so try to leave at least one core free S32 image_decode_count = llclamp(cores - 9, 1, 8); threadCounts["ImageDecode"] = image_decode_count; gSavedSettings.setLLSD("ThreadPoolSizes", threadCounts); - // Image decoding - LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true); - LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); - LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), - enable_threads && true, - app_metrics_qa_mode); + // Image decoding + LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true); + LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); + LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), + enable_threads && true, + app_metrics_qa_mode); // general task background thread (LLPerfStats, etc) LLAppViewer::instance()->initGeneralThread(); - LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread(); + LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread(); - if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) - { - LLTrace::BlockTimer::setLogLock(new LLMutex()); - mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName); - mFastTimerLogThread->start(); - } + if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) + { + LLTrace::BlockTimer::setLogLock(new LLMutex()); + mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName); + mFastTimerLogThread->start(); + } - // Mesh streaming and caching - gMeshRepo.init(); + // Mesh streaming and caching + gMeshRepo.init(); - LLFilePickerThread::initClass(); - LLDirPickerThread::initClass(); + LLFilePickerThread::initClass(); + LLDirPickerThread::initClass(); - // *FIX: no error handling here! - return true; + // *FIX: no error handling here! + return true; } void errorCallback(LLError::ELevel level, const std::string &error_string) @@ -2294,7 +2294,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() if (mSecondInstance) { LLFile::mkdir(gDirUtilp->getDumpLogsDirPath()); - + LLUUID uid; uid.generate(); LLError::logToFile(gDirUtilp->getDumpLogsDirPath(uid.asString() + ".log")); @@ -2365,123 +2365,123 @@ void LLAppViewer::initLoggingAndGetLastDuration() } bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, - bool set_defaults) + bool set_defaults) { - if (!mSettingsLocationList) - { - LL_ERRS() << "Invalid settings location list" << LL_ENDL; - } - - for (const SettingsGroup& group : mSettingsLocationList->groups) - { - // skip settings groups that aren't the one we requested - if (group.name() != location_key) continue; - - ELLPath path_index = (ELLPath)group.path_index(); - if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST) - { - LL_ERRS() << "Out of range path index in app_settings/settings_files.xml" << LL_ENDL; - return false; - } - - for (const SettingsFile& file : group.files) - { - LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name() - << " - from location " << location_key << LL_ENDL; - - auto settings_group = LLControlGroup::getInstance(file.name); - if(!settings_group) - { - LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL; - continue; - } - - std::string full_settings_path; - - if (file.file_name_setting.isProvided() - && gSavedSettings.controlExists(file.file_name_setting)) - { - // try to find filename stored in file_name_setting control - full_settings_path = gSavedSettings.getString(file.file_name_setting); - if (full_settings_path.empty()) - { - continue; - } - else if (!gDirUtilp->fileExists(full_settings_path)) - { - // search in default path - full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, full_settings_path); - } - } - else - { - // by default, use specified file name - full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name()); - } - - if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent)) - { // success! - LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL; - } - else - { // failed to load - if(file.required) - { + if (!mSettingsLocationList) + { + LL_ERRS() << "Invalid settings location list" << LL_ENDL; + } + + for (const SettingsGroup& group : mSettingsLocationList->groups) + { + // skip settings groups that aren't the one we requested + if (group.name() != location_key) continue; + + ELLPath path_index = (ELLPath)group.path_index(); + if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST) + { + LL_ERRS() << "Out of range path index in app_settings/settings_files.xml" << LL_ENDL; + return false; + } + + for (const SettingsFile& file : group.files) + { + LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name() + << " - from location " << location_key << LL_ENDL; + + auto settings_group = LLControlGroup::getInstance(file.name); + if(!settings_group) + { + LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL; + continue; + } + + std::string full_settings_path; + + if (file.file_name_setting.isProvided() + && gSavedSettings.controlExists(file.file_name_setting)) + { + // try to find filename stored in file_name_setting control + full_settings_path = gSavedSettings.getString(file.file_name_setting); + if (full_settings_path.empty()) + { + continue; + } + else if (!gDirUtilp->fileExists(full_settings_path)) + { + // search in default path + full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, full_settings_path); + } + } + else + { + // by default, use specified file name + full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name()); + } + + if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent)) + { // success! + LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL; + } + else + { // failed to load + if(file.required) + { LLError::LLUserWarningMsg::showMissingFiles(); - LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL; - return false; - } - else - { - // only complain if we actually have a filename at this point - if (!full_settings_path.empty()) - { - LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL; - } - } - } - } - } - - return true; + LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL; + return false; + } + else + { + // only complain if we actually have a filename at this point + if (!full_settings_path.empty()) + { + LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL; + } + } + } + } + } + + return true; } std::string LLAppViewer::getSettingsFilename(const std::string& location_key, - const std::string& file) + const std::string& file) { - for (const SettingsGroup& group : mSettingsLocationList->groups) - { - if (group.name() == location_key) - { - for (const SettingsFile& settings_file : group.files) - { - if (settings_file.name() == file) - { - return settings_file.file_name; - } - } - } - } - - return std::string(); + for (const SettingsGroup& group : mSettingsLocationList->groups) + { + if (group.name() == location_key) + { + for (const SettingsFile& settings_file : group.files) + { + if (settings_file.name() == file) + { + return settings_file.file_name; + } + } + } + } + + return std::string(); } void LLAppViewer::loadColorSettings() { - LLUIColorTable::instance().loadFromSettings(); + LLUIColorTable::instance().loadFromSettings(); } namespace { void handleCommandLineError(LLControlGroupCLP& clp) { - LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL; + LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL; - LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL; + LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL; - OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()), - LLStringUtil::null, - OSMB_OK); + OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()), + LLStringUtil::null, + OSMB_OK); } } // anonymous namespace @@ -2489,42 +2489,42 @@ namespace // Name can be specified as ".", with default group being Global. bool tempSetControl(const std::string& name, const std::string& value) { - std::string name_part; - std::string group_part; - LLControlVariable* control = NULL; - - // Name can be further split into ControlGroup.Name, with the default control group being Global - size_t pos = name.find('.'); - if (pos != std::string::npos) - { - group_part = name.substr(0, pos); - name_part = name.substr(pos+1); - LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; - auto g = LLControlGroup::getInstance(group_part); - if (g) control = g->getControl(name_part); - } - else - { - LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; - control = gSavedSettings.getControl(name); - } - - if (control) - { - control->setValue(value, false); - return true; - } - return false; + std::string name_part; + std::string group_part; + LLControlVariable* control = NULL; + + // Name can be further split into ControlGroup.Name, with the default control group being Global + size_t pos = name.find('.'); + if (pos != std::string::npos) + { + group_part = name.substr(0, pos); + name_part = name.substr(pos+1); + LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; + auto g = LLControlGroup::getInstance(group_part); + if (g) control = g->getControl(name_part); + } + else + { + LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; + control = gSavedSettings.getControl(name); + } + + if (control) + { + control->setValue(value, false); + return true; + } + return false; } bool LLAppViewer::initConfiguration() { - //Load settings files list - std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); - LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); - if (!success) - { + //Load settings files list + std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); + LLXMLNodePtr root; + BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); + if (!success) + { LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; LLError::LLUserWarningMsg::showMissingFiles(); if (gDirUtilp->fileExists(settings_file_list)) @@ -2541,175 +2541,175 @@ bool LLAppViewer::initConfiguration() << "and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; } - } + } - mSettingsLocationList = new SettingsFiles(); + mSettingsLocationList = new SettingsFiles(); - LLXUIParser parser; - parser.readXUI(root, *mSettingsLocationList, settings_file_list); + LLXUIParser parser; + parser.readXUI(root, *mSettingsLocationList, settings_file_list); - if (!mSettingsLocationList->validateBlock()) - { + if (!mSettingsLocationList->validateBlock()) + { LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL; - } - - // The settings and command line parsing have a fragile - // order-of-operation: - // - load defaults from app_settings - // - set procedural settings values - // - read command line settings - // - selectively apply settings needed to load user settings. + } + + // The settings and command line parsing have a fragile + // order-of-operation: + // - load defaults from app_settings + // - set procedural settings values + // - read command line settings + // - selectively apply settings needed to load user settings. // - load overrides from user_settings - // - apply command line settings (to override the overrides) - // - load per account settings (happens in llstartup - - // - load defaults - bool set_defaults = true; - if(!loadSettingsFromDirectory("Default", set_defaults)) - { - OSMessageBox( - "Unable to load default settings file. The installation may be corrupted.", - LLStringUtil::null,OSMB_OK); - return false; - } - - initStrings(); // setup paths for LLTrans based on settings files only - // - set procedural settings - // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet - gSavedSettings.setString("ClientSettingsFile", + // - apply command line settings (to override the overrides) + // - load per account settings (happens in llstartup + + // - load defaults + bool set_defaults = true; + if(!loadSettingsFromDirectory("Default", set_defaults)) + { + OSMessageBox( + "Unable to load default settings file. The installation may be corrupted.", + LLStringUtil::null,OSMB_OK); + return false; + } + + initStrings(); // setup paths for LLTrans based on settings files only + // - set procedural settings + // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet + gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); -#ifndef LL_RELEASE_FOR_DOWNLOAD - // provide developer build only overrides for these control variables that are not - // persisted to settings.xml - LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers"); - if (c) - { - c->setValue(true, false); - } - - gSavedSettings.setBOOL("QAMode", TRUE ); - gSavedSettings.setS32("WatchdogEnabled", 0); +#ifndef LL_RELEASE_FOR_DOWNLOAD + // provide developer build only overrides for these control variables that are not + // persisted to settings.xml + LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers"); + if (c) + { + c->setValue(true, false); + } + + gSavedSettings.setBOOL("QAMode", TRUE ); + gSavedSettings.setS32("WatchdogEnabled", 0); #endif - // These are warnings that appear on the first experience of that condition. - // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse - // for disable/reset ability -// LLFirstUse::addConfigVariable("FirstBalanceIncrease"); -// LLFirstUse::addConfigVariable("FirstBalanceDecrease"); -// LLFirstUse::addConfigVariable("FirstSit"); -// LLFirstUse::addConfigVariable("FirstMap"); -// LLFirstUse::addConfigVariable("FirstGoTo"); -// LLFirstUse::addConfigVariable("FirstBuild"); -// LLFirstUse::addConfigVariable("FirstLeftClickNoHit"); -// LLFirstUse::addConfigVariable("FirstTeleport"); -// LLFirstUse::addConfigVariable("FirstOverrideKeys"); -// LLFirstUse::addConfigVariable("FirstAttach"); -// LLFirstUse::addConfigVariable("FirstAppearance"); -// LLFirstUse::addConfigVariable("FirstInventory"); -// LLFirstUse::addConfigVariable("FirstSandbox"); -// LLFirstUse::addConfigVariable("FirstFlexible"); -// LLFirstUse::addConfigVariable("FirstDebugMenus"); -// LLFirstUse::addConfigVariable("FirstSculptedPrim"); -// LLFirstUse::addConfigVariable("FirstVoice"); -// LLFirstUse::addConfigVariable("FirstMedia"); - - // - read command line settings. - LLControlGroupCLP clp; - std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, - "cmd_line.xml"); - - clp.configure(cmd_line_config, &gSavedSettings); - - if(!initParseCommandLine(clp)) - { - handleCommandLineError(clp); - return false; - } - - // - selectively apply settings - - // If the user has specified a alternate settings file name. - // Load it now before loading the user_settings/settings.xml - if(clp.hasOption("settings")) - { - std::string user_settings_filename = - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, - clp.getOption("settings")[0]); - gSavedSettings.setString("ClientSettingsFile", user_settings_filename); - LL_INFOS("Settings") << "Using command line specified settings filename: " - << user_settings_filename << LL_ENDL; - } - - // - load overrides from user_settings - loadSettingsFromDirectory("User"); - - if (gSavedSettings.getBOOL("FirstRunThisInstall")) - { - // Set firstrun flag to indicate that some further init actiona should be taken - // like determining screen DPI value and so on - mIsFirstRun = true; - - gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); - } - - if (clp.hasOption("sessionsettings")) - { - std::string session_settings_filename = clp.getOption("sessionsettings")[0]; - gSavedSettings.setString("SessionSettingsFile", session_settings_filename); - LL_INFOS("Settings") << "Using session settings filename: " - << session_settings_filename << LL_ENDL; - } - loadSettingsFromDirectory("Session"); - - if (clp.hasOption("usersessionsettings")) - { - std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0]; - gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename); - LL_INFOS("Settings") << "Using user session settings filename: " - << user_session_settings_filename << LL_ENDL; - - } - loadSettingsFromDirectory("UserSession"); - - // - apply command line settings - if (! clp.notify()) - { - handleCommandLineError(clp); - return false; - } - - // Register the core crash option as soon as we can - // if we want gdb post-mortem on cores we need to be up and running - // ASAP or we might miss init issue etc. - if(gSavedSettings.getBOOL("DisableCrashLogger")) - { - LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL; - disableCrashlogger(); - } - - gNonInteractive = gSavedSettings.getBOOL("NonInteractive"); - // Handle initialization from settings. - // Start up the debugging console before handling other options. - if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive) - { - initConsole(); - } - - if(clp.hasOption("help")) - { - std::ostringstream msg; - msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp; - LL_INFOS() << msg.str() << LL_ENDL; - - OSMessageBox( - msg.str(), - LLStringUtil::null, - OSMB_OK); - - return false; - } + // These are warnings that appear on the first experience of that condition. + // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse + // for disable/reset ability +// LLFirstUse::addConfigVariable("FirstBalanceIncrease"); +// LLFirstUse::addConfigVariable("FirstBalanceDecrease"); +// LLFirstUse::addConfigVariable("FirstSit"); +// LLFirstUse::addConfigVariable("FirstMap"); +// LLFirstUse::addConfigVariable("FirstGoTo"); +// LLFirstUse::addConfigVariable("FirstBuild"); +// LLFirstUse::addConfigVariable("FirstLeftClickNoHit"); +// LLFirstUse::addConfigVariable("FirstTeleport"); +// LLFirstUse::addConfigVariable("FirstOverrideKeys"); +// LLFirstUse::addConfigVariable("FirstAttach"); +// LLFirstUse::addConfigVariable("FirstAppearance"); +// LLFirstUse::addConfigVariable("FirstInventory"); +// LLFirstUse::addConfigVariable("FirstSandbox"); +// LLFirstUse::addConfigVariable("FirstFlexible"); +// LLFirstUse::addConfigVariable("FirstDebugMenus"); +// LLFirstUse::addConfigVariable("FirstSculptedPrim"); +// LLFirstUse::addConfigVariable("FirstVoice"); +// LLFirstUse::addConfigVariable("FirstMedia"); + + // - read command line settings. + LLControlGroupCLP clp; + std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + "cmd_line.xml"); + + clp.configure(cmd_line_config, &gSavedSettings); + + if(!initParseCommandLine(clp)) + { + handleCommandLineError(clp); + return false; + } + + // - selectively apply settings + + // If the user has specified a alternate settings file name. + // Load it now before loading the user_settings/settings.xml + if(clp.hasOption("settings")) + { + std::string user_settings_filename = + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, + clp.getOption("settings")[0]); + gSavedSettings.setString("ClientSettingsFile", user_settings_filename); + LL_INFOS("Settings") << "Using command line specified settings filename: " + << user_settings_filename << LL_ENDL; + } + + // - load overrides from user_settings + loadSettingsFromDirectory("User"); + + if (gSavedSettings.getBOOL("FirstRunThisInstall")) + { + // Set firstrun flag to indicate that some further init actiona should be taken + // like determining screen DPI value and so on + mIsFirstRun = true; + + gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); + } + + if (clp.hasOption("sessionsettings")) + { + std::string session_settings_filename = clp.getOption("sessionsettings")[0]; + gSavedSettings.setString("SessionSettingsFile", session_settings_filename); + LL_INFOS("Settings") << "Using session settings filename: " + << session_settings_filename << LL_ENDL; + } + loadSettingsFromDirectory("Session"); + + if (clp.hasOption("usersessionsettings")) + { + std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0]; + gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename); + LL_INFOS("Settings") << "Using user session settings filename: " + << user_session_settings_filename << LL_ENDL; + + } + loadSettingsFromDirectory("UserSession"); + + // - apply command line settings + if (! clp.notify()) + { + handleCommandLineError(clp); + return false; + } + + // Register the core crash option as soon as we can + // if we want gdb post-mortem on cores we need to be up and running + // ASAP or we might miss init issue etc. + if(gSavedSettings.getBOOL("DisableCrashLogger")) + { + LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL; + disableCrashlogger(); + } + + gNonInteractive = gSavedSettings.getBOOL("NonInteractive"); + // Handle initialization from settings. + // Start up the debugging console before handling other options. + if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive) + { + initConsole(); + } + + if(clp.hasOption("help")) + { + std::ostringstream msg; + msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp; + LL_INFOS() << msg.str() << LL_ENDL; + + OSMessageBox( + msg.str(), + LLStringUtil::null, + OSMB_OK); + + return false; + } if(clp.hasOption("set")) { @@ -2727,43 +2727,43 @@ bool LLAppViewer::initConfiguration() const std::string& value = *(++itr); if (!tempSetControl(name,value)) { - LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL; + LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL; } } } } if (clp.hasOption("logevents")) { - LLViewerEventRecorder::instance().setEventLoggingOn(); + LLViewerEventRecorder::instance().setEventLoggingOn(); } - std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); - if(! CmdLineChannel.empty()) + std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); + if(! CmdLineChannel.empty()) { - LLVersionInfo::instance().resetChannel(CmdLineChannel); - } + LLVersionInfo::instance().resetChannel(CmdLineChannel); + } - // If we have specified crash on startup, set the global so we'll trigger the crash at the right time - gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup"); + // If we have specified crash on startup, set the global so we'll trigger the crash at the right time + gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup"); - if (gSavedSettings.getBOOL("LogPerformance")) - { - LLTrace::BlockTimer::sLog = true; - LLTrace::BlockTimer::sLogName = std::string("performance"); - } + if (gSavedSettings.getBOOL("LogPerformance")) + { + LLTrace::BlockTimer::sLog = true; + LLTrace::BlockTimer::sLogName = std::string("performance"); + } - std::string test_name(gSavedSettings.getString("LogMetrics")); - if (! test_name.empty()) - { - LLTrace::BlockTimer::sMetricLog = TRUE; - // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test - // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...) - LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL; - LLTrace::BlockTimer::sLogName = test_name; - } + std::string test_name(gSavedSettings.getString("LogMetrics")); + if (! test_name.empty()) + { + LLTrace::BlockTimer::sMetricLog = TRUE; + // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test + // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...) + LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL; + LLTrace::BlockTimer::sLogName = test_name; + } - if (clp.hasOption("graphicslevel")) - { + if (clp.hasOption("graphicslevel")) + { // User explicitly requested --graphicslevel on the command line. We // expect this switch has already set RenderQualityPerformance. Check // that value for validity later. @@ -2772,18 +2772,18 @@ bool LLAppViewer::initConfiguration() // will call LLFeatureManager::applyRecommendedSettings(), which // overwrites this settings variable! mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance"); - } + } - LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); - gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession")); + LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); + gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession")); - if (gSavedSettings.getBOOL("DebugSession")) - { - gDebugSession = TRUE; - gDebugGL = TRUE; + if (gSavedSettings.getBOOL("DebugSession")) + { + gDebugSession = TRUE; + gDebugGL = TRUE; - ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log")); - } + ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log")); + } if (gSavedSettings.getBOOL("RenderDebugGLSession")) { @@ -2794,47 +2794,47 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setBOOL("RenderDebugGLSession", FALSE); } - const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); - if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) - { - // Examining "Language" may not suffice -- see LLUI::getLanguage() - // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much - // good because we haven't yet called LLUI::initClass(). - gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), - gSavedSettings.getString("Language")); - } - - if (gSavedSettings.getBOOL("SpellCheck")) - { - std::list dict_list; - std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); - boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); - if (!dict_list.empty()) - { - LLSpellChecker::setUseSpellCheck(dict_list.front()); - dict_list.pop_front(); - LLSpellChecker::instance().setSecondaryDictionaries(dict_list); - } - } - - if (gNonInteractive) - { - tempSetControl("AllowMultipleViewers", "TRUE"); - tempSetControl("SLURLPassToOtherInstance", "FALSE"); - tempSetControl("RenderWater", "FALSE"); - tempSetControl("FlyingAtExit", "FALSE"); - tempSetControl("WindowWidth", "1024"); - tempSetControl("WindowHeight", "200"); - LLError::setEnabledLogTypesMask(0); - llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance")); - } - - - // Handle slurl use. NOTE: Don't let SL-55321 reappear. - // This initial-SLURL logic, up through the call to - // sendURLToOtherInstance(), must precede LLSplashScreen::show() -- - // because if sendURLToOtherInstance() succeeds, we take a fast exit, - // SKIPPING the splash screen and everything else. + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); + if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) + { + // Examining "Language" may not suffice -- see LLUI::getLanguage() + // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much + // good because we haven't yet called LLUI::initClass(). + gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), + gSavedSettings.getString("Language")); + } + + if (gSavedSettings.getBOOL("SpellCheck")) + { + std::list dict_list; + std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); + boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); + if (!dict_list.empty()) + { + LLSpellChecker::setUseSpellCheck(dict_list.front()); + dict_list.pop_front(); + LLSpellChecker::instance().setSecondaryDictionaries(dict_list); + } + } + + if (gNonInteractive) + { + tempSetControl("AllowMultipleViewers", "TRUE"); + tempSetControl("SLURLPassToOtherInstance", "FALSE"); + tempSetControl("RenderWater", "FALSE"); + tempSetControl("FlyingAtExit", "FALSE"); + tempSetControl("WindowWidth", "1024"); + tempSetControl("WindowHeight", "200"); + LLError::setEnabledLogTypesMask(0); + llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance")); + } + + + // Handle slurl use. NOTE: Don't let SL-55321 reappear. + // This initial-SLURL logic, up through the call to + // sendURLToOtherInstance(), must precede LLSplashScreen::show() -- + // because if sendURLToOtherInstance() succeeds, we take a fast exit, + // SKIPPING the splash screen and everything else. // *FIX: This init code should be made more robust to prevent // the issue SL-55321 from returning. One thought is to allow @@ -2852,143 +2852,143 @@ bool LLAppViewer::initConfiguration() // other browsers) and do the rough equivalent of command // injection and steal passwords. Phoenix. SL-55321 - std::string starting_location; - - std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation")); - if(! cmd_line_login_location.empty()) - { - starting_location = cmd_line_login_location; - } - else - { - std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation")); - if (! default_login_location.empty()) - { - starting_location = default_login_location; - } - } - - LLSLURL start_slurl; - if (! starting_location.empty()) - { - start_slurl = starting_location; - LLStartUp::setStartSLURL(start_slurl); - if(start_slurl.getType() == LLSLURL::LOCATION) - { - LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); - } - } - - // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL() - std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); - if ( !nextLoginLocation.empty() ) - { - LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<useMutex(); // LLApp and LLMutex magic must be manually enabled - LLPrimitive::setVolumeManager(volume_manager); - - // Note: this is where we used to initialize gFeatureManagerp. - - gStartTime = totalTime(); - - // - // Set the name of the window - // - gWindowTitle = LLTrans::getString("APP_NAME"); + std::string starting_location; + + std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation")); + if(! cmd_line_login_location.empty()) + { + starting_location = cmd_line_login_location; + } + else + { + std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation")); + if (! default_login_location.empty()) + { + starting_location = default_login_location; + } + } + + LLSLURL start_slurl; + if (! starting_location.empty()) + { + start_slurl = starting_location; + LLStartUp::setStartSLURL(start_slurl); + if(start_slurl.getType() == LLSLURL::LOCATION) + { + LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); + } + } + + // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL() + std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); + if ( !nextLoginLocation.empty() ) + { + LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<useMutex(); // LLApp and LLMutex magic must be manually enabled + LLPrimitive::setVolumeManager(volume_manager); + + // Note: this is where we used to initialize gFeatureManagerp. + + gStartTime = totalTime(); + + // + // Set the name of the window + // + gWindowTitle = LLTrans::getString("APP_NAME"); #if LL_DEBUG - gWindowTitle += std::string(" [DEBUG]"); + gWindowTitle += std::string(" [DEBUG]"); #endif - if (!gArgs.empty()) - { - gWindowTitle += std::string(" ") + gArgs; - } - LLStringUtil::truncate(gWindowTitle, 255); - - // - // Check for another instance of the app running - // This happens AFTER LLSplashScreen::show(). That may or may not be - // important. - // - if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers")) - { - OSMessageBox( - LLTrans::getString("MBAlreadyRunning"), - LLStringUtil::null, - OSMB_OK); - return false; - } - - if (mSecondInstance) - { - // This is the second instance of SL. Mute voice, - // but make sure the setting is *not* persisted. - // Also see LLVivoxVoiceClient::voiceEnabled() - LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat"); - if(enable_voice) - { - const BOOL DO_NOT_PERSIST = FALSE; - enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST); - } - } - - gLastRunVersion = gSavedSettings.getString("LastRunVersion"); - - loadColorSettings(); - - // Let anyone else who cares know that we've populated our settings - // variables. - for (const auto& key : LLControlGroup::key_snapshot()) - { - // For each named instance of LLControlGroup, send an event saying - // we've initialized an LLControlGroup instance by that name. - LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key)); - } + if (!gArgs.empty()) + { + gWindowTitle += std::string(" ") + gArgs; + } + LLStringUtil::truncate(gWindowTitle, 255); + + // + // Check for another instance of the app running + // This happens AFTER LLSplashScreen::show(). That may or may not be + // important. + // + if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers")) + { + OSMessageBox( + LLTrans::getString("MBAlreadyRunning"), + LLStringUtil::null, + OSMB_OK); + return false; + } + + if (mSecondInstance) + { + // This is the second instance of SL. Mute voice, + // but make sure the setting is *not* persisted. + // Also see LLVivoxVoiceClient::voiceEnabled() + LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat"); + if(enable_voice) + { + const BOOL DO_NOT_PERSIST = FALSE; + enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST); + } + } + + gLastRunVersion = gSavedSettings.getString("LastRunVersion"); + + loadColorSettings(); + + // Let anyone else who cares know that we've populated our settings + // variables. + for (const auto& key : LLControlGroup::key_snapshot()) + { + // For each named instance of LLControlGroup, send an event saying + // we've initialized an LLControlGroup instance by that name. + LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key)); + } LLError::LLUserWarningMsg::setOutOfMemoryStrings(LLTrans::getString("MBOutOfMemoryTitle"), LLTrans::getString("MBOutOfMemoryErr")); - return true; // Config was successful. + return true; // Config was successful. } // The following logic is replicated in initConfiguration() (to be able to get @@ -2997,214 +2997,214 @@ bool LLAppViewer::initConfiguration() // keeps growing, necessitating a method all its own. void LLAppViewer::initStrings() { - std::string strings_file = "strings.xml"; - std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); - if (strings_path_full.empty() || !LLFile::isfile(strings_path_full)) - { - if (strings_path_full.empty()) - { - LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL; - } - else - { - llstat st; - int rc = LLFile::stat(strings_path_full, &st); - if (rc != 0) - { - LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL; - } - else if (S_ISDIR(st.st_mode)) - { - LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL; - } - else - { - LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL; - } - } - - // initial check to make sure files are there failed - gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); + std::string strings_file = "strings.xml"; + std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); + if (strings_path_full.empty() || !LLFile::isfile(strings_path_full)) + { + if (strings_path_full.empty()) + { + LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL; + } + else + { + llstat st; + int rc = LLFile::stat(strings_path_full, &st); + if (rc != 0) + { + LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL; + } + else if (S_ISDIR(st.st_mode)) + { + LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL; + } + else + { + LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL; + } + } + + // initial check to make sure files are there failed + gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); LLError::LLUserWarningMsg::showMissingFiles(); - LL_ERRS() << "Viewer failed to find localization and UI files." - << " Please reinstall viewer from https://secondlife.com/support/downloads" - << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; - } - LLTransUtil::parseStrings(strings_file, default_trans_args); - LLTransUtil::parseLanguageStrings("language_settings.xml"); - - // parseStrings() sets up the LLTrans substitution table. Add this one item. - LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid")); - - // Now that we've set "[sourceid]", have to go back through - // default_trans_args and reinitialize all those other keys because some - // of them, in turn, reference "[sourceid]". - for (const std::string& key : default_trans_args) - { - std::string brackets(key), nobrackets(key); - // Invalid to inspect key[0] if key is empty(). But then, the entire - // body of this loop is pointless if key is empty(). - if (key.empty()) - continue; - - if (key[0] != '[') - { - // key was passed without brackets. That means that 'nobrackets' - // is correct but 'brackets' is not. - brackets = STRINGIZE('[' << brackets << ']'); - } - else - { - // key was passed with brackets. That means that 'brackets' is - // correct but 'nobrackets' is not. Erase the left bracket. - nobrackets.erase(0, 1); - std::string::size_type length(nobrackets.length()); - if (length && nobrackets[length - 1] == ']') - { - nobrackets.erase(length - 1); - } - } - // Calling LLTrans::getString() is what embeds the other default - // translation strings into this one. - LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets)); - } + LL_ERRS() << "Viewer failed to find localization and UI files." + << " Please reinstall viewer from https://secondlife.com/support/downloads" + << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; + } + LLTransUtil::parseStrings(strings_file, default_trans_args); + LLTransUtil::parseLanguageStrings("language_settings.xml"); + + // parseStrings() sets up the LLTrans substitution table. Add this one item. + LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid")); + + // Now that we've set "[sourceid]", have to go back through + // default_trans_args and reinitialize all those other keys because some + // of them, in turn, reference "[sourceid]". + for (const std::string& key : default_trans_args) + { + std::string brackets(key), nobrackets(key); + // Invalid to inspect key[0] if key is empty(). But then, the entire + // body of this loop is pointless if key is empty(). + if (key.empty()) + continue; + + if (key[0] != '[') + { + // key was passed without brackets. That means that 'nobrackets' + // is correct but 'brackets' is not. + brackets = STRINGIZE('[' << brackets << ']'); + } + else + { + // key was passed with brackets. That means that 'brackets' is + // correct but 'nobrackets' is not. Erase the left bracket. + nobrackets.erase(0, 1); + std::string::size_type length(nobrackets.length()); + if (length && nobrackets[length - 1] == ']') + { + nobrackets.erase(length - 1); + } + } + // Calling LLTrans::getString() is what embeds the other default + // translation strings into this one. + LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets)); + } } bool LLAppViewer::meetsRequirementsForMaximizedStart() { bool maximizedOk = (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1)); - return maximizedOk; + return maximizedOk; } bool LLAppViewer::initWindow() { - LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL; - - // store setting in a global for easy access and modification - gHeadlessClient = gSavedSettings.getBOOL("HeadlessClient"); - - // always start windowed - BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth"); - - LLViewerWindow::Params window_params; - window_params - .title(gWindowTitle) - .name(VIEWER_WINDOW_CLASSNAME) - .x(gSavedSettings.getS32("WindowX")) - .y(gSavedSettings.getS32("WindowY")) - .width(gSavedSettings.getU32("WindowWidth")) - .height(gSavedSettings.getU32("WindowHeight")) - .min_width(gSavedSettings.getU32("MinWindowWidth")) - .min_height(gSavedSettings.getU32("MinWindowHeight")) - .fullscreen(gSavedSettings.getBOOL("FullScreen")) - .ignore_pixel_depth(ignorePixelDepth) - .first_run(mIsFirstRun); - - gViewerWindow = new LLViewerWindow(window_params); - - LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL; - - // Need to load feature table before cheking to start watchdog. - bool use_watchdog = false; - int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); - if (watchdog_enabled_setting == -1) - { - use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); - } - else - { - // The user has explicitly set this setting; always use that value. - use_watchdog = bool(watchdog_enabled_setting); - } - - LL_INFOS("AppInit") << "watchdog" - << (use_watchdog ? " " : " NOT ") - << "enabled" - << " (setting = " << watchdog_enabled_setting << ")" - << LL_ENDL; - - if (use_watchdog) - { - LLWatchdog::getInstance()->init(); - } - - LLNotificationsUI::LLNotificationManager::getInstance(); + LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL; + + // store setting in a global for easy access and modification + gHeadlessClient = gSavedSettings.getBOOL("HeadlessClient"); + + // always start windowed + BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth"); + + LLViewerWindow::Params window_params; + window_params + .title(gWindowTitle) + .name(VIEWER_WINDOW_CLASSNAME) + .x(gSavedSettings.getS32("WindowX")) + .y(gSavedSettings.getS32("WindowY")) + .width(gSavedSettings.getU32("WindowWidth")) + .height(gSavedSettings.getU32("WindowHeight")) + .min_width(gSavedSettings.getU32("MinWindowWidth")) + .min_height(gSavedSettings.getU32("MinWindowHeight")) + .fullscreen(gSavedSettings.getBOOL("FullScreen")) + .ignore_pixel_depth(ignorePixelDepth) + .first_run(mIsFirstRun); + + gViewerWindow = new LLViewerWindow(window_params); + + LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL; + + // Need to load feature table before cheking to start watchdog. + bool use_watchdog = false; + int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); + if (watchdog_enabled_setting == -1) + { + use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); + } + else + { + // The user has explicitly set this setting; always use that value. + use_watchdog = bool(watchdog_enabled_setting); + } + + LL_INFOS("AppInit") << "watchdog" + << (use_watchdog ? " " : " NOT ") + << "enabled" + << " (setting = " << watchdog_enabled_setting << ")" + << LL_ENDL; + + if (use_watchdog) + { + LLWatchdog::getInstance()->init(); + } + + LLNotificationsUI::LLNotificationManager::getInstance(); #ifdef LL_DARWIN - //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later) - LLOSInfo& os_info = LLOSInfo::instance(); - if (os_info.mMajorVer == 10 && os_info.mMinorVer < 7) - { - if ( os_info.mMinorVer == 6 && os_info.mBuild < 8 ) - gViewerWindow->getWindow()->setOldResize(true); - } + //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later) + LLOSInfo& os_info = LLOSInfo::instance(); + if (os_info.mMajorVer == 10 && os_info.mMinorVer < 7) + { + if ( os_info.mMinorVer == 6 && os_info.mBuild < 8 ) + gViewerWindow->getWindow()->setOldResize(true); + } #endif - if (gSavedSettings.getBOOL("WindowMaximized")) - { - gViewerWindow->getWindow()->maximize(); - } + if (gSavedSettings.getBOOL("WindowMaximized")) + { + gViewerWindow->getWindow()->maximize(); + } - // - // Initialize GL stuff - // + // + // Initialize GL stuff + // - if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel))) - { - LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); - gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel); - } + if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel))) + { + LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); + gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel); + } - // Set this flag in case we crash while initializing GL - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + // Set this flag in case we crash while initializing GL + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - gPipeline.init(); - LL_INFOS("AppInit") << "gPipeline Initialized" << LL_ENDL; + gPipeline.init(); + LL_INFOS("AppInit") << "gPipeline Initialized" << LL_ENDL; - stop_glerror(); - gViewerWindow->initGLDefaults(); + stop_glerror(); + gViewerWindow->initGLDefaults(); - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - //If we have a startup crash, it's usually near GL initialization, so simulate that. - if(gCrashOnStartup) - { - LLAppViewer::instance()->forceErrorLLError(); - } + //If we have a startup crash, it's usually near GL initialization, so simulate that. + if(gCrashOnStartup) + { + LLAppViewer::instance()->forceErrorLLError(); + } - // - // Determine if the window should start maximized on initial run based - // on graphics capability - // - if (gSavedSettings.getBOOL("FirstLoginThisInstall") && meetsRequirementsForMaximizedStart()) - { - LL_INFOS("AppInit") << "This client met the requirements for a maximized initial screen." << LL_ENDL; - gSavedSettings.setBOOL("WindowMaximized", TRUE); - } + // + // Determine if the window should start maximized on initial run based + // on graphics capability + // + if (gSavedSettings.getBOOL("FirstLoginThisInstall") && meetsRequirementsForMaximizedStart()) + { + LL_INFOS("AppInit") << "This client met the requirements for a maximized initial screen." << LL_ENDL; + gSavedSettings.setBOOL("WindowMaximized", TRUE); + } - if (gSavedSettings.getBOOL("WindowMaximized")) - { - gViewerWindow->getWindow()->maximize(); - } + if (gSavedSettings.getBOOL("WindowMaximized")) + { + gViewerWindow->getWindow()->maximize(); + } - LLUI::getInstance()->mWindow = gViewerWindow->getWindow(); + LLUI::getInstance()->mWindow = gViewerWindow->getWindow(); - // Show watch cursor - gViewerWindow->setCursor(UI_CURSOR_WAIT); + // Show watch cursor + gViewerWindow->setCursor(UI_CURSOR_WAIT); - // Finish view initialization - gViewerWindow->initBase(); + // Finish view initialization + gViewerWindow->initBase(); - // show viewer window - //gViewerWindow->getWindow()->show(); + // show viewer window + //gViewerWindow->getWindow()->show(); - LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL; + LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL; - return true; + return true; } bool LLAppViewer::isUpdaterMissing() @@ -3243,28 +3243,28 @@ void LLAppViewer::writeDebugInfo(bool isStatic) LLSD LLAppViewer::getViewerInfo() const { - // The point of having one method build an LLSD info block and the other - // construct the user-visible About string is to ensure that the same info - // is available to a getInfo() caller as to the user opening - // LLFloaterAbout. - LLSD info; - auto& versionInfo(LLVersionInfo::instance()); - // With GitHub builds, the build number is too big to fit in a 32-bit int, - // and LLSD doesn't deal with integers wider than int. Use string. - info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(), - versionInfo.getPatch(), stringize(versionInfo.getBuild())); - info["VIEWER_VERSION_STR"] = versionInfo.getVersion(); - info["CHANNEL"] = versionInfo.getChannel(); - info["ADDRESS_SIZE"] = ADDRESS_SIZE; - std::string build_config = versionInfo.getBuildConfig(); - if (build_config != "Release") - { - info["BUILD_CONFIG"] = build_config; - } - - // return a URL to the release notes for this viewer, such as: - // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html - std::string url = versionInfo.getReleaseNotes(); // VVM supplied + // The point of having one method build an LLSD info block and the other + // construct the user-visible About string is to ensure that the same info + // is available to a getInfo() caller as to the user opening + // LLFloaterAbout. + LLSD info; + auto& versionInfo(LLVersionInfo::instance()); + // With GitHub builds, the build number is too big to fit in a 32-bit int, + // and LLSD doesn't deal with integers wider than int. Use string. + info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(), + versionInfo.getPatch(), stringize(versionInfo.getBuild())); + info["VIEWER_VERSION_STR"] = versionInfo.getVersion(); + info["CHANNEL"] = versionInfo.getChannel(); + info["ADDRESS_SIZE"] = ADDRESS_SIZE; + std::string build_config = versionInfo.getBuildConfig(); + if (build_config != "Release") + { + info["BUILD_CONFIG"] = build_config; + } + + // return a URL to the release notes for this viewer, such as: + // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html + std::string url = versionInfo.getReleaseNotes(); // VVM supplied if (url.empty()) { url = LLTrans::getString("RELEASE_NOTES_BASE_URL"); @@ -3272,32 +3272,32 @@ LLSD LLAppViewer::getViewerInfo() const url += "/"; url += LLURI::escape(versionInfo.getVersion()) + ".html"; } - info["VIEWER_RELEASE_NOTES_URL"] = url; - - // Position - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - LLVector3d pos = gAgent.getPositionGlobal(); - info["POSITION"] = ll_sd_from_vector3d(pos); - info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); - info["REGION"] = gAgent.getRegion()->getName(); - - boost::regex regex("\\.(secondlife|lindenlab)\\..*"); - info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, ""); - info["SERVER_VERSION"] = gLastVersionChannel; - LLSLURL slurl; - LLAgentUI::buildSLURL(slurl); - info["SLURL"] = slurl.getSLURLString(); - } - - // CPU - info["CPU"] = gSysCPU.getCPUString(); - info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits()); - // Moved hack adjustment to Windows memory size into llsys.cpp - info["OS_VERSION"] = LLOSInfo::instance().getOSString(); - info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR))); - info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER))); + info["VIEWER_RELEASE_NOTES_URL"] = url; + + // Position + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + LLVector3d pos = gAgent.getPositionGlobal(); + info["POSITION"] = ll_sd_from_vector3d(pos); + info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); + info["REGION"] = gAgent.getRegion()->getName(); + + boost::regex regex("\\.(secondlife|lindenlab)\\..*"); + info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, ""); + info["SERVER_VERSION"] = gLastVersionChannel; + LLSLURL slurl; + LLAgentUI::buildSLURL(slurl); + info["SLURL"] = slurl.getSLURLString(); + } + + // CPU + info["CPU"] = gSysCPU.getCPUString(); + info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits()); + // Moved hack adjustment to Windows memory size into llsys.cpp + info["OS_VERSION"] = LLOSInfo::instance().getOSString(); + info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR))); + info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER))); #if LL_WINDOWS std::string drvinfo; @@ -3322,22 +3322,22 @@ LLSD LLAppViewer::getViewerInfo() const drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY); } - if (!drvinfo.empty()) - { - info["GRAPHICS_DRIVER_VERSION"] = drvinfo; - } - else - { - LL_WARNS("DriverVersion")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL; - LLSD driver_info = gDXHardware.getDisplayInfo(); - if (driver_info.has("DriverVersion")) - { - info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; - } - } + if (!drvinfo.empty()) + { + info["GRAPHICS_DRIVER_VERSION"] = drvinfo; + } + else + { + LL_WARNS("DriverVersion")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL; + LLSD driver_info = gDXHardware.getDisplayInfo(); + if (driver_info.has("DriverVersion")) + { + info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; + } + } #endif - info["OPENGL_VERSION"] = ll_safe_string((const char*)(glGetString(GL_VERSION))); + info["OPENGL_VERSION"] = ll_safe_string((const char*)(glGetString(GL_VERSION))); // Settings @@ -3356,16 +3356,16 @@ LLSD LLAppViewer::getViewerInfo() const info["HIDPI"] = gHiDPISupport; #endif - // Libraries + // Libraries - info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); - bool want_fullname = true; - info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined"; - if(LLVoiceClient::getInstance()->voiceEnabled()) - { + info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); + bool want_fullname = true; + info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined"; + if(LLVoiceClient::getInstance()->voiceEnabled()) + { LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); const std::string build_version = version.mBuildVersion; - std::ostringstream version_string; + std::ostringstream version_string; if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(), version.serverVersion.begin())) { // Normal case: Show type and build version. @@ -3375,210 +3375,210 @@ LLSD LLAppViewer::getViewerInfo() const { // Mismatch: Show both versions. version_string << version.serverVersion << "/" << build_version << std::endl; } - info["VOICE_VERSION"] = version_string.str(); - } - else - { - info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); - } + info["VOICE_VERSION"] = version_string.str(); + } + else + { + info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); + } #if !LL_LINUX - std::ostringstream cef_ver_codec; - cef_ver_codec << "Dullahan: "; - cef_ver_codec << DULLAHAN_VERSION_MAJOR; - cef_ver_codec << "."; - cef_ver_codec << DULLAHAN_VERSION_MINOR; - cef_ver_codec << "."; - cef_ver_codec << DULLAHAN_VERSION_POINT; - cef_ver_codec << "."; - cef_ver_codec << DULLAHAN_VERSION_BUILD; - - cef_ver_codec << std::endl; - cef_ver_codec << " CEF: "; - cef_ver_codec << CEF_VERSION; - - cef_ver_codec << std::endl; - cef_ver_codec << " Chromium: "; - cef_ver_codec << CHROME_VERSION_MAJOR; - cef_ver_codec << "."; - cef_ver_codec << CHROME_VERSION_MINOR; - cef_ver_codec << "."; - cef_ver_codec << CHROME_VERSION_BUILD; - cef_ver_codec << "."; - cef_ver_codec << CHROME_VERSION_PATCH; - - info["LIBCEF_VERSION"] = cef_ver_codec.str(); + std::ostringstream cef_ver_codec; + cef_ver_codec << "Dullahan: "; + cef_ver_codec << DULLAHAN_VERSION_MAJOR; + cef_ver_codec << "."; + cef_ver_codec << DULLAHAN_VERSION_MINOR; + cef_ver_codec << "."; + cef_ver_codec << DULLAHAN_VERSION_POINT; + cef_ver_codec << "."; + cef_ver_codec << DULLAHAN_VERSION_BUILD; + + cef_ver_codec << std::endl; + cef_ver_codec << " CEF: "; + cef_ver_codec << CEF_VERSION; + + cef_ver_codec << std::endl; + cef_ver_codec << " Chromium: "; + cef_ver_codec << CHROME_VERSION_MAJOR; + cef_ver_codec << "."; + cef_ver_codec << CHROME_VERSION_MINOR; + cef_ver_codec << "."; + cef_ver_codec << CHROME_VERSION_BUILD; + cef_ver_codec << "."; + cef_ver_codec << CHROME_VERSION_PATCH; + + info["LIBCEF_VERSION"] = cef_ver_codec.str(); #else - info["LIBCEF_VERSION"] = "Undefined"; + info["LIBCEF_VERSION"] = "Undefined"; #endif #if !LL_LINUX - std::ostringstream vlc_ver_codec; - vlc_ver_codec << LIBVLC_VERSION_MAJOR; - vlc_ver_codec << "."; - vlc_ver_codec << LIBVLC_VERSION_MINOR; - vlc_ver_codec << "."; - vlc_ver_codec << LIBVLC_VERSION_REVISION; - info["LIBVLC_VERSION"] = vlc_ver_codec.str(); + std::ostringstream vlc_ver_codec; + vlc_ver_codec << LIBVLC_VERSION_MAJOR; + vlc_ver_codec << "."; + vlc_ver_codec << LIBVLC_VERSION_MINOR; + vlc_ver_codec << "."; + vlc_ver_codec << LIBVLC_VERSION_REVISION; + info["LIBVLC_VERSION"] = vlc_ver_codec.str(); #else - info["LIBVLC_VERSION"] = "Undefined"; + info["LIBVLC_VERSION"] = "Undefined"; #endif - S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); - if (packets_in > 0) - { - info["PACKETS_LOST"] = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST); - info["PACKETS_IN"] = packets_in; - info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); - } - - if (mServerReleaseNotesURL.empty()) - { - if (gAgent.getRegion()) - { - info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData"); - } - else - { - info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("NotConnected"); - } - } - else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL - { - info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]"; - } - else - { - info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL; - } + S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); + if (packets_in > 0) + { + info["PACKETS_LOST"] = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST); + info["PACKETS_IN"] = packets_in; + info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); + } + + if (mServerReleaseNotesURL.empty()) + { + if (gAgent.getRegion()) + { + info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData"); + } + else + { + info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("NotConnected"); + } + } + else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL + { + info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]"; + } + else + { + info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL; + } // populate field for new local disk cache with some details info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo(); - return info; + return info; } std::string LLAppViewer::getViewerInfoString(bool default_string) const { - std::ostringstream support; - - LLSD info(getViewerInfo()); - - // Render the LLSD from getInfo() as a format_map_t - LLStringUtil::format_map_t args; - - // allow the "Release Notes" URL label to be localized - args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string); - - for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap()); - ii != iend; ++ii) - { - if (! ii->second.isArray()) - { - // Scalar value - if (ii->second.isUndefined()) - { - args[ii->first] = LLTrans::getString("none_text", default_string); - } - else - { - // don't forget to render value asString() - args[ii->first] = ii->second.asString(); - } - } - else - { - // array value: build KEY_0, KEY_1 etc. entries - for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n) - { - args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString(); - } - } - } - - // Now build the various pieces - support << LLTrans::getString("AboutHeader", args, default_string); - if (info.has("BUILD_CONFIG")) - { - support << "\n" << LLTrans::getString("BuildConfig", args, default_string); - } - if (info.has("REGION")) - { - support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string); - } - support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string); - support << "\n"; - if (info.has("GRAPHICS_DRIVER_VERSION")) - { - support << "\n" << LLTrans::getString("AboutDriver", args, default_string); - } - support << "\n" << LLTrans::getString("AboutOGL", args, default_string); - support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string); + std::ostringstream support; + + LLSD info(getViewerInfo()); + + // Render the LLSD from getInfo() as a format_map_t + LLStringUtil::format_map_t args; + + // allow the "Release Notes" URL label to be localized + args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string); + + for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap()); + ii != iend; ++ii) + { + if (! ii->second.isArray()) + { + // Scalar value + if (ii->second.isUndefined()) + { + args[ii->first] = LLTrans::getString("none_text", default_string); + } + else + { + // don't forget to render value asString() + args[ii->first] = ii->second.asString(); + } + } + else + { + // array value: build KEY_0, KEY_1 etc. entries + for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n) + { + args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString(); + } + } + } + + // Now build the various pieces + support << LLTrans::getString("AboutHeader", args, default_string); + if (info.has("BUILD_CONFIG")) + { + support << "\n" << LLTrans::getString("BuildConfig", args, default_string); + } + if (info.has("REGION")) + { + support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string); + } + support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string); + support << "\n"; + if (info.has("GRAPHICS_DRIVER_VERSION")) + { + support << "\n" << LLTrans::getString("AboutDriver", args, default_string); + } + support << "\n" << LLTrans::getString("AboutOGL", args, default_string); + support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string); #if LL_DARWIN - support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string); + support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string); #endif - support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string); - if (info.has("COMPILER")) - { - support << "\n" << LLTrans::getString("AboutCompiler", args, default_string); - } - if (info.has("PACKETS_IN")) - { - support << '\n' << LLTrans::getString("AboutTraffic", args, default_string); - } - - // SLT timestamp - LLSD substitution; - substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected(); - support << "\n" << LLTrans::getString("AboutTime", substitution, default_string); - - return support.str(); + support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string); + if (info.has("COMPILER")) + { + support << "\n" << LLTrans::getString("AboutCompiler", args, default_string); + } + if (info.has("PACKETS_IN")) + { + support << '\n' << LLTrans::getString("AboutTraffic", args, default_string); + } + + // SLT timestamp + LLSD substitution; + substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected(); + support << "\n" << LLTrans::getString("AboutTime", substitution, default_string); + + return support.str(); } void LLAppViewer::cleanupSavedSettings() { - gSavedSettings.setBOOL("MouseSun", FALSE); + gSavedSettings.setBOOL("MouseSun", FALSE); - gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator + gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator - gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc); + gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc); - gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); + gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); - if (gDebugView) - { - gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible()); - } + if (gDebugView) + { + gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible()); + } - // save window position if not maximized - // as we don't track it in callbacks - if(NULL != gViewerWindow) - { - BOOL maximized = gViewerWindow->getWindow()->getMaximized(); - if (!maximized) - { - LLCoordScreen window_pos; + // save window position if not maximized + // as we don't track it in callbacks + if(NULL != gViewerWindow) + { + BOOL maximized = gViewerWindow->getWindow()->getMaximized(); + if (!maximized) + { + LLCoordScreen window_pos; - if (gViewerWindow->getWindow()->getPosition(&window_pos)) - { - gSavedSettings.setS32("WindowX", window_pos.mX); - gSavedSettings.setS32("WindowY", window_pos.mY); - } - } - } + if (gViewerWindow->getWindow()->getPosition(&window_pos)) + { + gSavedSettings.setS32("WindowX", window_pos.mX); + gSavedSettings.setS32("WindowY", window_pos.mY); + } + } + } gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting()); - // Some things are cached in LLAgent. - if (gAgent.isInitialized()) - { - gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance); - } + // Some things are cached in LLAgent. + if (gAgent.isInitialized()) + { + gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance); + } } void LLAppViewer::removeCacheFiles(const std::string& file_mask) { - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask); } void LLAppViewer::writeSystemInfo() @@ -3588,96 +3588,96 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["Dynamic"] = LLSD::emptyMap(); #if LL_WINDOWS && !LL_BUGSPLAT - gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); + gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); #else //Not ideal but sufficient for good reporting. gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName(); #endif - gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel(); - gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor(); - gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor(); - gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch(); - gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild()); - gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize(); + gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel(); + gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor(); + gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor(); + gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch(); + gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild()); + gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize(); - gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); + gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); - gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString(); - gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily(); - gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz(); - gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec(); - gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); - gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); + gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString(); + gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily(); + gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz(); + gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec(); + gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); + gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); - gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value()); - gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits()); - gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple(); + gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value()); + gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits()); + gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple(); - // The user is not logged on yet, but record the current grid choice login url - // which may have been the intended grid. - gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId(); + // The user is not logged on yet, but record the current grid choice login url + // which may have been the intended grid. + gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId(); - // *FIX:Mani - move this down in llappviewerwin32 + // *FIX:Mani - move this down in llappviewerwin32 #ifdef LL_WINDOWS - DWORD thread_id = GetCurrentThreadId(); - gDebugInfo["MainloopThreadID"] = (S32)thread_id; + DWORD thread_id = GetCurrentThreadId(); + gDebugInfo["MainloopThreadID"] = (S32)thread_id; #endif #ifndef LL_BUGSPLAT - // "CrashNotHandled" is set here, while things are running well, - // in case of a freeze. If there is a freeze, the crash logger will be launched - // and can read this value from the debug_info.log. - gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true); + // "CrashNotHandled" is set here, while things are running well, + // in case of a freeze. If there is a freeze, the crash logger will be launched + // and can read this value from the debug_info.log. + gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true); #else // LL_BUGSPLAT - // "CrashNotHandled" is obsolete; it used (not very successsfully) + // "CrashNotHandled" is obsolete; it used (not very successsfully) // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze - gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false); + gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false); #endif // ! LL_BUGSPLAT - // Insert crash host url (url to post crash log to) if configured. This insures - // that the crash report will go to the proper location in the case of a - // prior freeze. - std::string crashHostUrl = gSavedSettings.get("CrashHostUrl"); - if(crashHostUrl != "") - { - gDebugInfo["CrashHostUrl"] = crashHostUrl; - } - - // Dump some debugging info - LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL; - LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL; - - // Dump the local time and time zone - time_t now; - time(&now); - char tbuffer[256]; /* Flawfinder: ignore */ - strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now)); - LL_INFOS("SystemInfo") << "Local time: " << tbuffer << LL_ENDL; - - // query some system information - LL_INFOS("SystemInfo") << "CPU info:\n" << gSysCPU << LL_ENDL; - LL_INFOS("SystemInfo") << "Memory info:\n" << gSysMemory << LL_ENDL; - LL_INFOS("SystemInfo") << "OS: " << LLOSInfo::instance().getOSStringSimple() << LL_ENDL; - LL_INFOS("SystemInfo") << "OS info: " << LLOSInfo::instance() << LL_ENDL; + // Insert crash host url (url to post crash log to) if configured. This insures + // that the crash report will go to the proper location in the case of a + // prior freeze. + std::string crashHostUrl = gSavedSettings.get("CrashHostUrl"); + if(crashHostUrl != "") + { + gDebugInfo["CrashHostUrl"] = crashHostUrl; + } + + // Dump some debugging info + LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL; + LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL; + + // Dump the local time and time zone + time_t now; + time(&now); + char tbuffer[256]; /* Flawfinder: ignore */ + strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now)); + LL_INFOS("SystemInfo") << "Local time: " << tbuffer << LL_ENDL; + + // query some system information + LL_INFOS("SystemInfo") << "CPU info:\n" << gSysCPU << LL_ENDL; + LL_INFOS("SystemInfo") << "Memory info:\n" << gSysMemory << LL_ENDL; + LL_INFOS("SystemInfo") << "OS: " << LLOSInfo::instance().getOSStringSimple() << LL_ENDL; + LL_INFOS("SystemInfo") << "OS info: " << LLOSInfo::instance() << LL_ENDL; gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); - gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); - gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); - gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin()); - gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); + gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); + gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); + gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin()); + gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); if (gViewerWindow) { - std::vector resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList(); - for (auto res_iter : resolutions) - { - gDebugInfo["DisplayInfo"].append(res_iter); - } + std::vector resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList(); + for (auto res_iter : resolutions) + { + gDebugInfo["DisplayInfo"].append(res_iter); + } } - writeDebugInfo(); // Save out debug_info.log early, in case of crash. + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } #ifdef LL_WINDOWS @@ -3689,265 +3689,265 @@ void LLAppViewer::writeSystemInfo() // TODO make this a member function. void getFileList() { - std::stringstream filenames; - - typedef std::vector vec; - std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,""); - vec file_vec = gDirUtilp->getFilesInDir(pathname); - for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) - { - filenames << *iter << " "; - if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) ) - { - std::string fullname = pathname + *iter; - llifstream fdat( fullname.c_str(), std::ifstream::binary); - if (fdat) - { - char buf[5]; - fdat.read(buf,4); - fdat.close(); - if (!strncmp(buf,"MDMP",4)) - { - gDebugInfo["Dynamic"]["MinidumpPath"] = fullname; - break; - } - } - } - } - filenames << std::endl; - gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str(); + std::stringstream filenames; + + typedef std::vector vec; + std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,""); + vec file_vec = gDirUtilp->getFilesInDir(pathname); + for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) + { + filenames << *iter << " "; + if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) ) + { + std::string fullname = pathname + *iter; + llifstream fdat( fullname.c_str(), std::ifstream::binary); + if (fdat) + { + char buf[5]; + fdat.read(buf,4); + fdat.close(); + if (!strncmp(buf,"MDMP",4)) + { + gDebugInfo["Dynamic"]["MinidumpPath"] = fullname; + break; + } + } + } + } + filenames << std::endl; + gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str(); } #endif // static void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file) { - std::string marker_version(LLVersionInfo::instance().getChannelAndVersion()); - if ( marker_version.length() > MAX_MARKER_LENGTH ) - { - LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")" - << " greater than maximum (" << MAX_MARKER_LENGTH << ")" - << ": marker matching may be incorrect" - << LL_ENDL; - } - - // record the viewer version in the marker file - marker_file.write(marker_version.data(), marker_version.length()); + std::string marker_version(LLVersionInfo::instance().getChannelAndVersion()); + if ( marker_version.length() > MAX_MARKER_LENGTH ) + { + LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")" + << " greater than maximum (" << MAX_MARKER_LENGTH << ")" + << ": marker matching may be incorrect" + << LL_ENDL; + } + + // record the viewer version in the marker file + marker_file.write(marker_version.data(), marker_version.length()); } bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const { - bool sameVersion = false; - - std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); - char marker_version[MAX_MARKER_LENGTH]; - S32 marker_version_length; - - LLAPRFile marker_file; - marker_file.open(marker_name, LL_APR_RB); - if (marker_file.getFileHandle()) - { - marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); - std::string marker_string(marker_version, marker_version_length); - if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) - { - sameVersion = true; - } - LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': " - << "\n mine '" << my_version << "'" - << "\n marker '" << marker_string << "'" - << "\n " << ( sameVersion ? "same" : "different" ) << " version" - << LL_ENDL; - marker_file.close(); - } - return sameVersion; + bool sameVersion = false; + + std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); + char marker_version[MAX_MARKER_LENGTH]; + S32 marker_version_length; + + LLAPRFile marker_file; + marker_file.open(marker_name, LL_APR_RB); + if (marker_file.getFileHandle()) + { + marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); + std::string marker_string(marker_version, marker_version_length); + if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) + { + sameVersion = true; + } + LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': " + << "\n mine '" << my_version << "'" + << "\n marker '" << marker_string << "'" + << "\n " << ( sameVersion ? "same" : "different" ) << " version" + << LL_ENDL; + marker_file.close(); + } + return sameVersion; } void LLAppViewer::processMarkerFiles() { - //We've got 4 things to test for here - // - Other Process Running (SecondLife.exec_marker present, locked) - // - Freeze (SecondLife.exec_marker present, not locked) - // - LLError Crash (SecondLife.llerror_marker present) - // - Other Crash (SecondLife.error_marker present) - // These checks should also remove these files for the last 2 cases if they currently exist - - std::ostringstream marker_log_stream; - bool marker_is_same_version = true; - // first, look for the marker created at startup and deleted on a clean exit - mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); - if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB)) - { - // File exists... - // first, read it to see if it was created by the same version (we need this later) - marker_is_same_version = markerIsSameVersion(mMarkerFileName); - - // now test to see if this file is locked by a running process (try to open for write) - marker_log_stream << "Checking exec marker file for lock..."; - mMarkerFile.open(mMarkerFileName, LL_APR_WB); - apr_file_t* fMarker = mMarkerFile.getFileHandle() ; - if (!fMarker) - { - marker_log_stream << "Exec marker file open failed - assume it is locked."; - mSecondInstance = true; // lock means that instance is running. - } - else - { - // We were able to open it, now try to lock it ourselves... - if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) - { - marker_log_stream << "Locking exec marker failed."; - mSecondInstance = true; // lost a race? be conservative - } - else - { - // No other instances; we've locked this file now, so record our version; delete on quit. - recordMarkerVersion(mMarkerFile); - marker_log_stream << "Exec marker file existed but was not locked; rewritten."; - } - } - initLoggingAndGetLastDuration(); - - std::string marker_log_msg(marker_log_stream.str()); - LL_INFOS("MarkerFile") << marker_log_msg << LL_ENDL; - - if (mSecondInstance) - { - LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL; - } - else if (marker_is_same_version) - { - // the file existed, is ours, and matched our version, so we can report on what it says - LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL; - gLastExecEvent = LAST_EXEC_OTHER_CRASH; - } - else - { - LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL; - } - } - else // marker did not exist... last exec (if any) did not freeze - { - initLoggingAndGetLastDuration(); - // Create the marker file for this execution & lock it; it will be deleted on a clean exit - apr_status_t s; - s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE); - - if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) - { - LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL; - if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE)) - { - recordMarkerVersion(mMarkerFile); - LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL; - } - else - { - LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL; - } - } - else - { - LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL; - } - } - - // now check for cases in which the exec marker may have been cleaned up by crash handlers - - // check for any last exec event report based on whether or not it happened during logout - // (the logout marker is created when logout begins) - std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); - if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB)) - { - if (markerIsSameVersion(logout_marker_file)) - { - gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; - LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL; - } - else - { - LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL; - } - LLAPRFile::remove(logout_marker_file); - } - // further refine based on whether or not a marker created during an llerr crash is found - std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); - if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) - { - if (markerIsSameVersion(llerror_marker_file)) - { - if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) - { - gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; - } - else - { - gLastExecEvent = LAST_EXEC_LLERROR_CRASH; - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; - } - } - else - { - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; - } - LLAPRFile::remove(llerror_marker_file); - } - // and last refine based on whether or not a marker created during a non-llerr crash is found - std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); - if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) - { - if (markerIsSameVersion(error_marker_file)) - { - if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) - { - gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; - LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; - } - else - { - gLastExecEvent = LAST_EXEC_OTHER_CRASH; - LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; - } - } - else - { - LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; - } - LLAPRFile::remove(error_marker_file); - } + //We've got 4 things to test for here + // - Other Process Running (SecondLife.exec_marker present, locked) + // - Freeze (SecondLife.exec_marker present, not locked) + // - LLError Crash (SecondLife.llerror_marker present) + // - Other Crash (SecondLife.error_marker present) + // These checks should also remove these files for the last 2 cases if they currently exist + + std::ostringstream marker_log_stream; + bool marker_is_same_version = true; + // first, look for the marker created at startup and deleted on a clean exit + mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); + if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB)) + { + // File exists... + // first, read it to see if it was created by the same version (we need this later) + marker_is_same_version = markerIsSameVersion(mMarkerFileName); + + // now test to see if this file is locked by a running process (try to open for write) + marker_log_stream << "Checking exec marker file for lock..."; + mMarkerFile.open(mMarkerFileName, LL_APR_WB); + apr_file_t* fMarker = mMarkerFile.getFileHandle() ; + if (!fMarker) + { + marker_log_stream << "Exec marker file open failed - assume it is locked."; + mSecondInstance = true; // lock means that instance is running. + } + else + { + // We were able to open it, now try to lock it ourselves... + if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) + { + marker_log_stream << "Locking exec marker failed."; + mSecondInstance = true; // lost a race? be conservative + } + else + { + // No other instances; we've locked this file now, so record our version; delete on quit. + recordMarkerVersion(mMarkerFile); + marker_log_stream << "Exec marker file existed but was not locked; rewritten."; + } + } + initLoggingAndGetLastDuration(); + + std::string marker_log_msg(marker_log_stream.str()); + LL_INFOS("MarkerFile") << marker_log_msg << LL_ENDL; + + if (mSecondInstance) + { + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL; + } + else if (marker_is_same_version) + { + // the file existed, is ours, and matched our version, so we can report on what it says + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL; + gLastExecEvent = LAST_EXEC_OTHER_CRASH; + } + else + { + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL; + } + } + else // marker did not exist... last exec (if any) did not freeze + { + initLoggingAndGetLastDuration(); + // Create the marker file for this execution & lock it; it will be deleted on a clean exit + apr_status_t s; + s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE); + + if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) + { + LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL; + if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE)) + { + recordMarkerVersion(mMarkerFile); + LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL; + } + else + { + LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL; + } + } + else + { + LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL; + } + } + + // now check for cases in which the exec marker may have been cleaned up by crash handlers + + // check for any last exec event report based on whether or not it happened during logout + // (the logout marker is created when logout begins) + std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); + if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB)) + { + if (markerIsSameVersion(logout_marker_file)) + { + gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; + LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL; + } + else + { + LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL; + } + LLAPRFile::remove(logout_marker_file); + } + // further refine based on whether or not a marker created during an llerr crash is found + std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); + if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) + { + if (markerIsSameVersion(llerror_marker_file)) + { + if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) + { + gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; + LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; + } + else + { + gLastExecEvent = LAST_EXEC_LLERROR_CRASH; + LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; + } + } + else + { + LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; + } + LLAPRFile::remove(llerror_marker_file); + } + // and last refine based on whether or not a marker created during a non-llerr crash is found + std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) + { + if (markerIsSameVersion(error_marker_file)) + { + if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) + { + gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; + LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; + } + else + { + gLastExecEvent = LAST_EXEC_OTHER_CRASH; + LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } + } + else + { + LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; + } + LLAPRFile::remove(error_marker_file); + } } void LLAppViewer::removeMarkerFiles() { - if (!mSecondInstance) - { - if (mMarkerFile.getFileHandle()) - { - mMarkerFile.close() ; - LLAPRFile::remove( mMarkerFileName ); - LL_DEBUGS("MarkerFile") << "removed exec marker '"<updateAvatarRezMetrics(true); // force a last packet to be sent. - } - - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); - effectp->setPositionGlobal(gAgent.getPositionGlobal()); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - LLHUDManager::getInstance()->sendEffects(); - effectp->markDead() ;//remove it. - - // Attempt to close all floaters that might be - // editing things. - if (gFloaterView) - { - // application is quitting - gFloaterView->closeAllChildren(true); - } - - // Send preferences once, when exiting - bool include_preferences = true; - send_viewer_stats(include_preferences); - - gLogoutTimer.reset(); - mQuitRequested = true; + LL_INFOS() << "requestQuit" << LL_ENDL; + + LLViewerRegion* region = gAgent.getRegion(); + + if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) + { + // If we have a region, make some attempt to send a logout request first. + // This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes. + if(region) + { + sendLogoutRequest(); + } + + // Quit immediately + forceQuit(); + return; + } + + // Try to send metrics back to the grid + metricsSend(!gDisconnected); + + // Try to send last batch of avatar rez metrics. + if (!gDisconnected && isAgentAvatarValid()) + { + gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. + } + + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); + effectp->setPositionGlobal(gAgent.getPositionGlobal()); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + LLHUDManager::getInstance()->sendEffects(); + effectp->markDead() ;//remove it. + + // Attempt to close all floaters that might be + // editing things. + if (gFloaterView) + { + // application is quitting + gFloaterView->closeAllChildren(true); + } + + // Send preferences once, when exiting + bool include_preferences = true; + send_viewer_stats(include_preferences); + + gLogoutTimer.reset(); + mQuitRequested = true; } static bool finish_quit(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - LLAppViewer::instance()->requestQuit(); - } - return false; + if (option == 0) + { + LLAppViewer::instance()->requestQuit(); + } + return false; } static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_quit); void LLAppViewer::userQuit() { - LL_INFOS() << "User requested quit" << LL_ENDL; - if (gDisconnected - || !gViewerWindow - || !gViewerWindow->getProgressView() - || gViewerWindow->getProgressView()->getVisible()) - { - requestQuit(); - } - else - { - LLNotificationsUtil::add("ConfirmQuit"); - } + LL_INFOS() << "User requested quit" << LL_ENDL; + if (gDisconnected + || !gViewerWindow + || !gViewerWindow->getProgressView() + || gViewerWindow->getProgressView()->getVisible()) + { + requestQuit(); + } + else + { + LLNotificationsUtil::add("ConfirmQuit"); + } } static bool finish_early_exit(const LLSD& notification, const LLSD& response) { - LLAppViewer::instance()->forceQuit(); - return false; + LLAppViewer::instance()->forceQuit(); + return false; } void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions) { - LL_WARNS() << "app_early_exit: " << name << LL_ENDL; - gDoDisconnect = TRUE; - LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit); + LL_WARNS() << "app_early_exit: " << name << LL_ENDL; + gDoDisconnect = TRUE; + LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit); } // case where we need the viewer to exit without any need for notifications void LLAppViewer::earlyExitNoNotify() { - LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL; - gDoDisconnect = TRUE; - finish_early_exit( LLSD(), LLSD() ); + LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL; + gDoDisconnect = TRUE; + finish_early_exit( LLSD(), LLSD() ); } void LLAppViewer::abortQuit() { LL_INFOS() << "abortQuit()" << LL_ENDL; - mQuitRequested = false; + mQuitRequested = false; } void LLAppViewer::migrateCacheDirectory() { #if LL_WINDOWS || LL_DARWIN - // NOTE: (Nyx) as of 1.21, cache for mac is moving to /library/caches/SecondLife from - // /library/application support/SecondLife/cache This should clear/delete the old dir. - - // As of 1.23 the Windows cache moved from - // C:\Documents and Settings\James\Application Support\SecondLife\cache - // to - // C:\Documents and Settings\James\Local Settings\Application Support\SecondLife - // - // The Windows Vista equivalent is from - // C:\Users\James\AppData\Roaming\SecondLife\cache - // to - // C:\Users\James\AppData\Local\SecondLife - // - // Note the absence of \cache on the second path. James. - - // Only do this once per fresh install of this version. - if (gSavedSettings.getBOOL("MigrateCacheDirectory")) - { - gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE); - - std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache"); - std::string new_cache_dir = gDirUtilp->getCacheDir(true); - - if (gDirUtilp->fileExists(old_cache_dir)) - { - LL_INFOS() << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << LL_ENDL; - - // Migrate inventory cache to avoid pain to inventory database after mass update - S32 file_count = 0; - std::string file_name; - std::string mask = "*.*"; - - LLDirIterator iter(old_cache_dir, mask); - while (iter.next(file_name)) - { - if (file_name == "." || file_name == "..") continue; - std::string source_path = gDirUtilp->add(old_cache_dir, file_name); - std::string dest_path = gDirUtilp->add(new_cache_dir, file_name); - if (!LLFile::rename(source_path, dest_path)) - { - file_count++; - } - } - LL_INFOS() << "Moved " << file_count << " files" << LL_ENDL; - - // Nuke the old cache - gDirUtilp->setCacheDir(old_cache_dir); - purgeCache(); - gDirUtilp->setCacheDir(new_cache_dir); + // NOTE: (Nyx) as of 1.21, cache for mac is moving to /library/caches/SecondLife from + // /library/application support/SecondLife/cache This should clear/delete the old dir. + + // As of 1.23 the Windows cache moved from + // C:\Documents and Settings\James\Application Support\SecondLife\cache + // to + // C:\Documents and Settings\James\Local Settings\Application Support\SecondLife + // + // The Windows Vista equivalent is from + // C:\Users\James\AppData\Roaming\SecondLife\cache + // to + // C:\Users\James\AppData\Local\SecondLife + // + // Note the absence of \cache on the second path. James. + + // Only do this once per fresh install of this version. + if (gSavedSettings.getBOOL("MigrateCacheDirectory")) + { + gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE); + + std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache"); + std::string new_cache_dir = gDirUtilp->getCacheDir(true); + + if (gDirUtilp->fileExists(old_cache_dir)) + { + LL_INFOS() << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << LL_ENDL; + + // Migrate inventory cache to avoid pain to inventory database after mass update + S32 file_count = 0; + std::string file_name; + std::string mask = "*.*"; + + LLDirIterator iter(old_cache_dir, mask); + while (iter.next(file_name)) + { + if (file_name == "." || file_name == "..") continue; + std::string source_path = gDirUtilp->add(old_cache_dir, file_name); + std::string dest_path = gDirUtilp->add(new_cache_dir, file_name); + if (!LLFile::rename(source_path, dest_path)) + { + file_count++; + } + } + LL_INFOS() << "Moved " << file_count << " files" << LL_ENDL; + + // Nuke the old cache + gDirUtilp->setCacheDir(old_cache_dir); + purgeCache(); + gDirUtilp->setCacheDir(new_cache_dir); #if LL_DARWIN - // Clean up Mac files not deleted by removing *.* - std::string ds_store = old_cache_dir + "/.DS_Store"; - if (gDirUtilp->fileExists(ds_store)) - { - LLFile::remove(ds_store); - } + // Clean up Mac files not deleted by removing *.* + std::string ds_store = old_cache_dir + "/.DS_Store"; + if (gDirUtilp->fileExists(ds_store)) + { + LLFile::remove(ds_store); + } #endif - if (LLFile::rmdir(old_cache_dir) != 0) - { - LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL; - } - } - } + if (LLFile::rmdir(old_cache_dir) != 0) + { + LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL; + } + } + } #endif // LL_WINDOWS || LL_DARWIN } //static U32 LLAppViewer::getTextureCacheVersion() { - // Viewer texture cache version, change if the texture cache format changes. - // 2021-03-10 Bumping up by one to help obviate texture cache issues with - // Simple Cache Viewer - see SL-14985 for more information - //const U32 TEXTURE_CACHE_VERSION = 8; - const U32 TEXTURE_CACHE_VERSION = 9; + // Viewer texture cache version, change if the texture cache format changes. + // 2021-03-10 Bumping up by one to help obviate texture cache issues with + // Simple Cache Viewer - see SL-14985 for more information + //const U32 TEXTURE_CACHE_VERSION = 8; + const U32 TEXTURE_CACHE_VERSION = 9; - return TEXTURE_CACHE_VERSION ; + return TEXTURE_CACHE_VERSION ; } //static @@ -4190,92 +4190,92 @@ U32 LLAppViewer::getDiskCacheVersion() //static U32 LLAppViewer::getObjectCacheVersion() { - // Viewer object cache version, change if object update - // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 17; + // Viewer object cache version, change if object update + // format changes. JC + const U32 INDRA_OBJECT_CACHE_VERSION = 17; - return INDRA_OBJECT_CACHE_VERSION; + return INDRA_OBJECT_CACHE_VERSION; } bool LLAppViewer::initCache() { - mPurgeCache = false; - BOOL read_only = mSecondInstance ? TRUE : FALSE; - LLAppViewer::getTextureCache()->setReadOnly(read_only) ; - LLVOCache::initParamSingleton(read_only); + mPurgeCache = false; + BOOL read_only = mSecondInstance ? TRUE : FALSE; + LLAppViewer::getTextureCache()->setReadOnly(read_only) ; + LLVOCache::initParamSingleton(read_only); - // initialize the new disk cache using saved settings - const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); + // initialize the new disk cache using saved settings + const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); - const U32 MB = 1024 * 1024; + const U32 MB = 1024 * 1024; const uintmax_t MIN_CACHE_SIZE = 256 * MB; - const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; + const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB; const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); const F64 texture_cache_percent = 100.0 - disk_cache_percent; - // note that the maximum size of this cache is defined as a percentage of the - // total cache size - the 'CacheSize' pref - for all caches. + // note that the maximum size of this cache is defined as a percentage of the + // total cache size - the 'CacheSize' pref - for all caches. const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100); - const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); + const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); - bool texture_cache_mismatch = false; + bool texture_cache_mismatch = false; bool remove_vfs_files = false; - if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) - { - texture_cache_mismatch = true; - if(!read_only) - { - gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); + if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) + { + texture_cache_mismatch = true; + if(!read_only) + { + gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed - remove_vfs_files = true; - } - } - - if(!read_only) - { - // Purge cache if user requested it - if (gSavedSettings.getBOOL("PurgeCacheOnStartup") || - gSavedSettings.getBOOL("PurgeCacheOnNextStartup")) - { - LL_INFOS("AppCache") << "Startup cache purge requested: " << (gSavedSettings.getBOOL("PurgeCacheOnStartup") ? "ALWAYS" : "ONCE") << LL_ENDL; - gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false); - mPurgeCache = true; - // STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad - texture_cache_mismatch = true; - } - - // We have moved the location of the cache directory over time. - migrateCacheDirectory(); - - // Setup and verify the cache location - std::string cache_location = gSavedSettings.getString("CacheLocation"); - std::string new_cache_location = gSavedSettings.getString("NewCacheLocation"); - if (new_cache_location != cache_location) - { - LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL; - gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); - purgeCache(); // purge old cache - gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name)); - gSavedSettings.setString("CacheLocation", new_cache_location); - gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location)); - } - } - - if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"))) - { - LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL; - gSavedSettings.setString("CacheLocation", ""); - gSavedSettings.setString("CacheLocationTopFolder", ""); - } - - const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info); - - if (!read_only) - { + remove_vfs_files = true; + } + } + + if(!read_only) + { + // Purge cache if user requested it + if (gSavedSettings.getBOOL("PurgeCacheOnStartup") || + gSavedSettings.getBOOL("PurgeCacheOnNextStartup")) + { + LL_INFOS("AppCache") << "Startup cache purge requested: " << (gSavedSettings.getBOOL("PurgeCacheOnStartup") ? "ALWAYS" : "ONCE") << LL_ENDL; + gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false); + mPurgeCache = true; + // STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad + texture_cache_mismatch = true; + } + + // We have moved the location of the cache directory over time. + migrateCacheDirectory(); + + // Setup and verify the cache location + std::string cache_location = gSavedSettings.getString("CacheLocation"); + std::string new_cache_location = gSavedSettings.getString("NewCacheLocation"); + if (new_cache_location != cache_location) + { + LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL; + gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); + purgeCache(); // purge old cache + gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name)); + gSavedSettings.setString("CacheLocation", new_cache_location); + gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location)); + } + } + + if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"))) + { + LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL; + gSavedSettings.setString("CacheLocation", ""); + gSavedSettings.setString("CacheLocationTopFolder", ""); + } + + const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info); + + if (!read_only) + { if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion()) { LLDiskCache::getInstance()->clearCache(); @@ -4287,166 +4287,166 @@ bool LLAppViewer::initCache() { LLDiskCache::getInstance()->removeOldVFSFiles(); } - + if (mPurgeCache) - { - LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); - purgeCache(); - - // clear the new C++ file system based cache - LLDiskCache::getInstance()->clearCache(); - } - else - { - // purge excessive files from the new file system based cache - LLDiskCache::getInstance()->purge(); - } - } - LLAppViewer::getPurgeDiskCacheThread()->start(); - - LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); - - // Init the texture cache + { + LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); + purgeCache(); + + // clear the new C++ file system based cache + LLDiskCache::getInstance()->clearCache(); + } + else + { + // purge excessive files from the new file system based cache + LLDiskCache::getInstance()->purge(); + } + } + LLAppViewer::getPurgeDiskCacheThread()->start(); + + LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); + + // Init the texture cache // Allocate the remaining percent which is not allocated to the disk cache const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100); LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); - LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); + LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); return true; } void LLAppViewer::addOnIdleCallback(const boost::function& cb) { - gMainloopWork.post(cb); + gMainloopWork.post(cb); } void LLAppViewer::loadKeyBindings() { - std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml"); - if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file)) - { - // Failed to load custom bindings, try default ones - key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml"); - if (!gViewerInput.loadBindingsXML(key_bindings_file)) - { + std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml"); + if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file)) + { + // Failed to load custom bindings, try default ones + key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml"); + if (!gViewerInput.loadBindingsXML(key_bindings_file)) + { LLError::LLUserWarningMsg::showMissingFiles(); - LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; - } - } + LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; + } + } LLUrlRegistry::instance().setKeybindingHandler(&gViewerInput); } void LLAppViewer::purgeCache() { - LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; - LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); - LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); - LLViewerShaderMgr::instance()->clearShaderCache(); - std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); - if (LLFile::isdir(browser_cache)) - { - // cef does not support clear_cache and clear_cookies, so clear what we can manually. - gDirUtilp->deleteDirAndContents(browser_cache); - } - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*"); + LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; + LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); + LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); + LLViewerShaderMgr::instance()->clearShaderCache(); + std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); + if (LLFile::isdir(browser_cache)) + { + // cef does not support clear_cache and clear_cookies, so clear what we can manually. + gDirUtilp->deleteDirAndContents(browser_cache); + } + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*"); } //purge cache immediately, do not wait until the next login. void LLAppViewer::purgeCacheImmediate() { - LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL; - LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false); - LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true); + LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL; + LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false); + LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true); } std::string LLAppViewer::getSecondLifeTitle() const { - return LLTrans::getString("APP_NAME"); + return LLTrans::getString("APP_NAME"); } std::string LLAppViewer::getWindowTitle() const { - return gWindowTitle; + return gWindowTitle; } // Callback from a dialog indicating user was logged out. bool finish_disconnect(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (1 == option) - { + if (1 == option) + { LLAppViewer::instance()->forceQuit(); - } - return false; + } + return false; } // Callback from an early disconnect dialog, force an exit bool finish_forced_disconnect(const LLSD& notification, const LLSD& response) { - LLAppViewer::instance()->forceQuit(); - return false; + LLAppViewer::instance()->forceQuit(); + return false; } void LLAppViewer::forceDisconnect(const std::string& mesg) { - if (gDoDisconnect) - { - // Already popped up one of these dialogs, don't - // do this again. - return; - } - - // *TODO: Translate the message if possible - std::string big_reason = LLAgent::sTeleportErrorMessages[mesg]; - if ( big_reason.size() == 0 ) - { - big_reason = mesg; - } - - LLSD args; - gDoDisconnect = TRUE; - - if (LLStartUp::getStartupState() < STATE_STARTED) - { - // Tell users what happened - args["ERROR_MESSAGE"] = big_reason; - LLNotificationsUtil::add("ErrorMessage", args, LLSD(), &finish_forced_disconnect); - } - else - { - args["MESSAGE"] = big_reason; - LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect ); - } + if (gDoDisconnect) + { + // Already popped up one of these dialogs, don't + // do this again. + return; + } + + // *TODO: Translate the message if possible + std::string big_reason = LLAgent::sTeleportErrorMessages[mesg]; + if ( big_reason.size() == 0 ) + { + big_reason = mesg; + } + + LLSD args; + gDoDisconnect = TRUE; + + if (LLStartUp::getStartupState() < STATE_STARTED) + { + // Tell users what happened + args["ERROR_MESSAGE"] = big_reason; + LLNotificationsUtil::add("ErrorMessage", args, LLSD(), &finish_forced_disconnect); + } + else + { + args["MESSAGE"] = big_reason; + LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect ); + } } void LLAppViewer::badNetworkHandler() { - // Dump the packet - gMessageSystem->dumpPacketToLog(); - - // Flush all of our caches on exit in the case of disconnect due to - // invalid packets. - - mPurgeCacheOnExit = TRUE; - - std::ostringstream message; - message << - "The viewer has detected mangled network data indicative\n" - "of a bad upstream network connection or an incomplete\n" - "local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n" - " \n" - "Try uninstalling and reinstalling to see if this resolves \n" - "the issue. \n" - " \n" - "If the problem continues, see the Tech Support FAQ at: \n" - "www.secondlife.com/support"; - forceDisconnect(message.str()); - - LLApp::instance()->writeMiniDump(); + // Dump the packet + gMessageSystem->dumpPacketToLog(); + + // Flush all of our caches on exit in the case of disconnect due to + // invalid packets. + + mPurgeCacheOnExit = TRUE; + + std::ostringstream message; + message << + "The viewer has detected mangled network data indicative\n" + "of a bad upstream network connection or an incomplete\n" + "local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n" + " \n" + "Try uninstalling and reinstalling to see if this resolves \n" + "the issue. \n" + " \n" + "If the problem continues, see the Tech Support FAQ at: \n" + "www.secondlife.com/support"; + forceDisconnect(message.str()); + + LLApp::instance()->writeMiniDump(); } // This routine may get called more than once during the shutdown process. @@ -4454,93 +4454,93 @@ void LLAppViewer::badNetworkHandler() // is destroyed. void LLAppViewer::saveFinalSnapshot() { - if (!mSavedFinalSnapshot) - { - gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal()); - gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal()); - gViewerWindow->setCursor(UI_CURSOR_WAIT); - gAgentCamera.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch - gSavedSettings.setBOOL("ShowParcelOwners", FALSE); - idle(); - - std::string snap_filename = gDirUtilp->getLindenUserDir(); - snap_filename += gDirUtilp->getDirDelimiter(); - snap_filename += LLStartUp::getScreenLastFilename(); - // use full pixel dimensions of viewer window (not post-scale dimensions) - gViewerWindow->saveSnapshot(snap_filename, - gViewerWindow->getWindowWidthRaw(), - gViewerWindow->getWindowHeightRaw(), - FALSE, - gSavedSettings.getBOOL("RenderHUDInSnapshot"), - TRUE, - LLSnapshotModel::SNAPSHOT_TYPE_COLOR, - LLSnapshotModel::SNAPSHOT_FORMAT_PNG); - mSavedFinalSnapshot = TRUE; - - if (gAgent.isInHomeRegion()) - { - LLVector3d home; - if (gAgent.getHomePosGlobal(&home) && dist_vec(home, gAgent.getPositionGlobal()) < 10) - { - // We are at home position or close to it, see if we need to create home screenshot - // Notes: - // 1. It might be beneficial to also replace home if file is too old - // 2. This is far from best way/place to update screenshot since location might be not fully loaded, - // but we don't have many options - std::string snap_home = gDirUtilp->getLindenUserDir(); - snap_home += gDirUtilp->getDirDelimiter(); - snap_home += LLStartUp::getScreenHomeFilename(); - if (!gDirUtilp->fileExists(snap_home)) - { - // We are at home position yet no home image exist, fix it - LLFile::copy(snap_filename, snap_home); - } - } - } - } + if (!mSavedFinalSnapshot) + { + gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal()); + gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal()); + gViewerWindow->setCursor(UI_CURSOR_WAIT); + gAgentCamera.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch + gSavedSettings.setBOOL("ShowParcelOwners", FALSE); + idle(); + + std::string snap_filename = gDirUtilp->getLindenUserDir(); + snap_filename += gDirUtilp->getDirDelimiter(); + snap_filename += LLStartUp::getScreenLastFilename(); + // use full pixel dimensions of viewer window (not post-scale dimensions) + gViewerWindow->saveSnapshot(snap_filename, + gViewerWindow->getWindowWidthRaw(), + gViewerWindow->getWindowHeightRaw(), + FALSE, + gSavedSettings.getBOOL("RenderHUDInSnapshot"), + TRUE, + LLSnapshotModel::SNAPSHOT_TYPE_COLOR, + LLSnapshotModel::SNAPSHOT_FORMAT_PNG); + mSavedFinalSnapshot = TRUE; + + if (gAgent.isInHomeRegion()) + { + LLVector3d home; + if (gAgent.getHomePosGlobal(&home) && dist_vec(home, gAgent.getPositionGlobal()) < 10) + { + // We are at home position or close to it, see if we need to create home screenshot + // Notes: + // 1. It might be beneficial to also replace home if file is too old + // 2. This is far from best way/place to update screenshot since location might be not fully loaded, + // but we don't have many options + std::string snap_home = gDirUtilp->getLindenUserDir(); + snap_home += gDirUtilp->getDirDelimiter(); + snap_home += LLStartUp::getScreenHomeFilename(); + if (!gDirUtilp->fileExists(snap_home)) + { + // We are at home position yet no home image exist, fix it + LLFile::copy(snap_filename, snap_home); + } + } + } + } } void LLAppViewer::loadNameCache() { - // display names cache - std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); - LL_INFOS("AvNameCache") << filename << LL_ENDL; - llifstream name_cache_stream(filename.c_str()); - if(name_cache_stream.is_open()) - { - if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream)) + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + LL_INFOS("AvNameCache") << filename << LL_ENDL; + llifstream name_cache_stream(filename.c_str()); + if(name_cache_stream.is_open()) + { + if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream)) { LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL; name_cache_stream.close(); LLFile::remove(filename); } - } + } - if (!gCacheName) return; + if (!gCacheName) return; - std::string name_cache; - name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); - llifstream cache_file(name_cache.c_str()); - if(cache_file.is_open()) - { - if(gCacheName->importFile(cache_file)) return; - } + std::string name_cache; + name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); + llifstream cache_file(name_cache.c_str()); + if(cache_file.is_open()) + { + if(gCacheName->importFile(cache_file)) return; + } } void LLAppViewer::saveNameCache() { - // display names cache - std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); - llofstream name_cache_stream(filename.c_str()); - if(name_cache_stream.is_open()) - { - LLAvatarNameCache::getInstance()->exportFile(name_cache_stream); + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + llofstream name_cache_stream(filename.c_str()); + if(name_cache_stream.is_open()) + { + LLAvatarNameCache::getInstance()->exportFile(name_cache_stream); } // real names cache - if (gCacheName) + if (gCacheName) { std::string name_cache; name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); @@ -4549,24 +4549,24 @@ void LLAppViewer::saveNameCache() { gCacheName->exportFile(cache_file); } - } + } } -/*! @brief This class is an LLFrameTimer that can be created with - an elapsed time that starts counting up from the given value - rather than 0.0. +/*! @brief This class is an LLFrameTimer that can be created with + an elapsed time that starts counting up from the given value + rather than 0.0. - Otherwise it behaves the same way as LLFrameTimer. + Otherwise it behaves the same way as LLFrameTimer. */ class LLFrameStatsTimer : public LLFrameTimer { public: - LLFrameStatsTimer(F64 elapsed_already = 0.0) - : LLFrameTimer() - { - mStartTime -= elapsed_already; - } + LLFrameStatsTimer(F64 elapsed_already = 0.0) + : LLFrameTimer() + { + mStartTime -= elapsed_already; + } }; static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio"); @@ -4592,118 +4592,118 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects"); void LLAppViewer::idle() { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - pingMainloopTimeout("Main:Idle"); + pingMainloopTimeout("Main:Idle"); - // Update frame timers - static LLTimer idle_timer; + // Update frame timers + static LLTimer idle_timer; - LLFrameTimer::updateFrameTime(); - LLFrameTimer::updateFrameCount(); - LLEventTimer::updateClass(); + LLFrameTimer::updateFrameTime(); + LLFrameTimer::updateFrameCount(); + LLEventTimer::updateClass(); LLPerfStats::updateClass(); - // LLApp::stepFrame() performs the above three calls plus mRunner.run(). - // Not sure why we don't call stepFrame() here, except that LLRunner seems - // completely redundant with LLEventTimer. - LLNotificationsUI::LLToast::updateClass(); - LLSmoothInterpolation::updateInterpolants(); - LLMortician::updateClass(); - LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() - LLDirPickerThread::clearDead(); - F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); + // LLApp::stepFrame() performs the above three calls plus mRunner.run(). + // Not sure why we don't call stepFrame() here, except that LLRunner seems + // completely redundant with LLEventTimer. + LLNotificationsUI::LLToast::updateClass(); + LLSmoothInterpolation::updateInterpolants(); + LLMortician::updateClass(); + LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() + LLDirPickerThread::clearDead(); + F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); LLGLTFMaterialList::flushUpdates(); - // Service the WorkQueue we use for replies from worker threads. - // Use function statics for the timeslice setting so we only have to fetch - // and convert MainWorkTime once. - static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime"); - static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw); - // MainWorkTime is specified in fractional milliseconds, but std::chrono - // uses integer representations. What if we want less than a microsecond? - // Use nanoseconds. We're very sure we will never need to specify a - // MainWorkTime that would be larger than we could express in - // std::chrono::nanoseconds. - static std::chrono::nanoseconds MainWorkTimeNanoSec{ - std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)}; - gMainloopWork.runFor(MainWorkTimeNanoSec); - - // Cap out-of-control frame times - // Too low because in menus, swapping, debugger, etc. - // Too high because idle called with no objects in view, etc. - const F32 MIN_FRAME_RATE = 1.f; - const F32 MAX_FRAME_RATE = 200.f; - - F32 frame_rate_clamped = 1.f / dt_raw; - frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE); - gFrameDTClamped = 1.f / frame_rate_clamped; - - // Global frame timer - // Smoothly weight toward current frame - gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f; - - F32 qas = gSavedSettings.getF32("QuitAfterSeconds"); - if (qas > 0.f) - { - if (gRenderStartTime.getElapsedTimeF32() > qas) - { - LL_INFOS() << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << LL_ENDL; - LLAppViewer::instance()->forceQuit(); - } - } - - // Must wait until both have avatar object and mute list, so poll - // here. - LLIMProcessing::requestOfflineMessages(); - - /////////////////////////////////// - // - // Special case idle if still starting up - // - if (LLStartUp::getStartupState() < STATE_STARTED) - { - // Skip rest if idle startup returns false (essentially, no world yet) - gGLActive = TRUE; - if (!idle_startup()) - { - gGLActive = FALSE; - return; - } - gGLActive = FALSE; - } - - - F32 yaw = 0.f; // radians - - if (!gDisconnected) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK); - // Update spaceserver timeinfo - LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw)); - - - ////////////////////////////////////// - // - // Update simulator agent state - // - - if (gSavedSettings.getBOOL("RotateRight")) - { - gAgent.moveYaw(-1.f); - } - - { + // Service the WorkQueue we use for replies from worker threads. + // Use function statics for the timeslice setting so we only have to fetch + // and convert MainWorkTime once. + static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime"); + static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw); + // MainWorkTime is specified in fractional milliseconds, but std::chrono + // uses integer representations. What if we want less than a microsecond? + // Use nanoseconds. We're very sure we will never need to specify a + // MainWorkTime that would be larger than we could express in + // std::chrono::nanoseconds. + static std::chrono::nanoseconds MainWorkTimeNanoSec{ + std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)}; + gMainloopWork.runFor(MainWorkTimeNanoSec); + + // Cap out-of-control frame times + // Too low because in menus, swapping, debugger, etc. + // Too high because idle called with no objects in view, etc. + const F32 MIN_FRAME_RATE = 1.f; + const F32 MAX_FRAME_RATE = 200.f; + + F32 frame_rate_clamped = 1.f / dt_raw; + frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE); + gFrameDTClamped = 1.f / frame_rate_clamped; + + // Global frame timer + // Smoothly weight toward current frame + gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f; + + F32 qas = gSavedSettings.getF32("QuitAfterSeconds"); + if (qas > 0.f) + { + if (gRenderStartTime.getElapsedTimeF32() > qas) + { + LL_INFOS() << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << LL_ENDL; + LLAppViewer::instance()->forceQuit(); + } + } + + // Must wait until both have avatar object and mute list, so poll + // here. + LLIMProcessing::requestOfflineMessages(); + + /////////////////////////////////// + // + // Special case idle if still starting up + // + if (LLStartUp::getStartupState() < STATE_STARTED) + { + // Skip rest if idle startup returns false (essentially, no world yet) + gGLActive = TRUE; + if (!idle_startup()) + { + gGLActive = FALSE; + return; + } + gGLActive = FALSE; + } + + + F32 yaw = 0.f; // radians + + if (!gDisconnected) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK); + // Update spaceserver timeinfo + LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw)); + + + ////////////////////////////////////// + // + // Update simulator agent state + // + + if (gSavedSettings.getBOOL("RotateRight")) + { + gAgent.moveYaw(-1.f); + } + + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Autopilot"); - // Handle automatic walking towards points - gAgentPilot.updateTarget(); - gAgent.autoPilot(&yaw); - } + // Handle automatic walking towards points + gAgentPilot.updateTarget(); + gAgent.autoPilot(&yaw); + } - static LLFrameTimer agent_update_timer; + static LLFrameTimer agent_update_timer; - // When appropriate, update agent location to the simulator. - F32 agent_update_time = agent_update_timer.getElapsedTimeF32(); - F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time; + // When appropriate, update agent location to the simulator. + F32 agent_update_time = agent_update_timer.getElapsedTimeF32(); + F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time; bool timed_out = agent_update_time > (1.0f / (F32)AGENT_UPDATES_PER_SECOND); BOOL force_send = // if there is something to send @@ -4714,111 +4714,111 @@ void LLAppViewer::idle() || (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND)); // timing out doesn't warranty that an update will be sent, // just that it will be checked. - if (force_send || timed_out) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - // Send avatar and camera info - mLastAgentControlFlags = gAgent.getControlFlags(); - mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time; - send_agent_update(force_send); - agent_update_timer.reset(); - } - } - - ////////////////////////////////////// - // - // Manage statistics - // - // - { - // Initialize the viewer_stats_timer with an already elapsed time - // of SEND_STATS_PERIOD so that the initial stats report will - // be sent immediately. - static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD); - - // Update session stats every large chunk of time - // *FIX: (?) SAMANTHA - if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected) - { - LL_INFOS() << "Transmitting sessions stats" << LL_ENDL; - bool include_preferences = false; - send_viewer_stats(include_preferences); - viewer_stats_timer.reset(); - } - - // Print the object debugging stats - static LLFrameTimer object_debug_timer; - if (object_debug_timer.getElapsedTimeF32() > 5.f) - { - object_debug_timer.reset(); - if (gObjectList.mNumDeadObjectUpdates) - { - LL_INFOS() << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << LL_ENDL; - gObjectList.mNumDeadObjectUpdates = 0; - } - if (gObjectList.mNumUnknownUpdates) - { - LL_INFOS() << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << LL_ENDL; - gObjectList.mNumUnknownUpdates = 0; - } - - } - } - - if (!gDisconnected) - { + if (force_send || timed_out) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + // Send avatar and camera info + mLastAgentControlFlags = gAgent.getControlFlags(); + mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time; + send_agent_update(force_send); + agent_update_timer.reset(); + } + } + + ////////////////////////////////////// + // + // Manage statistics + // + // + { + // Initialize the viewer_stats_timer with an already elapsed time + // of SEND_STATS_PERIOD so that the initial stats report will + // be sent immediately. + static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD); + + // Update session stats every large chunk of time + // *FIX: (?) SAMANTHA + if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected) + { + LL_INFOS() << "Transmitting sessions stats" << LL_ENDL; + bool include_preferences = false; + send_viewer_stats(include_preferences); + viewer_stats_timer.reset(); + } + + // Print the object debugging stats + static LLFrameTimer object_debug_timer; + if (object_debug_timer.getElapsedTimeF32() > 5.f) + { + object_debug_timer.reset(); + if (gObjectList.mNumDeadObjectUpdates) + { + LL_INFOS() << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << LL_ENDL; + gObjectList.mNumDeadObjectUpdates = 0; + } + if (gObjectList.mNumUnknownUpdates) + { + LL_INFOS() << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << LL_ENDL; + gObjectList.mNumUnknownUpdates = 0; + } + + } + } + + if (!gDisconnected) + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Network"); - //////////////////////////////////////////////// - // - // Network processing - // - // NOTE: Starting at this point, we may still have pointers to "dead" objects - // floating throughout the various object lists. - // - idleNameCache(); - idleNetwork(); + //////////////////////////////////////////////// + // + // Network processing + // + // NOTE: Starting at this point, we may still have pointers to "dead" objects + // floating throughout the various object lists. + // + idleNameCache(); + idleNetwork(); - // Check for away from keyboard, kick idle agents. - idle_afk_check(); + // Check for away from keyboard, kick idle agents. + idle_afk_check(); - // Update statistics for this frame - update_statistics(); - } + // Update statistics for this frame + update_statistics(); + } - //////////////////////////////////////// - // - // Handle the regular UI idle callbacks as well as - // hover callbacks - // + //////////////////////////////////////// + // + // Handle the regular UI idle callbacks as well as + // hover callbacks + // #ifdef LL_DARWIN - if (!mQuitRequested) //MAINT-4243 + if (!mQuitRequested) //MAINT-4243 #endif - { -// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB); + { +// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB); - // Do event notifications if necessary. Yes, we may want to move this elsewhere. - gEventNotifier.update(); + // Do event notifications if necessary. Yes, we may want to move this elsewhere. + gEventNotifier.update(); - gIdleCallbacks.callFunctions(); - gInventory.idleNotifyObservers(); - LLAvatarTracker::instance().idleNotifyObservers(); - } + gIdleCallbacks.callFunctions(); + gInventory.idleNotifyObservers(); + LLAvatarTracker::instance().idleNotifyObservers(); + } - // Metrics logging (LLViewerAssetStats, etc.) - { - static LLTimer report_interval; + // Metrics logging (LLViewerAssetStats, etc.) + { + static LLTimer report_interval; - // *TODO: Add configuration controls for this - F32 seconds = report_interval.getElapsedTimeF32(); - if (seconds >= app_metrics_interval) - { - metricsSend(! gDisconnected); - report_interval.reset(); - } - } + // *TODO: Add configuration controls for this + F32 seconds = report_interval.getElapsedTimeF32(); + if (seconds >= app_metrics_interval) + { + metricsSend(! gDisconnected); + report_interval.reset(); + } + } // Update layonts, handle mouse events, tooltips, e t c @@ -4827,336 +4827,336 @@ void LLAppViewer::idle() // opening chat. gViewerWindow->updateUI(); - if (gDisconnected) + if (gDisconnected) { - return; + return; } - if (gTeleportDisplay) + if (gTeleportDisplay) { - return; + return; } - /////////////////////////////////////// - // Agent and camera movement - // - LLCoordGL current_mouse = gViewerWindow->getCurrentMouse(); + /////////////////////////////////////// + // Agent and camera movement + // + LLCoordGL current_mouse = gViewerWindow->getCurrentMouse(); - { - // After agent and camera moved, figure out if we need to - // deselect objects. - LLSelectMgr::getInstance()->deselectAllIfTooFar(); + { + // After agent and camera moved, figure out if we need to + // deselect objects. + LLSelectMgr::getInstance()->deselectAllIfTooFar(); - } + } - { - // Handle pending gesture processing - LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION); - LLGestureMgr::instance().update(); + { + // Handle pending gesture processing + LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION); + LLGestureMgr::instance().update(); - gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); - } + gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); + } - { - LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE); + { + LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE); if (!(logoutRequestSent() && hasSavedFinalSnapshot())) - { - gObjectList.update(gAgent); + { + gObjectList.update(gAgent); LL::GLTFSceneManager::instance().update(); - } - } - - ////////////////////////////////////// - // - // Deletes objects... - // Has to be done after doing idleUpdates (which can kill objects) - // - - { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP); - { - gObjectList.cleanDeadObjects(); - } - { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES); - LLDrawable::cleanupDeadDrawables(); - } - } - - // - // After this point, in theory we should never see a dead object - // in the various object/drawable lists. - // - - ////////////////////////////////////// - // - // Update/send HUD effects - // - // At this point, HUD effects may clean up some references to - // dead objects. - // - - { - LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS); - LLSelectMgr::getInstance()->updateEffects(); - LLHUDManager::getInstance()->cleanupEffects(); - LLHUDManager::getInstance()->sendEffects(); - } - - //////////////////////////////////////// - // - // Unpack layer data that we've received - // - - { - LL_RECORD_BLOCK_TIME(FTM_NETWORK); - gVLManager.unpackData(); - } - - ///////////////////////// - // - // Update surfaces, and surface textures as well. - // - - LLWorld::getInstance()->updateVisibilities(); - { - const F32 max_region_update_time = .001f; // 1ms - LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); - LLWorld::getInstance()->updateRegions(max_region_update_time); - } - - ///////////////////////// - // - // Update weather effects - // - - // Update wind vector - LLVector3 wind_position_region; - static LLVector3 average_wind; - - LLViewerRegion *regionp; - regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position - if (regionp) - { - gWindVec = regionp->mWind.getVelocity(wind_position_region); - - // Compute average wind and use to drive motion of water - - average_wind = regionp->mWind.getAverage(); - gSky.setWind(average_wind); - //LLVOWater::setWind(average_wind); - } - else - { - gWindVec.setVec(0.0f, 0.0f, 0.0f); - } - - ////////////////////////////////////// - // - // Sort and cull in the new renderer are moved to pipeline.cpp - // Here, particles are updated and drawables are moved. - // - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); - gPipeline.updateMove(); - } - - LLWorld::getInstance()->updateParticles(); - - if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera()) - { - gAgentPilot.moveCamera(); - } - else if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - LLViewerJoystick::getInstance()->moveFlycam(); - } - else - { - if (LLToolMgr::getInstance()->inBuildMode()) - { - LLViewerJoystick::getInstance()->moveObjects(); - } - - gAgentCamera.updateCamera(); - } - - // update media focus - LLViewerMediaFocus::getInstance()->update(); - - // Update marketplace - LLMarketplaceInventoryImporter::update(); - LLMarketplaceInventoryNotifications::update(); - - // objects and camera should be in sync, do LOD calculations now - { - LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE); - gObjectList.updateApparentAngles(gAgent); - } - - // Update AV render info - LLAvatarRenderInfoAccountant::getInstance()->idle(); - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); - - if (gAudiop) - { - audio_update_volume(false); - audio_update_listener(); - audio_update_wind(false); - - // this line actually commits the changes we've made to source positions, etc. - gAudiop->idle(); - } - } - - // Handle shutdown process, for example, - // wait for floaters to close, send quit message, - // forcibly quit if it has taken too long - if (mQuitRequested) - { - gGLActive = TRUE; - idleShutdown(); - } + } + } + + ////////////////////////////////////// + // + // Deletes objects... + // Has to be done after doing idleUpdates (which can kill objects) + // + + { + LL_RECORD_BLOCK_TIME(FTM_CLEANUP); + { + gObjectList.cleanDeadObjects(); + } + { + LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES); + LLDrawable::cleanupDeadDrawables(); + } + } + + // + // After this point, in theory we should never see a dead object + // in the various object/drawable lists. + // + + ////////////////////////////////////// + // + // Update/send HUD effects + // + // At this point, HUD effects may clean up some references to + // dead objects. + // + + { + LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS); + LLSelectMgr::getInstance()->updateEffects(); + LLHUDManager::getInstance()->cleanupEffects(); + LLHUDManager::getInstance()->sendEffects(); + } + + //////////////////////////////////////// + // + // Unpack layer data that we've received + // + + { + LL_RECORD_BLOCK_TIME(FTM_NETWORK); + gVLManager.unpackData(); + } + + ///////////////////////// + // + // Update surfaces, and surface textures as well. + // + + LLWorld::getInstance()->updateVisibilities(); + { + const F32 max_region_update_time = .001f; // 1ms + LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); + LLWorld::getInstance()->updateRegions(max_region_update_time); + } + + ///////////////////////// + // + // Update weather effects + // + + // Update wind vector + LLVector3 wind_position_region; + static LLVector3 average_wind; + + LLViewerRegion *regionp; + regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position + if (regionp) + { + gWindVec = regionp->mWind.getVelocity(wind_position_region); + + // Compute average wind and use to drive motion of water + + average_wind = regionp->mWind.getAverage(); + gSky.setWind(average_wind); + //LLVOWater::setWind(average_wind); + } + else + { + gWindVec.setVec(0.0f, 0.0f, 0.0f); + } + + ////////////////////////////////////// + // + // Sort and cull in the new renderer are moved to pipeline.cpp + // Here, particles are updated and drawables are moved. + // + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); + gPipeline.updateMove(); + } + + LLWorld::getInstance()->updateParticles(); + + if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera()) + { + gAgentPilot.moveCamera(); + } + else if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + LLViewerJoystick::getInstance()->moveFlycam(); + } + else + { + if (LLToolMgr::getInstance()->inBuildMode()) + { + LLViewerJoystick::getInstance()->moveObjects(); + } + + gAgentCamera.updateCamera(); + } + + // update media focus + LLViewerMediaFocus::getInstance()->update(); + + // Update marketplace + LLMarketplaceInventoryImporter::update(); + LLMarketplaceInventoryNotifications::update(); + + // objects and camera should be in sync, do LOD calculations now + { + LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE); + gObjectList.updateApparentAngles(gAgent); + } + + // Update AV render info + LLAvatarRenderInfoAccountant::getInstance()->idle(); + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); + + if (gAudiop) + { + audio_update_volume(false); + audio_update_listener(); + audio_update_wind(false); + + // this line actually commits the changes we've made to source positions, etc. + gAudiop->idle(); + } + } + + // Handle shutdown process, for example, + // wait for floaters to close, send quit message, + // forcibly quit if it has taken too long + if (mQuitRequested) + { + gGLActive = TRUE; + idleShutdown(); + } } void LLAppViewer::idleShutdown() { - // Wait for all modal alerts to get resolved - if (LLModalDialog::activeCount() > 0) - { - return; - } - - // close IM interface - if(gIMMgr) - { - gIMMgr->disconnectAllSessions(); - } - - // Wait for all floaters to get resolved - if (gFloaterView - && !gFloaterView->allChildrenClosed()) - { - return; - } - - - - - // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup() - // *TODO: ugly - static bool saved_teleport_history = false; - if (!saved_teleport_history) - { - saved_teleport_history = true; - LLTeleportHistory::getInstance()->dump(); - LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this - return; - } - - static bool saved_snapshot = false; - if (!saved_snapshot) - { - saved_snapshot = true; - saveFinalSnapshot(); - return; - } - - const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f; - - S32 pending_uploads = gAssetStorage->getNumPendingUploads(); - if (pending_uploads > 0 - && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME - && !logoutRequestSent()) - { - static S32 total_uploads = 0; - // Sometimes total upload count can change during logout. - total_uploads = llmax(total_uploads, pending_uploads); - gViewerWindow->setShowProgress(TRUE); - S32 finished_uploads = total_uploads - pending_uploads; - F32 percent = 100.f * finished_uploads / total_uploads; - gViewerWindow->setProgressPercent(percent); - gViewerWindow->setProgressString(LLTrans::getString("SavingSettings")); - return; - } - - if (gPendingMetricsUploads > 0 - && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME - && !logoutRequestSent()) - { + // Wait for all modal alerts to get resolved + if (LLModalDialog::activeCount() > 0) + { + return; + } + + // close IM interface + if(gIMMgr) + { + gIMMgr->disconnectAllSessions(); + } + + // Wait for all floaters to get resolved + if (gFloaterView + && !gFloaterView->allChildrenClosed()) + { + return; + } + + + + + // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup() + // *TODO: ugly + static bool saved_teleport_history = false; + if (!saved_teleport_history) + { + saved_teleport_history = true; + LLTeleportHistory::getInstance()->dump(); + LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this + return; + } + + static bool saved_snapshot = false; + if (!saved_snapshot) + { + saved_snapshot = true; + saveFinalSnapshot(); + return; + } + + const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f; + + S32 pending_uploads = gAssetStorage->getNumPendingUploads(); + if (pending_uploads > 0 + && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME + && !logoutRequestSent()) + { + static S32 total_uploads = 0; + // Sometimes total upload count can change during logout. + total_uploads = llmax(total_uploads, pending_uploads); + gViewerWindow->setShowProgress(TRUE); + S32 finished_uploads = total_uploads - pending_uploads; + F32 percent = 100.f * finished_uploads / total_uploads; + gViewerWindow->setProgressPercent(percent); + gViewerWindow->setProgressString(LLTrans::getString("SavingSettings")); + return; + } + + if (gPendingMetricsUploads > 0 + && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME + && !logoutRequestSent()) + { gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(100.f); gViewerWindow->setProgressString(LLTrans::getString("LoggingOut")); - return; - } - - // All floaters are closed. Tell server we want to quit. - if( !logoutRequestSent() ) - { - sendLogoutRequest(); - - // Wait for a LogoutReply message - gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(100.f); - gViewerWindow->setProgressString(LLTrans::getString("LoggingOut")); - return; - } - - // Make sure that we quit if we haven't received a reply from the server. - if( logoutRequestSent() - && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime ) - { - forceQuit(); - return; - } + return; + } + + // All floaters are closed. Tell server we want to quit. + if( !logoutRequestSent() ) + { + sendLogoutRequest(); + + // Wait for a LogoutReply message + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(100.f); + gViewerWindow->setProgressString(LLTrans::getString("LoggingOut")); + return; + } + + // Make sure that we quit if we haven't received a reply from the server. + if( logoutRequestSent() + && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime ) + { + forceQuit(); + return; + } } void LLAppViewer::sendLogoutRequest() { - if(!mLogoutRequestSent && gMessageSystem) - { - //Set internal status variables and marker files before actually starting the logout process - gLogoutInProgress = TRUE; - if (!mSecondInstance) - { - mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - - mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); - if (mLogoutMarkerFile.getFileHandle()) - { - LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; - recordMarkerVersion(mLogoutMarkerFile); - } - else - { - LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; - } - } - else - { - LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL; - } - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_LogoutRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gAgent.sendReliableMessage(); - - gLogoutTimer.reset(); - gLogoutMaxTime = LOGOUT_REQUEST_TIME; - mLogoutRequestSent = TRUE; - - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->leaveChannel(); - } - } + if(!mLogoutRequestSent && gMessageSystem) + { + //Set internal status variables and marker files before actually starting the logout process + gLogoutInProgress = TRUE; + if (!mSecondInstance) + { + mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); + + mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); + if (mLogoutMarkerFile.getFileHandle()) + { + LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; + recordMarkerVersion(mLogoutMarkerFile); + } + else + { + LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; + } + } + else + { + LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL; + } + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LogoutRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + + gLogoutTimer.reset(); + gLogoutMaxTime = LOGOUT_REQUEST_TIME; + mLogoutRequestSent = TRUE; + + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->leaveChannel(); + } + } } void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp) @@ -5202,19 +5202,19 @@ void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp) void LLAppViewer::idleNameCache() { - // Neither old nor new name cache can function before agent has a region - LLViewerRegion* region = gAgent.getRegion(); + // Neither old nor new name cache can function before agent has a region + LLViewerRegion* region = gAgent.getRegion(); if (!region) { return; } - // deal with any queued name requests and replies. - gCacheName->processPending(); + // deal with any queued name requests and replies. + gCacheName->processPending(); - // Can't run the new cache until we have the list of capabilities - // for the agent region, and can therefore decide whether to use - // display names or fall back to the old name system. + // Can't run the new cache until we have the list of capabilities + // for the agent region, and can therefore decide whether to use + // display names or fall back to the old name system. if (!region->capabilitiesReceived()) { return; @@ -5244,141 +5244,141 @@ static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circ void LLAppViewer::idleNetwork() { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - pingMainloopTimeout("idleNetwork"); - - gObjectList.mNumNewObjects = 0; - S32 total_decoded = 0; - - if (!gSavedSettings.getBOOL("SpeedTest")) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode - - LLTimer check_message_timer; - // Read all available packets from network - const S64 frame_count = gFrameCount; // U32->S64 - F32 total_time = 0.0f; - - { - LockMessageChecker lmc(gMessageSystem); - while (lmc.checkAllMessages(frame_count, gServicePump)) - { - if (gDoDisconnect) - { - // We're disconnecting, don't process any more messages from the server - // We're usually disconnecting due to either network corruption or a - // server going down, so this is OK. - break; - } - - total_decoded++; - gPacketsIn++; - - if (total_decoded > MESSAGE_MAX_PER_FRAME) - { - break; - } + pingMainloopTimeout("idleNetwork"); + + gObjectList.mNumNewObjects = 0; + S32 total_decoded = 0; + + if (!gSavedSettings.getBOOL("SpeedTest")) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode + + LLTimer check_message_timer; + // Read all available packets from network + const S64 frame_count = gFrameCount; // U32->S64 + F32 total_time = 0.0f; + + { + LockMessageChecker lmc(gMessageSystem); + while (lmc.checkAllMessages(frame_count, gServicePump)) + { + if (gDoDisconnect) + { + // We're disconnecting, don't process any more messages from the server + // We're usually disconnecting due to either network corruption or a + // server going down, so this is OK. + break; + } + + total_decoded++; + gPacketsIn++; + + if (total_decoded > MESSAGE_MAX_PER_FRAME) + { + break; + } #ifdef TIME_THROTTLE_MESSAGES - // Prevent slow packets from completely destroying the frame rate. - // This usually happens due to clumps of avatars taking huge amount - // of network processing time (which needs to be fixed, but this is - // a good limit anyway). - total_time = check_message_timer.getElapsedTimeF32(); - if (total_time >= CheckMessagesMaxTime) - break; + // Prevent slow packets from completely destroying the frame rate. + // This usually happens due to clumps of avatars taking huge amount + // of network processing time (which needs to be fixed, but this is + // a good limit anyway). + total_time = check_message_timer.getElapsedTimeF32(); + if (total_time >= CheckMessagesMaxTime) + break; #endif - } + } - // Handle per-frame message system processing. - lmc.processAcks(gSavedSettings.getF32("AckCollectTime")); - } + // Handle per-frame message system processing. + lmc.processAcks(gSavedSettings.getF32("AckCollectTime")); + } #ifdef TIME_THROTTLE_MESSAGES - if (total_time >= CheckMessagesMaxTime) - { - // Increase CheckMessagesMaxTime so that we will eventually catch up - CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames - } - else - { - // Reset CheckMessagesMaxTime to default value - CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; - } + if (total_time >= CheckMessagesMaxTime) + { + // Increase CheckMessagesMaxTime so that we will eventually catch up + CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames + } + else + { + // Reset CheckMessagesMaxTime to default value + CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; + } #endif - // we want to clear the control after sending out all necessary agent updates - gAgent.resetControlFlags(); - - // Decode enqueued messages... - S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; - - if( remaining_possible_decodes <= 0 ) - { - LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL; - } - - if (gPrintMessagesThisFrame) - { - LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL; - gPrintMessagesThisFrame = FALSE; - } - } - add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); - - // Retransmit unacknowledged packets. - gXferManager->retransmitUnackedPackets(); - gAssetStorage->checkForTimeouts(); - gViewerThrottle.updateDynamicThrottle(); - - // Check that the circuit between the viewer and the agent's current - // region is still alive - LLViewerRegion *agent_region = gAgent.getRegion(); - if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED)) - { - LLUUID this_region_id = agent_region->getRegionID(); - bool this_region_alive = agent_region->isAlive(); - if ((mAgentRegionLastAlive && !this_region_alive) // newly dead - && (mAgentRegionLastID == this_region_id)) // same region - { - forceDisconnect(LLTrans::getString("AgentLostConnection")); - } - mAgentRegionLastID = this_region_id; - mAgentRegionLastAlive = this_region_alive; - } + // we want to clear the control after sending out all necessary agent updates + gAgent.resetControlFlags(); + + // Decode enqueued messages... + S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; + + if( remaining_possible_decodes <= 0 ) + { + LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL; + } + + if (gPrintMessagesThisFrame) + { + LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL; + gPrintMessagesThisFrame = FALSE; + } + } + add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); + + // Retransmit unacknowledged packets. + gXferManager->retransmitUnackedPackets(); + gAssetStorage->checkForTimeouts(); + gViewerThrottle.updateDynamicThrottle(); + + // Check that the circuit between the viewer and the agent's current + // region is still alive + LLViewerRegion *agent_region = gAgent.getRegion(); + if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED)) + { + LLUUID this_region_id = agent_region->getRegionID(); + bool this_region_alive = agent_region->isAlive(); + if ((mAgentRegionLastAlive && !this_region_alive) // newly dead + && (mAgentRegionLastID == this_region_id)) // same region + { + forceDisconnect(LLTrans::getString("AgentLostConnection")); + } + mAgentRegionLastID = this_region_id; + mAgentRegionLastAlive = this_region_alive; + } } void LLAppViewer::disconnectViewer() { - if (gDisconnected) - { - return; - } - // - // Cleanup after quitting. - // - // Save snapshot for next time, if we made it through initialization - - LL_INFOS() << "Disconnecting viewer!" << LL_ENDL; - - // Dump our frame statistics - - // Remember if we were flying - gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() ); - - // Un-minimize all windows so they don't get saved minimized - if (gFloaterView) - { - gFloaterView->restoreAll(); - } - - if (LLSelectMgr::instanceExists()) - { - LLSelectMgr::getInstance()->deselectAll(); - } - - // save inventory if appropriate + if (gDisconnected) + { + return; + } + // + // Cleanup after quitting. + // + // Save snapshot for next time, if we made it through initialization + + LL_INFOS() << "Disconnecting viewer!" << LL_ENDL; + + // Dump our frame statistics + + // Remember if we were flying + gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() ); + + // Un-minimize all windows so they don't get saved minimized + if (gFloaterView) + { + gFloaterView->restoreAll(); + } + + if (LLSelectMgr::instanceExists()) + { + LLSelectMgr::getInstance()->deselectAll(); + } + + // save inventory if appropriate if (gInventory.isInventoryUsable() && gAgent.getID().notNull()) // Shouldn't be null at this stage { @@ -5393,44 +5393,44 @@ void LLAppViewer::disconnectViewer() } } - saveNameCache(); - if (LLExperienceCache::instanceExists()) - { - // TODO: LLExperienceCache::cleanup() logic should be moved to - // cleanupSingleton(). - LLExperienceCache::instance().cleanup(); - } + saveNameCache(); + if (LLExperienceCache::instanceExists()) + { + // TODO: LLExperienceCache::cleanup() logic should be moved to + // cleanupSingleton(). + LLExperienceCache::instance().cleanup(); + } - // close inventory interface, close all windows - LLSidepanelInventory::cleanup(); + // close inventory interface, close all windows + LLSidepanelInventory::cleanup(); - gAgentWearables.cleanup(); - gAgentCamera.cleanup(); - // Also writes cached agent settings to gSavedSettings - gAgent.cleanup(); + gAgentWearables.cleanup(); + gAgentCamera.cleanup(); + // Also writes cached agent settings to gSavedSettings + gAgent.cleanup(); - // This is where we used to call gObjectList.destroy() and then delete gWorldp. - // Now we just ask the LLWorld singleton to cleanly shut down. - if(LLWorld::instanceExists()) - { - LLWorld::getInstance()->resetClass(); - } - LLVOCache::deleteSingleton(); + // This is where we used to call gObjectList.destroy() and then delete gWorldp. + // Now we just ask the LLWorld singleton to cleanly shut down. + if(LLWorld::instanceExists()) + { + LLWorld::getInstance()->resetClass(); + } + LLVOCache::deleteSingleton(); - // call all self-registered classes - LLDestroyClassList::instance().fireCallbacks(); + // call all self-registered classes + LLDestroyClassList::instance().fireCallbacks(); - cleanup_xfer_manager(); - gDisconnected = TRUE; + cleanup_xfer_manager(); + gDisconnected = TRUE; - // Pass the connection state to LLUrlEntryParcel not to attempt - // parcel info requests while disconnected. - LLUrlEntryParcel::setDisconnected(gDisconnected); + // Pass the connection state to LLUrlEntryParcel not to attempt + // parcel info requests while disconnected. + LLUrlEntryParcel::setDisconnected(gDisconnected); } void LLAppViewer::forceErrorLLError() { - LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; + LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; } void LLAppViewer::forceErrorLLErrorMsg() @@ -5443,7 +5443,7 @@ void LLAppViewer::forceErrorLLErrorMsg() void LLAppViewer::forceErrorBreakpoint() { - LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL; + LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL; #ifdef LL_WINDOWS DebugBreak(); #else @@ -5454,7 +5454,7 @@ void LLAppViewer::forceErrorBreakpoint() void LLAppViewer::forceErrorBadMemoryAccess() { - LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL; + LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL; S32* crash = NULL; *crash = 0xDEADBEEF; return; @@ -5462,7 +5462,7 @@ void LLAppViewer::forceErrorBadMemoryAccess() void LLAppViewer::forceErrorInfiniteLoop() { - LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL; + LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL; // Loop is intentionally complicated to fool basic loop detection LLTimer timer_total; LLTimer timer_expiry; @@ -5481,7 +5481,7 @@ void LLAppViewer::forceErrorInfiniteLoop() void LLAppViewer::forceErrorSoftwareException() { - LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL; + LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL; LLTHROW(LLException("User selected Force Software Exception")); } @@ -5494,8 +5494,8 @@ void LLAppViewer::forceErrorOSSpecificException() void LLAppViewer::forceErrorDriverCrash() { - LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL; - glDeleteTextures(1, NULL); + LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL; + glDeleteTextures(1, NULL); } void LLAppViewer::forceErrorCoroutineCrash() @@ -5527,120 +5527,120 @@ void LLAppViewer::forceErrorThreadCrash() void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) { - if(!mMainloopTimeout) - { - mMainloopTimeout = new LLWatchdogTimeout(); - resumeMainloopTimeout(state, secs); - } + if(!mMainloopTimeout) + { + mMainloopTimeout = new LLWatchdogTimeout(); + resumeMainloopTimeout(state, secs); + } } void LLAppViewer::destroyMainloopTimeout() { - if(mMainloopTimeout) - { - delete mMainloopTimeout; - mMainloopTimeout = NULL; - } + if(mMainloopTimeout) + { + delete mMainloopTimeout; + mMainloopTimeout = NULL; + } } void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs) { - if(mMainloopTimeout) - { - if(secs < 0.0f) - { - static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); - secs = mainloop_timeout; - } - - mMainloopTimeout->setTimeout(secs); - mMainloopTimeout->start(state); - } + if(mMainloopTimeout) + { + if(secs < 0.0f) + { + static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); + secs = mainloop_timeout; + } + + mMainloopTimeout->setTimeout(secs); + mMainloopTimeout->start(state); + } } void LLAppViewer::pauseMainloopTimeout() { - if(mMainloopTimeout) - { - mMainloopTimeout->stop(); - } + if(mMainloopTimeout) + { + mMainloopTimeout->stop(); + } } void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - if(mMainloopTimeout) - { - if(secs < 0.0f) - { - static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); - secs = mainloop_timeout; - } - - mMainloopTimeout->setTimeout(secs); - mMainloopTimeout->ping(state); - } + if(mMainloopTimeout) + { + if(secs < 0.0f) + { + static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); + secs = mainloop_timeout; + } + + mMainloopTimeout->setTimeout(secs); + mMainloopTimeout->ping(state); + } } void LLAppViewer::handleLoginComplete() { - gLoggedInTime.start(); - initMainloopTimeout("Mainloop Init"); - - // Store some data to DebugInfo in case of a freeze. - gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel(); - - gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor(); - gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor(); - gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch(); - gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild()); - - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if ( parcel && parcel->getMusicURL()[0]) - { - gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); - } - if ( parcel && parcel->getMediaURL()[0]) - { - gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); - } - - gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); - gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); - gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); - gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); - - if(gAgent.getRegion()) - { - gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName(); - gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); - } - - if(LLAppViewer::instance()->mMainloopTimeout) - { - gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); - } - - mOnLoginCompleted(); - - writeDebugInfo(); - - // we logged in successfully, so save settings on logout - LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL; - mSavePerAccountSettings=true; + gLoggedInTime.start(); + initMainloopTimeout("Mainloop Init"); + + // Store some data to DebugInfo in case of a freeze. + gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel(); + + gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor(); + gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor(); + gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch(); + gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild()); + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if ( parcel && parcel->getMusicURL()[0]) + { + gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); + } + if ( parcel && parcel->getMediaURL()[0]) + { + gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); + } + + gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); + gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); + gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); + gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); + + if(gAgent.getRegion()) + { + gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName(); + gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); + } + + if(LLAppViewer::instance()->mMainloopTimeout) + { + gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); + } + + mOnLoginCompleted(); + + writeDebugInfo(); + + // we logged in successfully, so save settings on logout + LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL; + mSavePerAccountSettings=true; } //virtual void LLAppViewer::setMasterSystemAudioMute(bool mute) { - gSavedSettings.setBOOL("MuteAudio", mute); + gSavedSettings.setBOOL("MuteAudio", mute); } //virtual bool LLAppViewer::getMasterSystemAudioMute() { - return gSavedSettings.getBOOL("MuteAudio"); + return gSavedSettings.getBOOL("MuteAudio"); } //---------------------------------------------------------------------------- @@ -5656,10 +5656,10 @@ bool LLAppViewer::getMasterSystemAudioMute() */ void LLAppViewer::metricsUpdateRegion(U64 region_handle) { - if (0 != region_handle) - { - LLViewerAssetStatsFF::set_region(region_handle); - } + if (0 != region_handle) + { + LLViewerAssetStatsFF::set_region(region_handle); + } } /** @@ -5668,35 +5668,35 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) */ void LLAppViewer::metricsSend(bool enable_reporting) { - if (! gViewerAssetStats) - return; + if (! gViewerAssetStats) + return; - if (LLAppViewer::sTextureFetch) - { - LLViewerRegion * regionp = gAgent.getRegion(); + if (LLAppViewer::sTextureFetch) + { + LLViewerRegion * regionp = gAgent.getRegion(); - if (enable_reporting && regionp) - { - std::string caps_url = regionp->getCapability("ViewerMetrics"); + if (enable_reporting && regionp) + { + std::string caps_url = regionp->getCapability("ViewerMetrics"); LLSD sd = gViewerAssetStats->asLLSD(true); - // Send a report request into 'thread1' to get the rest of the data - // and provide some additional parameters while here. - LLAppViewer::sTextureFetch->commandSendMetrics(caps_url, - gAgentSessionID, - gAgentID, - sd); - } - else - { - LLAppViewer::sTextureFetch->commandDataBreak(); - } - } - - // Reset even if we can't report. Rather than gather up a huge chunk of - // data, we'll keep to our sampling interval and retain the data - // resolution in time. - gViewerAssetStats->restart(); + // Send a report request into 'thread1' to get the rest of the data + // and provide some additional parameters while here. + LLAppViewer::sTextureFetch->commandSendMetrics(caps_url, + gAgentSessionID, + gAgentID, + sd); + } + else + { + LLAppViewer::sTextureFetch->commandDataBreak(); + } + } + + // Reset even if we can't report. Rather than gather up a huge chunk of + // data, we'll keep to our sampling interval and retain the data + // resolution in time. + gViewerAssetStats->restart(); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index fc182fc2e2..726667813a 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -1,25 +1,25 @@ -/** +/** * @file lldrawable.h * @brief LLDrawable class definition * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -67,280 +67,280 @@ class LLDrawable public: typedef std::vector face_list_t; - LLDrawable(const LLDrawable& rhs) + LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) - { - *this = rhs; - } - - const LLDrawable& operator=(const LLDrawable& rhs) - { - LL_ERRS() << "Illegal operation!" << LL_ENDL; - return *this; - } - - static void initClass(); - - LLDrawable(LLViewerObject *vobj, bool new_entry = false); - - void markDead(); // Mark this drawable as dead - BOOL isDead() const { return isState(DEAD); } - BOOL isNew() const { return !isState(BUILT); } - BOOL isUnload() const { return isState(FOR_UNLOAD); } - - BOOL isLight() const; - - virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); - - LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} - LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } - const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); } - LLPointer& getVObj() { return mVObjp; } - const LLViewerObject *getVObj() const { return mVObjp; } - LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK - - const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } - const LLMatrix4& getRenderMatrix() const; - void setPosition(LLVector3 v) const { } - const LLVector3& getPosition() const { return mXform.getPosition(); } - const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } - const LLVector3 getPositionAgent() const; - const LLVector3& getScale() const { return mCurrentScale; } - void setScale(const LLVector3& scale) { mCurrentScale = scale; } - const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); } - const LLQuaternion& getRotation() const { return mXform.getRotation(); } - F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } - S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - - void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } - LLXformMatrix* getXform() { return &mXform; } - - U32 getState() const { return mState; } - BOOL isState (U32 bits) const { return ((mState & bits) != 0); } - void setState (U32 bits) { mState |= bits; } - void clearState(U32 bits) { mState &= ~bits; } - - BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); } - BOOL isRoot() const { return !mParent || mParent->isAvatar(); } + { + *this = rhs; + } + + const LLDrawable& operator=(const LLDrawable& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } + + static void initClass(); + + LLDrawable(LLViewerObject *vobj, bool new_entry = false); + + void markDead(); // Mark this drawable as dead + BOOL isDead() const { return isState(DEAD); } + BOOL isNew() const { return !isState(BUILT); } + BOOL isUnload() const { return isState(FOR_UNLOAD); } + + BOOL isLight() const; + + virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); + + LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} + LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } + const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); } + LLPointer& getVObj() { return mVObjp; } + const LLViewerObject *getVObj() const { return mVObjp; } + LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK + + const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } + const LLMatrix4& getRenderMatrix() const; + void setPosition(LLVector3 v) const { } + const LLVector3& getPosition() const { return mXform.getPosition(); } + const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } + const LLVector3 getPositionAgent() const; + const LLVector3& getScale() const { return mCurrentScale; } + void setScale(const LLVector3& scale) { mCurrentScale = scale; } + const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); } + const LLQuaternion& getRotation() const { return mXform.getRotation(); } + F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } + S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } + + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } + LLXformMatrix* getXform() { return &mXform; } + + U32 getState() const { return mState; } + BOOL isState (U32 bits) const { return ((mState & bits) != 0); } + void setState (U32 bits) { mState |= bits; } + void clearState(U32 bits) { mState &= ~bits; } + + BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); } + BOOL isRoot() const { return !mParent || mParent->isAvatar(); } LLDrawable* getRoot(); - BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); } - virtual BOOL isSpatialBridge() const { return FALSE; } - virtual LLSpatialPartition* asPartition() { return NULL; } - LLDrawable* getParent() const { return mParent; } - - // must set parent through LLViewerObject:: () - //BOOL setParent(LLDrawable *parent); - - inline LLFace* getFace(const S32 i) const; - inline S32 getNumFaces() const; + BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); } + virtual BOOL isSpatialBridge() const { return FALSE; } + virtual LLSpatialPartition* asPartition() { return NULL; } + LLDrawable* getParent() const { return mParent; } + + // must set parent through LLViewerObject:: () + //BOOL setParent(LLDrawable *parent); + + inline LLFace* getFace(const S32 i) const; + inline S32 getNumFaces() const; face_list_t& getFaces() { return mFaces; } const face_list_t& getFaces() const { return mFaces; } - //void removeFace(const S32 i); // SJB: Avoid using this, it's slow - LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); - LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep); - LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp); - LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp); - void deleteFaces(S32 offset, S32 count); - void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); - void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); - void mergeFaces(LLDrawable* src); - - void init(bool new_entry); - void unload(); - void destroy(); - - void update(); - F32 updateXform(BOOL undamped); - - virtual void makeActive(); - /*virtual*/ void makeStatic(BOOL warning_enabled = TRUE); - - BOOL isActive() const { return isState(ACTIVE); } - BOOL isStatic() const { return !isActive(); } - BOOL isAnimating() const; - - virtual BOOL updateMove(); - virtual void movePartition(); - - void updateTexture(); - void updateMaterial(); - virtual void updateDistance(LLCamera& camera, bool force_update); - BOOL updateGeometry(); - void updateFaceSize(S32 idx); - - void updateSpecialHoverCursor(BOOL enabled); - - virtual void shiftPos(const LLVector4a &shift_vector); - - S32 getGeneration() const { return mGeneration; } - - BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; } - void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); } - - bool isVisible() const; - bool isRecentlyVisible() const; - - virtual void cleanupReferences(); - - void setGroup(LLViewerOctreeGroup* group); - void setRadius(const F32 radius); - F32 getRadius() const { return mRadius; } - F32 getVisibilityRadius() const; - - void updateUVMinMax(); // Updates the cache of sun space bounding box. - - const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; - virtual void updateSpatialExtents(); - virtual void updateBinRadius(); - - void setRenderType(S32 type) { mRenderType = type; } - BOOL isRenderType(S32 type) { return mRenderType == type; } - S32 getRenderType() { return mRenderType; } - - // Debugging methods - S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... - - LLSpatialPartition* getSpatialPartition(); - - void removeFromOctree(); - - void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } - LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } - - // Statics - static void incrementVisible(); - static void cleanupDeadDrawables(); + //void removeFace(const S32 i); // SJB: Avoid using this, it's slow + LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); + LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep); + LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp); + LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp); + void deleteFaces(S32 offset, S32 count); + void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); + void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); + void mergeFaces(LLDrawable* src); + + void init(bool new_entry); + void unload(); + void destroy(); + + void update(); + F32 updateXform(BOOL undamped); + + virtual void makeActive(); + /*virtual*/ void makeStatic(BOOL warning_enabled = TRUE); + + BOOL isActive() const { return isState(ACTIVE); } + BOOL isStatic() const { return !isActive(); } + BOOL isAnimating() const; + + virtual BOOL updateMove(); + virtual void movePartition(); + + void updateTexture(); + void updateMaterial(); + virtual void updateDistance(LLCamera& camera, bool force_update); + BOOL updateGeometry(); + void updateFaceSize(S32 idx); + + void updateSpecialHoverCursor(BOOL enabled); + + virtual void shiftPos(const LLVector4a &shift_vector); + + S32 getGeneration() const { return mGeneration; } + + BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; } + void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); } + + bool isVisible() const; + bool isRecentlyVisible() const; + + virtual void cleanupReferences(); + + void setGroup(LLViewerOctreeGroup* group); + void setRadius(const F32 radius); + F32 getRadius() const { return mRadius; } + F32 getVisibilityRadius() const; + + void updateUVMinMax(); // Updates the cache of sun space bounding box. + + const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; + virtual void updateSpatialExtents(); + virtual void updateBinRadius(); + + void setRenderType(S32 type) { mRenderType = type; } + BOOL isRenderType(S32 type) { return mRenderType == type; } + S32 getRenderType() { return mRenderType; } + + // Debugging methods + S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... + + LLSpatialPartition* getSpatialPartition(); + + void removeFromOctree(); + + void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } + LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } + + // Statics + static void incrementVisible(); + static void cleanupDeadDrawables(); protected: - ~LLDrawable() { destroy(); } - void moveUpdatePipeline(BOOL moved); - void updatePartition(); - BOOL updateMoveDamped(); - BOOL updateMoveUndamped(); - + ~LLDrawable() { destroy(); } + void moveUpdatePipeline(BOOL moved); + void updatePartition(); + BOOL updateMoveDamped(); + BOOL updateMoveUndamped(); + public: - friend class LLPipeline; - friend class LLDrawPool; - friend class LLSpatialBridge; - - typedef std::unordered_set > drawable_set_t; + friend class LLPipeline; + friend class LLDrawPool; + friend class LLSpatialBridge; + + typedef std::unordered_set > drawable_set_t; typedef std::set > ordered_drawable_set_t; - typedef std::vector > drawable_vector_t; - typedef std::list > drawable_list_t; - typedef std::queue > drawable_queue_t; - - struct CompareDistanceGreater - { - bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs) - { - return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last - } - }; - - struct CompareDistanceGreaterVisibleFirst - { - bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs) - { - if (lhs->isVisible() && !rhs->isVisible()) - { - return TRUE; //visible things come first - } - else if (!lhs->isVisible() && rhs->isVisible()) - { - return FALSE; //rhs is visible, comes first - } - - return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last - } - }; - - typedef enum e_drawable_flags - { - IN_REBUILD_Q = 0x00000001, - EARLY_MOVE = 0x00000004, - MOVE_UNDAMPED = 0x00000008, - ON_MOVE_LIST = 0x00000010, - UV = 0x00000020, - UNLIT = 0x00000040, - LIGHT = 0x00000080, - REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed - REBUILD_TCOORD = 0x00000200, //texture coordinates changed - REBUILD_COLOR = 0x00000400, //color changed - REBUILD_POSITION= 0x00000800, //vertex positions/normals changed - REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, - REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, - REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, - REBUILD_RIGGED = 0x00001000, - ON_SHIFT_LIST = 0x00002000, - ACTIVE = 0x00004000, - DEAD = 0x00008000, - INVISIBLE = 0x00010000, // stay invisible until flag is cleared - NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet - BUILT = 0x00040000, - FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - HAS_ALPHA = 0x00100000, - RIGGED = 0x00200000, //has a rigged face + typedef std::vector > drawable_vector_t; + typedef std::list > drawable_list_t; + typedef std::queue > drawable_queue_t; + + struct CompareDistanceGreater + { + bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs) + { + return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last + } + }; + + struct CompareDistanceGreaterVisibleFirst + { + bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs) + { + if (lhs->isVisible() && !rhs->isVisible()) + { + return TRUE; //visible things come first + } + else if (!lhs->isVisible() && rhs->isVisible()) + { + return FALSE; //rhs is visible, comes first + } + + return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last + } + }; + + typedef enum e_drawable_flags + { + IN_REBUILD_Q = 0x00000001, + EARLY_MOVE = 0x00000004, + MOVE_UNDAMPED = 0x00000008, + ON_MOVE_LIST = 0x00000010, + UV = 0x00000020, + UNLIT = 0x00000040, + LIGHT = 0x00000080, + REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed + REBUILD_TCOORD = 0x00000200, //texture coordinates changed + REBUILD_COLOR = 0x00000400, //color changed + REBUILD_POSITION= 0x00000800, //vertex positions/normals changed + REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, + REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, + REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, + REBUILD_RIGGED = 0x00001000, + ON_SHIFT_LIST = 0x00002000, + ACTIVE = 0x00004000, + DEAD = 0x00008000, + INVISIBLE = 0x00010000, // stay invisible until flag is cleared + NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet + BUILT = 0x00040000, + FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) + HAS_ALPHA = 0x00100000, + RIGGED = 0x00200000, //has a rigged face RIGGED_CHILD = 0x00400000, //has a child with a rigged face - PARTITION_MOVE = 0x00800000, - ANIMATED_CHILD = 0x01000000, - ACTIVE_CHILD = 0x02000000, - FOR_UNLOAD = 0x04000000, //should be unload from memory + PARTITION_MOVE = 0x00800000, + ANIMATED_CHILD = 0x01000000, + ACTIVE_CHILD = 0x02000000, + FOR_UNLOAD = 0x04000000, //should be unload from memory MIRROR = 0x08000000, // Used as a mirror, needs a hero probe position to be calculated. - } EDrawableFlags; + } EDrawableFlags; public: - LLXformMatrix mXform; + LLXformMatrix mXform; - // vis data - LLPointer mParent; + // vis data + LLPointer mParent; - F32 mDistanceWRTCamera; + F32 mDistanceWRTCamera; - static F32 sCurPixelAngle; //current pixels per radian + static F32 sCurPixelAngle; //current pixels per radian private: - U32 mState; - S32 mRenderType; - LLPointer mVObjp; - face_list_t mFaces; - LLPointer mSpatialBridge; - - F32 mRadius; - S32 mGeneration; - - LLVector3 mCurrentScale; - - static U32 sNumZombieDrawables; - static std::vector > sDeadList; + U32 mState; + S32 mRenderType; + LLPointer mVObjp; + face_list_t mFaces; + LLPointer mSpatialBridge; + + F32 mRadius; + S32 mGeneration; + + LLVector3 mCurrentScale; + + static U32 sNumZombieDrawables; + static std::vector > sDeadList; } LL_ALIGN_POSTFIX(16); inline LLFace* LLDrawable::getFace(const S32 i) const { - //switch these asserts to LL_ERRS() -- davep - //llassert((U32)i < mFaces.size()); - //llassert(mFaces[i]); - - if ((U32) i >= mFaces.size()) - { - LL_WARNS() << "Invalid face index." << LL_ENDL; - return NULL; - } - - if (!mFaces[i]) - { - LL_WARNS() << "Null face found." << LL_ENDL; - return NULL; - } - - return mFaces[i]; + //switch these asserts to LL_ERRS() -- davep + //llassert((U32)i < mFaces.size()); + //llassert(mFaces[i]); + + if ((U32) i >= mFaces.size()) + { + LL_WARNS() << "Invalid face index." << LL_ENDL; + return NULL; + } + + if (!mFaces[i]) + { + LL_WARNS() << "Null face found." << LL_ENDL; + return NULL; + } + + return mFaces[i]; } inline S32 LLDrawable::getNumFaces()const { - return (S32)mFaces.size(); + return (S32)mFaces.size(); } #endif diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 556760632a..2d44949c4a 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpool.cpp * @brief LLDrawPool class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -60,81 +60,81 @@ S32 LLDrawPool::sNumDrawPools = 0; //============================= LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0) { - LLDrawPool *poolp = NULL; - switch (type) - { - case POOL_SIMPLE: - poolp = new LLDrawPoolSimple(); - break; - case POOL_GRASS: - poolp = new LLDrawPoolGrass(); - break; - case POOL_ALPHA_MASK: - poolp = new LLDrawPoolAlphaMask(); - break; - case POOL_FULLBRIGHT_ALPHA_MASK: - poolp = new LLDrawPoolFullbrightAlphaMask(); - break; - case POOL_FULLBRIGHT: - poolp = new LLDrawPoolFullbright(); - break; - case POOL_GLOW: - poolp = new LLDrawPoolGlow(); - break; - case POOL_ALPHA_PRE_WATER: - poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER); - break; + LLDrawPool *poolp = NULL; + switch (type) + { + case POOL_SIMPLE: + poolp = new LLDrawPoolSimple(); + break; + case POOL_GRASS: + poolp = new LLDrawPoolGrass(); + break; + case POOL_ALPHA_MASK: + poolp = new LLDrawPoolAlphaMask(); + break; + case POOL_FULLBRIGHT_ALPHA_MASK: + poolp = new LLDrawPoolFullbrightAlphaMask(); + break; + case POOL_FULLBRIGHT: + poolp = new LLDrawPoolFullbright(); + break; + case POOL_GLOW: + poolp = new LLDrawPoolGlow(); + break; + case POOL_ALPHA_PRE_WATER: + poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER); + break; case POOL_ALPHA_POST_WATER: poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_POST_WATER); break; - case POOL_AVATAR: - case POOL_CONTROL_AV: - poolp = new LLDrawPoolAvatar(type); - break; - case POOL_TREE: - poolp = new LLDrawPoolTree(tex0); - break; - case POOL_TERRAIN: - poolp = new LLDrawPoolTerrain(tex0); - break; - case POOL_SKY: - poolp = new LLDrawPoolSky(); - break; - case POOL_VOIDWATER: - case POOL_WATER: - poolp = new LLDrawPoolWater(); - break; - case POOL_BUMP: - poolp = new LLDrawPoolBump(); - break; - case POOL_MATERIALS: - poolp = new LLDrawPoolMaterials(); - break; - case POOL_WL_SKY: - poolp = new LLDrawPoolWLSky(); - break; - case POOL_GLTF_PBR: - poolp = new LLDrawPoolGLTFPBR(); + case POOL_AVATAR: + case POOL_CONTROL_AV: + poolp = new LLDrawPoolAvatar(type); + break; + case POOL_TREE: + poolp = new LLDrawPoolTree(tex0); + break; + case POOL_TERRAIN: + poolp = new LLDrawPoolTerrain(tex0); + break; + case POOL_SKY: + poolp = new LLDrawPoolSky(); + break; + case POOL_VOIDWATER: + case POOL_WATER: + poolp = new LLDrawPoolWater(); + break; + case POOL_BUMP: + poolp = new LLDrawPoolBump(); + break; + case POOL_MATERIALS: + poolp = new LLDrawPoolMaterials(); + break; + case POOL_WL_SKY: + poolp = new LLDrawPoolWLSky(); + break; + case POOL_GLTF_PBR: + poolp = new LLDrawPoolGLTFPBR(); break; case POOL_GLTF_PBR_ALPHA_MASK: poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK); - break; - default: - LL_ERRS() << "Unknown draw pool type!" << LL_ENDL; - return NULL; - } + break; + default: + LL_ERRS() << "Unknown draw pool type!" << LL_ENDL; + return NULL; + } - llassert(poolp->mType == type); - return poolp; + llassert(poolp->mType == type); + return poolp; } LLDrawPool::LLDrawPool(const U32 type) { - mType = type; - sNumDrawPools++; - mId = sNumDrawPools; - mShaderLevel = 0; - mSkipRender = false; + mType = type; + sNumDrawPools++; + mId = sNumDrawPools; + mShaderLevel = 0; + mSkipRender = false; } LLDrawPool::~LLDrawPool() @@ -144,7 +144,7 @@ LLDrawPool::~LLDrawPool() LLViewerTexture *LLDrawPool::getDebugTexture() { - return NULL; + return NULL; } //virtual @@ -152,55 +152,55 @@ void LLDrawPool::beginRenderPass( S32 pass ) { } -//virtual -S32 LLDrawPool::getNumPasses() +//virtual +S32 LLDrawPool::getNumPasses() { - return 1; + return 1; } - -//virtual + +//virtual void LLDrawPool::beginDeferredPass(S32 pass) { } -//virtual +//virtual void LLDrawPool::endDeferredPass(S32 pass) { } -//virtual +//virtual S32 LLDrawPool::getNumDeferredPasses() { - return 0; + return 0; } -//virtual +//virtual void LLDrawPool::renderDeferred(S32 pass) { } -//virtual +//virtual void LLDrawPool::beginPostDeferredPass(S32 pass) { } -//virtual +//virtual void LLDrawPool::endPostDeferredPass(S32 pass) { } -//virtual +//virtual S32 LLDrawPool::getNumPostDeferredPasses() { - return 0; + return 0; } -//virtual +//virtual void LLDrawPool::renderPostDeferred(S32 pass) { @@ -209,29 +209,29 @@ void LLDrawPool::renderPostDeferred(S32 pass) //virtual void LLDrawPool::endRenderPass( S32 pass ) { - //make sure channel 0 is active channel - gGL.getTexUnit(0)->activate(); + //make sure channel 0 is active channel + gGL.getTexUnit(0)->activate(); } -//virtual +//virtual void LLDrawPool::beginShadowPass(S32 pass) { } -//virtual +//virtual void LLDrawPool::endShadowPass(S32 pass) { } -//virtual +//virtual S32 LLDrawPool::getNumShadowPasses() { - return 0; + return 0; } -//virtual +//virtual void LLDrawPool::renderShadow(S32 pass) { @@ -243,20 +243,20 @@ void LLDrawPool::renderShadow(S32 pass) LLFacePool::LLFacePool(const U32 type) : LLDrawPool(type) { - resetDrawOrders(); + resetDrawOrders(); } LLFacePool::~LLFacePool() { - destroy(); + destroy(); } void LLFacePool::destroy() { - if (!mReferences.empty()) - { - LL_INFOS() << mReferences.size() << " references left on deletion of draw pool!" << LL_ENDL; - } + if (!mReferences.empty()) + { + LL_INFOS() << mReferences.size() << " references left on deletion of draw pool!" << LL_ENDL; + } } void LLFacePool::dirtyTextures(const std::set& textures) @@ -265,59 +265,59 @@ void LLFacePool::dirtyTextures(const std::set& textures void LLFacePool::enqueue(LLFace* facep) { - mDrawFace.push_back(facep); + mDrawFace.push_back(facep); } // virtual BOOL LLFacePool::addFace(LLFace *facep) { - addFaceReference(facep); - return TRUE; + addFaceReference(facep); + return TRUE; } // virtual BOOL LLFacePool::removeFace(LLFace *facep) { - removeFaceReference(facep); + removeFaceReference(facep); - vector_replace_with_last(mDrawFace, facep); + vector_replace_with_last(mDrawFace, facep); - return TRUE; + return TRUE; } // Not absolutely sure if we should be resetting all of the chained pools as well - djs void LLFacePool::resetDrawOrders() { - mDrawFace.resize(0); + mDrawFace.resize(0); } LLViewerTexture *LLFacePool::getTexture() { - return NULL; + return NULL; } void LLFacePool::removeFaceReference(LLFace *facep) { - if (facep->getReferenceIndex() != -1) - { - if (facep->getReferenceIndex() != (S32)mReferences.size()) - { - LLFace *back = mReferences.back(); - mReferences[facep->getReferenceIndex()] = back; - back->setReferenceIndex(facep->getReferenceIndex()); - } - mReferences.pop_back(); - } - facep->setReferenceIndex(-1); + if (facep->getReferenceIndex() != -1) + { + if (facep->getReferenceIndex() != (S32)mReferences.size()) + { + LLFace *back = mReferences.back(); + mReferences[facep->getReferenceIndex()] = back; + back->setReferenceIndex(facep->getReferenceIndex()); + } + mReferences.pop_back(); + } + facep->setReferenceIndex(-1); } void LLFacePool::addFaceReference(LLFace *facep) { - if (-1 == facep->getReferenceIndex()) - { - facep->setReferenceIndex(mReferences.size()); - mReferences.push_back(facep); - } + if (-1 == facep->getReferenceIndex()) + { + facep->setReferenceIndex(mReferences.size()); + mReferences.push_back(facep); + } } void LLFacePool::pushFaceGeometry() @@ -330,47 +330,47 @@ void LLFacePool::pushFaceGeometry() BOOL LLFacePool::verify() const { - BOOL ok = TRUE; - - for (std::vector::const_iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - const LLFace* facep = *iter; - if (facep->getPool() != this) - { - LL_INFOS() << "Face in wrong pool!" << LL_ENDL; - facep->printDebugInfo(); - ok = FALSE; - } - else if (!facep->verify()) - { - ok = FALSE; - } - } - - return ok; + BOOL ok = TRUE; + + for (std::vector::const_iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + const LLFace* facep = *iter; + if (facep->getPool() != this) + { + LL_INFOS() << "Face in wrong pool!" << LL_ENDL; + facep->printDebugInfo(); + ok = FALSE; + } + else if (!facep->verify()) + { + ok = FALSE; + } + } + + return ok; } void LLFacePool::printDebugInfo() const { - LL_INFOS() << "Pool " << this << " Type: " << getType() << LL_ENDL; + LL_INFOS() << "Pool " << this << " Type: " << getType() << LL_ENDL; } BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE; void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color) { - gGL.diffuseColor4fv(color.mV); + gGL.diffuseColor4fv(color.mV); } void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color) { - glColor4ubv(color.mV); + glColor4ubv(color.mV); } void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) { - gGL.diffuseColor4f(r,g,b,a); + gGL.diffuseColor4f(r,g,b,a); } @@ -391,16 +391,16 @@ LLRenderPass::~LLRenderPass() void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) - { - LLDrawInfo *pparams = *k; - if (pparams) + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo *pparams = *k; + if (pparams) { pushBatch(*pparams, texture); - } - } + } + } } void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture) @@ -409,11 +409,11 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; - + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo* pparams = *k; - if (pparams) + if (pparams) { if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) { @@ -465,7 +465,7 @@ void LLRenderPass::pushUntexturedBatches(U32 type) void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - + if (texture) { LLVOAvatar* lastAvatar = nullptr; @@ -521,13 +521,13 @@ void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures) LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); auto* end = gPipeline.endRenderMap(type); - for (LLCullResult::drawinfo_iterator i = begin; i != end; ) - { + for (LLCullResult::drawinfo_iterator i = begin; i != end; ) + { LLDrawInfo* pparams = *i; LLCullResult::increment_iterator(i, end); - LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); - pushBatch(*pparams, texture, batch_textures); - } + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); + pushBatch(*pparams, texture, batch_textures); + } } void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures) @@ -567,22 +567,22 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) { - applyModelMatrix(params.mModelMatrix); + applyModelMatrix(params.mModelMatrix); } void LLRenderPass::applyModelMatrix(const LLMatrix4* model_matrix) { - if (model_matrix != gGLLastMatrix) - { - gGLLastMatrix = model_matrix; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); - if (model_matrix) - { - gGL.multMatrix((GLfloat*) model_matrix->mMatrix); - } - gPipeline.mMatrixOpCount++; - } + if (model_matrix != gGLLastMatrix) + { + gGLLastMatrix = model_matrix; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } } void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures) @@ -595,51 +595,51 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textur return; } - applyModelMatrix(params); - - bool tex_setup = false; - - { - if (batch_textures && params.mTextureList.size() > 1) - { - for (U32 i = 0; i < params.mTextureList.size(); ++i) - { - if (params.mTextureList[i].notNull()) - { - gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); - } - } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(params.mTexture); - if (params.mTextureMatrix) - { - tex_setup = true; - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - } - else - { - gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); - } - } - } - + applyModelMatrix(params); + + bool tex_setup = false; + + { + if (batch_textures && params.mTextureList.size() > 1) + { + for (U32 i = 0; i < params.mTextureList.size(); ++i) + { + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); + } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTexture.notNull()) + { + gGL.getTexUnit(0)->bindFast(params.mTexture); + if (params.mTextureMatrix) + { + tex_setup = true; + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + else + { + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); + } + } + } + params.mVertexBuffer->setBuffer(); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); - if (tex_setup) - { + if (tex_setup) + { gGL.matrixMode(LLRender::MM_TEXTURE0); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } } void LLRenderPass::pushUntexturedBatch(LLDrawInfo& params) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index c69f386c6d..789d8d45c9 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpool.h * @brief LLDrawPool class definition * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,87 +43,87 @@ class LLMeshSkinInfo; class LLDrawPool { public: - static S32 sNumDrawPools; + static S32 sNumDrawPools; - enum - { - // Correspond to LLPipeline render type + enum + { + // Correspond to LLPipeline render type // Also controls render order, so passes that don't use alpha masking/blending should come before // other passes to preserve hierarchical Z for occlusion queries. Occlusion queries happen just // before grass, so grass should be the first alpha masked pool. Other ordering should be done // based on fill rate and likelihood to occlude future passes (faster, large occluders first). - // + // POOL_SKY = 1, POOL_WL_SKY, - POOL_SIMPLE, - POOL_FULLBRIGHT, - POOL_BUMP, + POOL_SIMPLE, + POOL_FULLBRIGHT, + POOL_BUMP, POOL_MATERIALS, POOL_GLTF_PBR, - POOL_TERRAIN, + POOL_TERRAIN, POOL_GRASS, POOL_GLTF_PBR_ALPHA_MASK, - POOL_TREE, - POOL_ALPHA_MASK, - POOL_FULLBRIGHT_ALPHA_MASK, - POOL_AVATAR, - POOL_CONTROL_AV, // Animesh - POOL_GLOW, - POOL_ALPHA_PRE_WATER, + POOL_TREE, + POOL_ALPHA_MASK, + POOL_FULLBRIGHT_ALPHA_MASK, + POOL_AVATAR, + POOL_CONTROL_AV, // Animesh + POOL_GLOW, + POOL_ALPHA_PRE_WATER, POOL_VOIDWATER, POOL_WATER, POOL_ALPHA_POST_WATER, POOL_ALPHA, // note there is no actual "POOL_ALPHA" but pre-water and post-water pools consume POOL_ALPHA faces - NUM_POOL_TYPES, - }; - - LLDrawPool(const U32 type); - virtual ~LLDrawPool(); - - virtual BOOL isDead() = 0; - - S32 getId() const { return mId; } - U32 getType() const { return mType; } - - BOOL getSkipRenderFlag() const { return mSkipRender;} - void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; } - - virtual LLViewerTexture *getDebugTexture(); - virtual void beginRenderPass( S32 pass ); - virtual void endRenderPass( S32 pass ); - virtual S32 getNumPasses(); - - virtual void beginDeferredPass(S32 pass); - virtual void endDeferredPass(S32 pass); - virtual S32 getNumDeferredPasses(); - virtual void renderDeferred(S32 pass = 0); - - virtual void beginPostDeferredPass(S32 pass); - virtual void endPostDeferredPass(S32 pass); - virtual S32 getNumPostDeferredPasses(); - virtual void renderPostDeferred(S32 pass = 0); - - virtual void beginShadowPass(S32 pass); - virtual void endShadowPass(S32 pass); - virtual S32 getNumShadowPasses(); - virtual void renderShadow(S32 pass = 0); + NUM_POOL_TYPES, + }; + + LLDrawPool(const U32 type); + virtual ~LLDrawPool(); + + virtual BOOL isDead() = 0; + + S32 getId() const { return mId; } + U32 getType() const { return mType; } + + BOOL getSkipRenderFlag() const { return mSkipRender;} + void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; } + + virtual LLViewerTexture *getDebugTexture(); + virtual void beginRenderPass( S32 pass ); + virtual void endRenderPass( S32 pass ); + virtual S32 getNumPasses(); + + virtual void beginDeferredPass(S32 pass); + virtual void endDeferredPass(S32 pass); + virtual S32 getNumDeferredPasses(); + virtual void renderDeferred(S32 pass = 0); + + virtual void beginPostDeferredPass(S32 pass); + virtual void endPostDeferredPass(S32 pass); + virtual S32 getNumPostDeferredPasses(); + virtual void renderPostDeferred(S32 pass = 0); + + virtual void beginShadowPass(S32 pass); + virtual void endShadowPass(S32 pass); + virtual S32 getNumShadowPasses(); + virtual void renderShadow(S32 pass = 0); virtual void render(S32 pass = 0) {}; virtual void prerender() {}; virtual U32 getVertexDataMask() { return 0; } // DEPRECATED -- draw pool doesn't actually determine vertex data mask any more - virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! - virtual S32 getShaderLevel() const { return mShaderLevel; } - - static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); - virtual LLViewerTexture* getTexture() = 0; - virtual BOOL isFacePool() { return FALSE; } - virtual void resetDrawOrders() = 0; + virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! + virtual S32 getShaderLevel() const { return mShaderLevel; } + + static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); + virtual LLViewerTexture* getTexture() = 0; + virtual BOOL isFacePool() { return FALSE; } + virtual void resetDrawOrders() = 0; virtual void pushFaceGeometry() {} - S32 mShaderLevel; - S32 mId; - U32 mType; // Type of draw pool - BOOL mSkipRender; + S32 mShaderLevel; + S32 mId; + U32 mType; // Type of draw pool + BOOL mSkipRender; }; class LLRenderPass : public LLDrawPool @@ -132,77 +132,77 @@ public: // list of possible LLRenderPass types to assign a render batch to // NOTE: "rigged" variant MUST be non-rigged variant + 1 // see LLVolumeGeometryManager::registerFace() - enum - { - PASS_SIMPLE = NUM_POOL_TYPES, + enum + { + PASS_SIMPLE = NUM_POOL_TYPES, PASS_SIMPLE_RIGGED, - PASS_GRASS, - PASS_FULLBRIGHT, + PASS_GRASS, + PASS_FULLBRIGHT, PASS_FULLBRIGHT_RIGGED, - PASS_INVISIBLE, + PASS_INVISIBLE, PASS_INVISIBLE_RIGGED, - PASS_INVISI_SHINY, + PASS_INVISI_SHINY, PASS_INVISI_SHINY_RIGGED, - PASS_FULLBRIGHT_SHINY, + PASS_FULLBRIGHT_SHINY, PASS_FULLBRIGHT_SHINY_RIGGED, - PASS_SHINY, + PASS_SHINY, PASS_SHINY_RIGGED, - PASS_BUMP, + PASS_BUMP, PASS_BUMP_RIGGED, - PASS_POST_BUMP, + PASS_POST_BUMP, PASS_POST_BUMP_RIGGED, - PASS_MATERIAL, + PASS_MATERIAL, PASS_MATERIAL_RIGGED, - PASS_MATERIAL_ALPHA, + PASS_MATERIAL_ALPHA, PASS_MATERIAL_ALPHA_RIGGED, - PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask + PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask PASS_MATERIAL_ALPHA_MASK_RIGGED, - PASS_MATERIAL_ALPHA_EMISSIVE, + PASS_MATERIAL_ALPHA_EMISSIVE, PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, - PASS_SPECMAP, + PASS_SPECMAP, PASS_SPECMAP_RIGGED, - PASS_SPECMAP_BLEND, + PASS_SPECMAP_BLEND, PASS_SPECMAP_BLEND_RIGGED, - PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map) + PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map) PASS_SPECMAP_MASK_RIGGED, - PASS_SPECMAP_EMISSIVE, + PASS_SPECMAP_EMISSIVE, PASS_SPECMAP_EMISSIVE_RIGGED, - PASS_NORMMAP, + PASS_NORMMAP, PASS_NORMMAP_RIGGED, - PASS_NORMMAP_BLEND, + PASS_NORMMAP_BLEND, PASS_NORMMAP_BLEND_RIGGED, - PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map + PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map PASS_NORMMAP_MASK_RIGGED, - PASS_NORMMAP_EMISSIVE, + PASS_NORMMAP_EMISSIVE, PASS_NORMMAP_EMISSIVE_RIGGED, - PASS_NORMSPEC, + PASS_NORMSPEC, PASS_NORMSPEC_RIGGED, - PASS_NORMSPEC_BLEND, + PASS_NORMSPEC_BLEND, PASS_NORMSPEC_BLEND_RIGGED, - PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map + PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map PASS_NORMSPEC_MASK_RIGGED, - PASS_NORMSPEC_EMISSIVE, + PASS_NORMSPEC_EMISSIVE, PASS_NORMSPEC_EMISSIVE_RIGGED, - PASS_GLOW, + PASS_GLOW, PASS_GLOW_RIGGED, PASS_GLTF_GLOW, PASS_GLTF_GLOW_RIGGED, - PASS_ALPHA, + PASS_ALPHA, PASS_ALPHA_RIGGED, - PASS_ALPHA_MASK, + PASS_ALPHA_MASK, PASS_ALPHA_MASK_RIGGED, - PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright + PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, - PASS_ALPHA_INVISIBLE, + PASS_ALPHA_INVISIBLE, PASS_ALPHA_INVISIBLE_RIGGED, PASS_GLTF_PBR, PASS_GLTF_PBR_RIGGED, PASS_GLTF_PBR_ALPHA_MASK, PASS_GLTF_PBR_ALPHA_MASK_RIGGED, - NUM_RENDER_TYPES, - }; + NUM_RENDER_TYPES, + }; - #ifdef LL_PROFILER_ENABLE_RENDER_DOC + #ifdef LL_PROFILER_ENABLE_RENDER_DOC static inline const char* lookupPassName(U32 pass) { switch (pass) @@ -336,22 +336,22 @@ public: default: return "Unknown pass"; } - } - #else + } + #else static inline const char* lookupPass(U32 pass) { return ""; } - #endif + #endif - LLRenderPass(const U32 type); - virtual ~LLRenderPass(); - /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; } - LLViewerTexture* getTexture() { return NULL; } - BOOL isDead() { return FALSE; } - void resetDrawOrders() { } + LLRenderPass(const U32 type); + virtual ~LLRenderPass(); + /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; } + LLViewerTexture* getTexture() { return NULL; } + BOOL isDead() { return FALSE; } + void resetDrawOrders() { } - static void applyModelMatrix(const LLDrawInfo& params); + static void applyModelMatrix(const LLDrawInfo& params); // For rendering that doesn't use LLDrawInfo for some reason - static void applyModelMatrix(const LLMatrix4* model_matrix); - void pushBatches(U32 type, bool texture = true, bool batch_textures = false); + static void applyModelMatrix(const LLMatrix4* model_matrix); + void pushBatches(U32 type, bool texture = true, bool batch_textures = false); void pushUntexturedBatches(U32 type); void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false); @@ -379,104 +379,104 @@ public: static void pushUntexturedGLTFBatch(LLDrawInfo& params); static void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); - void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false); + void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false); void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false); - void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); + void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); void pushUntexturedBatch(LLDrawInfo& params); - void pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); + void pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); static bool uploadMatrixPalette(LLDrawInfo& params); static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo); - virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true); + virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true); virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture = true); }; class LLFacePool : public LLDrawPool { public: - typedef std::vector face_array_t; - - enum - { - SHADER_LEVEL_SCATTERING = 2 - }; + typedef std::vector face_array_t; + + enum + { + SHADER_LEVEL_SCATTERING = 2 + }; public: - LLFacePool(const U32 type); - virtual ~LLFacePool(); - - BOOL isDead() { return mReferences.empty(); } - - virtual LLViewerTexture *getTexture(); - virtual void dirtyTextures(const std::set& textures); + LLFacePool(const U32 type); + virtual ~LLFacePool(); + + BOOL isDead() { return mReferences.empty(); } + + virtual LLViewerTexture *getTexture(); + virtual void dirtyTextures(const std::set& textures); + + virtual void enqueue(LLFace *face); + virtual BOOL addFace(LLFace *face); + virtual BOOL removeFace(LLFace *face); - virtual void enqueue(LLFace *face); - virtual BOOL addFace(LLFace *face); - virtual BOOL removeFace(LLFace *face); + virtual BOOL verify() const; // Verify that all data in the draw pool is correct! - virtual BOOL verify() const; // Verify that all data in the draw pool is correct! - - virtual void resetDrawOrders(); - void resetAll(); + virtual void resetDrawOrders(); + void resetAll(); - void destroy(); + void destroy(); - void buildEdges(); + void buildEdges(); - void addFaceReference(LLFace *facep); - void removeFaceReference(LLFace *facep); + void addFaceReference(LLFace *facep); + void removeFaceReference(LLFace *facep); - void printDebugInfo() const; - - BOOL isFacePool() { return TRUE; } + void printDebugInfo() const; + + BOOL isFacePool() { return TRUE; } // call drawIndexed on every draw face void pushFaceGeometry(); - friend class LLFace; - friend class LLPipeline; + friend class LLFace; + friend class LLPipeline; public: - face_array_t mDrawFace; - face_array_t mMoveFace; - face_array_t mReferences; + face_array_t mDrawFace; + face_array_t mMoveFace; + face_array_t mReferences; public: - class LLOverrideFaceColor - { - public: - LLOverrideFaceColor(LLDrawPool* pool) - : mOverride(sOverrideFaceColor), mPool(pool) - { - sOverrideFaceColor = TRUE; - } - LLOverrideFaceColor(LLDrawPool* pool, const LLColor4& color) - : mOverride(sOverrideFaceColor), mPool(pool) - { - sOverrideFaceColor = TRUE; - setColor(color); - } - LLOverrideFaceColor(LLDrawPool* pool, const LLColor4U& color) - : mOverride(sOverrideFaceColor), mPool(pool) - { - sOverrideFaceColor = TRUE; - setColor(color); - } - LLOverrideFaceColor(LLDrawPool* pool, F32 r, F32 g, F32 b, F32 a) - : mOverride(sOverrideFaceColor), mPool(pool) - { - sOverrideFaceColor = TRUE; - setColor(r, g, b, a); - } - ~LLOverrideFaceColor() - { - sOverrideFaceColor = mOverride; - } - void setColor(const LLColor4& color); - void setColor(const LLColor4U& color); - void setColor(F32 r, F32 g, F32 b, F32 a); - BOOL mOverride; - LLDrawPool* mPool; - static BOOL sOverrideFaceColor; - }; + class LLOverrideFaceColor + { + public: + LLOverrideFaceColor(LLDrawPool* pool) + : mOverride(sOverrideFaceColor), mPool(pool) + { + sOverrideFaceColor = TRUE; + } + LLOverrideFaceColor(LLDrawPool* pool, const LLColor4& color) + : mOverride(sOverrideFaceColor), mPool(pool) + { + sOverrideFaceColor = TRUE; + setColor(color); + } + LLOverrideFaceColor(LLDrawPool* pool, const LLColor4U& color) + : mOverride(sOverrideFaceColor), mPool(pool) + { + sOverrideFaceColor = TRUE; + setColor(color); + } + LLOverrideFaceColor(LLDrawPool* pool, F32 r, F32 g, F32 b, F32 a) + : mOverride(sOverrideFaceColor), mPool(pool) + { + sOverrideFaceColor = TRUE; + setColor(r, g, b, a); + } + ~LLOverrideFaceColor() + { + sOverrideFaceColor = mOverride; + } + void setColor(const LLColor4& color); + void setColor(const LLColor4U& color); + void setColor(F32 r, F32 g, F32 b, F32 a); + BOOL mOverride; + LLDrawPool* mPool; + static BOOL sOverrideFaceColor; + }; }; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index fd27010877..60cfe9440d 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolalpha.cpp * @brief LLDrawPoolAlpha class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,7 +39,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewertexturelist.h" // For debugging +#include "llviewertexturelist.h" // For debugging #include "llviewerobjectlist.h" // For debugging #include "llviewerwindow.h" #include "pipeline.h" @@ -66,11 +66,11 @@ static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255 static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : - LLRenderPass(type), target_shader(NULL), - mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), - mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF) + LLRenderPass(type), target_shader(NULL), + mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), + mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF) { - + } LLDrawPoolAlpha::~LLDrawPoolAlpha() @@ -80,15 +80,15 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha() void LLDrawPoolAlpha::prerender() { - mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); // TODO: is this even necessay? These are probably set to never discard LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f); LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f); } -S32 LLDrawPoolAlpha::getNumPostDeferredPasses() -{ +S32 LLDrawPoolAlpha::getNumPostDeferredPasses() +{ return 1; } @@ -108,7 +108,7 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d { shader->mCanBindFast = false; } - + shader->bind(); shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); @@ -139,15 +139,15 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d //also prepare rigged variant if (shader->mRiggedVariant && shader->mRiggedVariant != shader) - { + { prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign); } } extern BOOL gCubeSnapshot; -void LLDrawPoolAlpha::renderPostDeferred(S32 pass) -{ +void LLDrawPoolAlpha::renderPostDeferred(S32 pass) +{ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; if (LLPipeline::isWaterClip() && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER) @@ -177,13 +177,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) prepare_alpha_shader(pbr_emissive_shader, true, false, water_sign); - fullbright_shader = + fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram : (LLPipeline::sRenderingHUDs) ? &gHUDFullbrightAlphaMaskAlphaProgram : &gDeferredFullbrightAlphaMaskAlphaProgram; prepare_alpha_shader(fullbright_shader, true, true, water_sign); - simple_shader = + simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : (LLPipeline::sRenderingHUDs) ? &gHUDAlphaProgram : &gDeferredAlphaProgram; @@ -196,8 +196,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) prepare_alpha_shader(&materialShader[i], false, true, water_sign); } - pbr_shader = - (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram : + pbr_shader = + (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram : &gDeferredPBRAlphaProgram; prepare_alpha_shader(pbr_shader, false, true, water_sign); @@ -217,7 +217,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) // final pass, render to depth for depth of field effects if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot && !LLPipeline::sRenderingHUDs && getType() == LLDrawPool::POOL_ALPHA_POST_WATER) - { + { //update depth buffer sampler simple_shader = fullbright_shader = &gDeferredFullbrightAlphaMaskProgram; @@ -229,7 +229,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) // If the face is more than 90% transparent, then don't update the Depth buffer for Dof // We don't want the nearly invisible objects to cause of DoF effects - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, true); // <--- discard mostly transparent faces gGL.setColorMask(true, false); @@ -287,8 +287,8 @@ void LLDrawPoolAlpha::forwardRender(bool rigged) void LLDrawPoolAlpha::renderDebugAlpha() { - if (sShowDebugAlpha) - { + if (sShowDebugAlpha) + { gHighlightProgram.bind(); gGL.diffuseColor4f(1, 0, 0, 1); gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::getSmokeImage()); @@ -296,19 +296,19 @@ void LLDrawPoolAlpha::renderDebugAlpha() renderAlphaHighlight(); - pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK); - pushUntexturedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE); + pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK); + pushUntexturedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE); - // Material alpha mask - gGL.diffuseColor4f(0, 0, 1, 1); - pushUntexturedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK); - pushUntexturedBatches(LLRenderPass::PASS_NORMMAP_MASK); - pushUntexturedBatches(LLRenderPass::PASS_SPECMAP_MASK); - pushUntexturedBatches(LLRenderPass::PASS_NORMSPEC_MASK); - pushUntexturedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + // Material alpha mask + gGL.diffuseColor4f(0, 0, 1, 1); + pushUntexturedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK); + pushUntexturedBatches(LLRenderPass::PASS_NORMMAP_MASK); + pushUntexturedBatches(LLRenderPass::PASS_SPECMAP_MASK); + pushUntexturedBatches(LLRenderPass::PASS_NORMSPEC_MASK); + pushUntexturedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); pushUntexturedBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK); - gGL.diffuseColor4f(0, 1, 0, 1); + gGL.diffuseColor4f(0, 1, 0, 1); pushUntexturedBatches(LLRenderPass::PASS_INVISIBLE); gHighlightProgram.mRiggedVariant->bind(); @@ -329,7 +329,7 @@ void LLDrawPoolAlpha::renderDebugAlpha() gGL.diffuseColor4f(0, 1, 0, 1); pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, false); LLGLSLShader::sCurBoundShaderPtr->unbind(); - } + } } void LLDrawPoolAlpha::renderAlphaHighlight() @@ -348,7 +348,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight() if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { @@ -403,7 +403,7 @@ inline void Draw(LLDrawInfo* draw, U32 mask) { draw->mVertexBuffer->setBuffer(); LLRenderPass::applyModelMatrix(*draw); - draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); + draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) @@ -485,19 +485,19 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup) { if (tex_setup) - { - gGL.getTexUnit(0)->activate(); + { + gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } } void LLDrawPoolAlpha::drawEmissive(LLDrawInfo* draw) { LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); draw->mVertexBuffer->setBuffer(); - draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); + draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } @@ -561,7 +561,7 @@ void LLDrawPoolAlpha::renderRiggedPbrEmissives(std::vector& emissiv { LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter pbr_emissive_shader->bind(true); - + LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; @@ -588,7 +588,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; BOOL initialized_lighting = FALSE; - BOOL light_enabled = TRUE; + BOOL light_enabled = TRUE; LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; @@ -607,7 +607,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) begin = gPipeline.beginAlphaGroups(); end = gPipeline.endAlphaGroups(); } - + LLEnvironment& env = LLEnvironment::instance(); F32 water_height = env.getWaterHeight(); @@ -619,15 +619,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) for (LLCullResult::sg_iterator i = begin; i != end; ++i) - { + { LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("renderAlpha - group"); - LLSpatialGroup* group = *i; - llassert(group); - llassert(group->getSpatialPartition()); + LLSpatialGroup* group = *i; + llassert(group); + llassert(group->getSpatialPartition()); - if (group->getSpatialPartition()->mRenderByGroup && - !group->isDead()) - { + if (group->getSpatialPartition()->mRenderByGroup && + !group->isDead()) + { LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents(); @@ -660,17 +660,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) pbr_emissives.resize(0); pbr_rigged_emissives.resize(0); - bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE - || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; + bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE + || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; - bool disable_cull = is_particle_or_hud_particle; - LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); + bool disable_cull = is_particle_or_hud_particle; + LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); - LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; + LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) - { - LLDrawInfo& params = **k; + { + LLDrawInfo& params = **k; if ((bool)params.mAvatar != rigged) { continue; @@ -681,7 +681,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) LLRenderPass::applyModelMatrix(params); LLMaterial* mat = NULL; - LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; + LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; LLGLDisable cull_face(gltf_mat && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0); @@ -803,8 +803,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) bool tex_setup = TexSetup(¶ms, (mat != nullptr)); - { - gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); + { + gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); bool reset_minimum_alpha = false; if (!LLPipeline::sImpostorRender && @@ -823,12 +823,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) { current_shader->setMinimumAlpha(MINIMUM_ALPHA); } - } + } - // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha. - if (getType() != LLDrawPool::POOL_ALPHA_PRE_WATER && - params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) - { + // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha. + if (getType() != LLDrawPool::POOL_ALPHA_PRE_WATER && + params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) + { if (params.mAvatar != nullptr) { if (params.mGLTFMaterial.isNull()) @@ -851,16 +851,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) pbr_emissives.push_back(¶ms); } } - } - - if (tex_setup) - { - gGL.getTexUnit(0)->activate(); + } + + if (tex_setup) + { + gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - } + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + } // render emissive faces into alpha channel for bloom effects if (!depth_only) @@ -909,17 +909,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) lastShader->bind(); } } - } - } + } + } - gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - if (!light_enabled) - { - gPipeline.enableLightsDynamic(); - } + if (!light_enabled) + { + gPipeline.enableLightsDynamic(); + } } bool LLDrawPoolAlpha::uploadMatrixPalette(const LLDrawInfo& params) diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 24df11c158..eec17149e7 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolbump.cpp * @brief LLDrawPoolBump class implementation * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,7 +54,7 @@ //#include "../tools/imdebug/imdebug.h" // static -LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT]; +LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT]; LL::WorkQueue::weak_t LLBumpImageList::sMainQueue; LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue; LLRenderTarget LLBumpImageList::sRenderTarget; @@ -84,13 +84,13 @@ static BOOL shiny = FALSE; #define LL_BUMPLIST_MULTITHREADED 1 -// static +// static void LLStandardBumpmap::shutdown() { - LLStandardBumpmap::destroyGL(); + LLStandardBumpmap::destroyGL(); } -// static +// static void LLStandardBumpmap::restoreGL() { addstandard(); @@ -99,12 +99,12 @@ void LLStandardBumpmap::restoreGL() // static void LLStandardBumpmap::addstandard() { - if(!gTextureList.isInitialized()) - { - //Note: loading pre-configuration sometimes triggers this call. - //But it is safe to return here because bump images will be reloaded during initialization later. - return ; - } + if(!gTextureList.isInitialized()) + { + //Note: loading pre-configuration sometimes triggers this call. + //But it is safe to return here because bump images will be reloaded during initialization later. + return ; + } if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED) { @@ -112,99 +112,99 @@ void LLStandardBumpmap::addstandard() return; } - // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. - //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); - clear(); - LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS - - std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); - LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/ - if( !file ) - { - LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL; - return; - } - - S32 file_version = 0; - - S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version ); - if( fields_read != 1 ) - { - LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL; - return; - } - - if( file_version > STD_BUMP_LATEST_FILE_VERSION ) - { - LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL; - return; - } - - while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) - { - // *NOTE: This buffer size is hard coded into scanf() below. - char label[2048] = ""; /* Flawfinder: ignore */ - char bump_image_id[2048] = ""; /* Flawfinder: ignore */ - fields_read = fscanf( /* Flawfinder: ignore */ - file, "\n%2047s %2047s", label, bump_image_id); - if( EOF == fields_read ) - { - break; - } - if( fields_read != 2 ) - { - LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL; - return; - } - -// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ; - LLStandardBumpmap::sStandardBumpmapCount++; - } - - fclose( file ); + // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. + //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); + clear(); + LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS + + std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); + LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/ + if( !file ) + { + LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL; + return; + } + + S32 file_version = 0; + + S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version ); + if( fields_read != 1 ) + { + LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL; + return; + } + + if( file_version > STD_BUMP_LATEST_FILE_VERSION ) + { + LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL; + return; + } + + while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) + { + // *NOTE: This buffer size is hard coded into scanf() below. + char label[2048] = ""; /* Flawfinder: ignore */ + char bump_image_id[2048] = ""; /* Flawfinder: ignore */ + fields_read = fscanf( /* Flawfinder: ignore */ + file, "\n%2047s %2047s", label, bump_image_id); + if( EOF == fields_read ) + { + break; + } + if( fields_read != 2 ) + { + LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL; + return; + } + +// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ; + LLStandardBumpmap::sStandardBumpmapCount++; + } + + fclose( file ); } // static void LLStandardBumpmap::clear() { - LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL; - for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ ) - { - gStandardBumpmapList[i].mLabel.assign(""); - gStandardBumpmapList[i].mImage = NULL; - } - sStandardBumpmapCount = 0; + LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL; + for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ ) + { + gStandardBumpmapList[i].mLabel.assign(""); + gStandardBumpmapList[i].mImage = NULL; + } + sStandardBumpmapCount = 0; } // static void LLStandardBumpmap::destroyGL() { - clear(); + clear(); } //////////////////////////////////////////////////////////////// -LLDrawPoolBump::LLDrawPoolBump() +LLDrawPoolBump::LLDrawPoolBump() : LLRenderPass(LLDrawPool::POOL_BUMP) { - shiny = FALSE; + shiny = FALSE; } void LLDrawPoolBump::prerender() { - mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } // static @@ -217,88 +217,88 @@ S32 LLDrawPoolBump::numBumpPasses() //static void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled ) - { - if (shader ) - { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); - LLVector3 vec = LLVector3(gShinyOrigin) * mat; - LLVector4 vec4(vec, gShinyOrigin.mV[3]); - shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); - if (shader_level > 1) - { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled ) + { + if (shader ) + { + LLMatrix4 mat; + mat.initRows(LLVector4(gGLModelView+0), + LLVector4(gGLModelView+4), + LLVector4(gGLModelView+8), + LLVector4(gGLModelView+12)); + LLVector3 vec = LLVector3(gShinyOrigin) * mat; + LLVector4 vec4(vec, gShinyOrigin.mV[3]); + shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + if (shader_level > 1) + { cube_map->setMatrix(1); - // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for - // the cube map in the one pass shiny shaders - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - cube_map->enableTexture(cube_channel); - diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - else - { + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + cube_map->enableTexture(cube_channel); + diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + else + { cube_map->setMatrix(0); - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - diffuse_channel = -1; - cube_map->enable(cube_channel); - } - gGL.getTexUnit(cube_channel)->bind(cube_map); - gGL.getTexUnit(0)->activate(); - } - else - { - cube_channel = 0; - diffuse_channel = -1; - gGL.getTexUnit(0)->disable(); - cube_map->enable(0); + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + diffuse_channel = -1; + cube_map->enable(cube_channel); + } + gGL.getTexUnit(cube_channel)->bind(cube_map); + gGL.getTexUnit(0)->activate(); + } + else + { + cube_channel = 0; + diffuse_channel = -1; + gGL.getTexUnit(0)->disable(); + cube_map->enable(0); cube_map->setMatrix(0); - gGL.getTexUnit(0)->bind(cube_map); - } - } + gGL.getTexUnit(0)->bind(cube_map); + } + } } //static void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled) - { - if (shader_level > 1) - { - shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) - { - if (diffuse_channel != 0) - { - shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - } - } + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled) + { + if (shader_level > 1) + { + shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) + { + if (diffuse_channel != 0) + { + shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + } + } // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0 // MAINT-755 - cube_map->disable(); + cube_map->disable(); cube_map->restoreMatrix(); - } + } } void LLDrawPoolBump::beginFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - - sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; - // Second pass: environment map - shader = &gDeferredFullbrightShinyProgram; + sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; + + // Second pass: environment map + shader = &gDeferredFullbrightShinyProgram; if (LLPipeline::sRenderingHUDs) { shader = &gHUDFullbrightShinyProgram; } - + if (mRigged) { llassert(shader->mRiggedVariant); @@ -312,32 +312,32 @@ void LLDrawPoolBump::beginFullbrightShiny() gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap); } - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map && !LLPipeline::sReflectionProbesEnabled) { - // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for - // the cube map in the one pass shiny shaders - gGL.getTexUnit(1)->disable(); - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - cube_map->enableTexture(cube_channel); - diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - - gGL.getTexUnit(cube_channel)->bind(cube_map); - gGL.getTexUnit(0)->activate(); + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + gGL.getTexUnit(1)->disable(); + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + cube_map->enableTexture(cube_channel); + diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + + gGL.getTexUnit(cube_channel)->bind(cube_map); + gGL.getTexUnit(0)->activate(); } - { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); - shader->bind(); - - LLVector3 vec = LLVector3(gShinyOrigin) * mat; - LLVector4 vec4(vec, gShinyOrigin.mV[3]); - shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + { + LLMatrix4 mat; + mat.initRows(LLVector4(gGLModelView+0), + LLVector4(gGLModelView+4), + LLVector4(gGLModelView+8), + LLVector4(gGLModelView+12)); + shader->bind(); + + LLVector3 vec = LLVector3(gShinyOrigin) * mat; + LLVector4 vec4(vec, gShinyOrigin.mV[3]); + shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); if (LLPipeline::sReflectionProbesEnabled) { @@ -347,25 +347,25 @@ void LLDrawPoolBump::beginFullbrightShiny() { gPipeline.setEnvMat(*shader); } - } + } - if (mShaderLevel > 1) - { //indexed texture rendering, channel 0 is always diffuse - diffuse_channel = 0; - } + if (mShaderLevel > 1) + { //indexed texture rendering, channel 0 is always diffuse + diffuse_channel = 0; + } - shiny = TRUE; + shiny = TRUE; } void LLDrawPoolBump::renderFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - { - LLGLEnable blend_enable(GL_BLEND); + { + LLGLEnable blend_enable(GL_BLEND); - if (mShaderLevel > 1) - { + if (mShaderLevel > 1) + { if (mRigged) { LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, true, true); @@ -374,9 +374,9 @@ void LLDrawPoolBump::renderFullbrightShiny() { LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, true, true); } - } - else - { + } + else + { if (mRigged) { LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED); @@ -385,125 +385,125 @@ void LLDrawPoolBump::renderFullbrightShiny() { LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY); } - } - } + } + } } void LLDrawPoolBump::endFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled ) - { - cube_map->disable(); + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled ) + { + cube_map->disable(); if (shader->mFeatures.hasReflectionProbes) { gPipeline.unbindReflectionProbes(*shader); } - shader->unbind(); - } - - diffuse_channel = -1; - cube_channel = 0; - shiny = FALSE; + shader->unbind(); + } + + diffuse_channel = -1; + cube_channel = 0; + shiny = FALSE; } void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true) -{ - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; - - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) - { - LLDrawInfo& params = **k; - - applyModelMatrix(params); - - params.mVertexBuffer->setBuffer(); - params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); - } +{ + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; + + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo& params = **k; + + applyModelMatrix(params); + + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + } } // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - U8 bump_code = params.mBump; + U8 bump_code = params.mBump; - return bindBumpMap(bump_code, params.mTexture, channel); + return bindBumpMap(bump_code, params.mTexture, channel); } //static BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) { - const LLTextureEntry* te = face->getTextureEntry(); - if (te) - { - U8 bump_code = te->getBumpmap(); - return bindBumpMap(bump_code, face->getTexture(), channel); - } - - return FALSE; + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + U8 bump_code = te->getBumpmap(); + return bindBumpMap(bump_code, face->getTexture(), channel); + } + + return FALSE; } //static BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - //Note: texture atlas does not support bump texture now. - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; - if(!tex) - { - //if the texture is not a fetched texture - return FALSE; - } - - LLViewerTexture* bump = NULL; - - switch( bump_code ) - { - case BE_NO_BUMP: - break; - case BE_BRIGHTNESS: - case BE_DARKNESS: - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); - break; - - default: - if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) - { - bump = gStandardBumpmapList[bump_code].mImage; - gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize()); - } - break; - } - - if (bump) - { - if (channel == -2) - { - gGL.getTexUnit(1)->bindFast(bump); - gGL.getTexUnit(0)->bindFast(bump); - } - else - { + //Note: texture atlas does not support bump texture now. + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; + if(!tex) + { + //if the texture is not a fetched texture + return FALSE; + } + + LLViewerTexture* bump = NULL; + + switch( bump_code ) + { + case BE_NO_BUMP: + break; + case BE_BRIGHTNESS: + case BE_DARKNESS: + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); + break; + + default: + if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) + { + bump = gStandardBumpmapList[bump_code].mImage; + gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize()); + } + break; + } + + if (bump) + { + if (channel == -2) + { + gGL.getTexUnit(1)->bindFast(bump); + gGL.getTexUnit(0)->bindFast(bump); + } + else + { // NOTE: do not use bindFast here (see SL-16222) gGL.getTexUnit(channel)->bind(bump); - } + } - return TRUE; - } + return TRUE; + } - return FALSE; + return FALSE; } //static void LLDrawPoolBump::beginBump() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - sVertexMask = VERTEX_MASK_BUMP; - // Optional second pass: emboss bump map - stop_glerror(); + sVertexMask = VERTEX_MASK_BUMP; + // Optional second pass: emboss bump map + stop_glerror(); shader = &gObjectBumpProgram; @@ -515,21 +515,21 @@ void LLDrawPoolBump::beginBump() shader->bind(); - gGL.setSceneBlendType(LLRender::BT_MULT_X2); - stop_glerror(); + gGL.setSceneBlendType(LLRender::BT_MULT_X2); + stop_glerror(); } //static void LLDrawPoolBump::renderBump(U32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); - LLGLEnable blend(GL_BLEND); - gGL.diffuseColor4f(1,1,1,1); - /// Get rid of z-fighting with non-bump pass. - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - pushBumpBatches(pass); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + LLGLEnable blend(GL_BLEND); + gGL.diffuseColor4f(1,1,1,1); + /// Get rid of z-fighting with non-bump pass. + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + pushBumpBatches(pass); } //static @@ -541,7 +541,7 @@ void LLDrawPoolBump::endBump(U32 pass) } S32 LLDrawPoolBump::getNumDeferredPasses() -{ +{ return 1; } @@ -604,7 +604,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) void LLDrawPoolBump::renderPostDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - + S32 num_passes = LLPipeline::sRenderingHUDs ? 1 : 2; // skip rigged pass when rendering HUDs for (int i = 0; i < num_passes; ++i) @@ -632,127 +632,127 @@ void LLDrawPoolBump::renderPostDeferred(S32 pass) void LLBumpImageList::init() { - llassert( mBrightnessEntries.size() == 0 ); - llassert( mDarknessEntries.size() == 0 ); + llassert( mBrightnessEntries.size() == 0 ); + llassert( mDarknessEntries.size() == 0 ); - LLStandardBumpmap::restoreGL(); + LLStandardBumpmap::restoreGL(); sMainQueue = LL::WorkQueue::getInstance("mainloop"); sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. } void LLBumpImageList::clear() { - LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL; - // these will be re-populated on-demand - mBrightnessEntries.clear(); - mDarknessEntries.clear(); + LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL; + // these will be re-populated on-demand + mBrightnessEntries.clear(); + mDarknessEntries.clear(); sRenderTarget.release(); - LLStandardBumpmap::clear(); + LLStandardBumpmap::clear(); } void LLBumpImageList::shutdown() { - clear(); - LLStandardBumpmap::shutdown(); + clear(); + LLStandardBumpmap::shutdown(); } void LLBumpImageList::destroyGL() { - clear(); - LLStandardBumpmap::destroyGL(); + clear(); + LLStandardBumpmap::destroyGL(); } void LLBumpImageList::restoreGL() { - if(!gTextureList.isInitialized()) - { - //safe to return here because bump images will be reloaded during initialization later. - return ; - } - - LLStandardBumpmap::restoreGL(); - // Images will be recreated as they are needed. + if(!gTextureList.isInitialized()) + { + //safe to return here because bump images will be reloaded during initialization later. + return ; + } + + LLStandardBumpmap::restoreGL(); + // Images will be recreated as they are needed. } LLBumpImageList::~LLBumpImageList() { - // Shutdown should have already been called. - llassert( mBrightnessEntries.size() == 0 ); - llassert( mDarknessEntries.size() == 0 ); + // Shutdown should have already been called. + llassert( mBrightnessEntries.size() == 0 ); + llassert( mDarknessEntries.size() == 0 ); } // Note: Does nothing for entries in gStandardBumpmapList that are not actually standard bump images (e.g. none, brightness, and darkness) void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size) { - bump &= TEM_BUMP_MASK; - LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; - if( bump_image ) - { - bump_image->addTextureStats(virtual_size); - } + bump &= TEM_BUMP_MASK; + LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; + if( bump_image ) + { + bump_image->addTextureStats(virtual_size); + } } void LLBumpImageList::updateImages() -{ - for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) - { - LLViewerTexture* image = iter->second; - if( image ) - { - BOOL destroy = TRUE; - if( image->hasGLTexture()) - { - if( image->getBoundRecently() ) - { - destroy = FALSE; - } - else - { - image->destroyGLTexture(); - } - } - - if( destroy ) - { - //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL; - iter = mBrightnessEntries.erase(iter); // deletes the image thanks to reference counting +{ + for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) + { + LLViewerTexture* image = iter->second; + if( image ) + { + BOOL destroy = TRUE; + if( image->hasGLTexture()) + { + if( image->getBoundRecently() ) + { + destroy = FALSE; + } + else + { + image->destroyGLTexture(); + } + } + + if( destroy ) + { + //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL; + iter = mBrightnessEntries.erase(iter); // deletes the image thanks to reference counting continue; - } - } + } + } ++iter; - } - - for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) - { - bump_image_map_t::iterator curiter = iter++; - LLViewerTexture* image = curiter->second; - if( image ) - { - BOOL destroy = TRUE; - if( image->hasGLTexture()) - { - if( image->getBoundRecently() ) - { - destroy = FALSE; - } - else - { - image->destroyGLTexture(); - } - } - - if( destroy ) - { - //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;; - mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting - } - } - } + } + + for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) + { + bump_image_map_t::iterator curiter = iter++; + LLViewerTexture* image = curiter->second; + if( image ) + { + BOOL destroy = TRUE; + if( image->hasGLTexture()) + { + if( image->getBoundRecently() ) + { + destroy = FALSE; + } + else + { + image->destroyGLTexture(); + } + } + + if( destroy ) + { + //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;; + mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting + } + } + } } @@ -760,52 +760,52 @@ void LLBumpImageList::updateImages() LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - - LLViewerTexture* bump = NULL; - - bump_image_map_t* entries_list = NULL; - void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; - - switch( bump_code ) - { - case BE_BRIGHTNESS: - entries_list = &mBrightnessEntries; - callback_func = LLBumpImageList::onSourceBrightnessLoaded; - break; - case BE_DARKNESS: - entries_list = &mDarknessEntries; - callback_func = LLBumpImageList::onSourceDarknessLoaded; - break; - default: - llassert(0); - return NULL; - } - - bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); - if (iter != entries_list->end() && iter->second.notNull()) - { - bump = iter->second; - } - else - { - (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); - bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image - } - - if (!src_image->hasCallbacks()) - { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again - if (src_image->getWidth() != bump->getWidth() || - src_image->getHeight() != bump->getHeight())// || - //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) - { - src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); - src_image->forceToSaveRawImage(0) ; - } - } - - return bump; + llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); + + LLViewerTexture* bump = NULL; + + bump_image_map_t* entries_list = NULL; + void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; + + switch( bump_code ) + { + case BE_BRIGHTNESS: + entries_list = &mBrightnessEntries; + callback_func = LLBumpImageList::onSourceBrightnessLoaded; + break; + case BE_DARKNESS: + entries_list = &mDarknessEntries; + callback_func = LLBumpImageList::onSourceDarknessLoaded; + break; + default: + llassert(0); + return NULL; + } + + bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); + if (iter != entries_list->end() && iter->second.notNull()) + { + bump = iter->second; + } + else + { + (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); + bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image + } + + if (!src_image->hasCallbacks()) + { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again + if (src_image->getWidth() != bump->getWidth() || + src_image->getHeight() != bump->getHeight())// || + //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) + { + src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; + src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); + src_image->forceToSaveRawImage(0) ; + } + } + + return bump; } @@ -813,94 +813,94 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); - if( final ) - { - delete source_asset_id; - } + LLUUID* source_asset_id = (LLUUID*)userdata; + LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); + if( final ) + { + delete source_asset_id; + } } // static void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); - if( final ) - { - delete source_asset_id; - } + LLUUID* source_asset_id = (LLUUID*)userdata; + LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); + if( final ) + { + delete source_asset_id; + } } void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - if (success && LLPipeline::sRenderDeferred) - { + if (success && LLPipeline::sRenderDeferred) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLPointer nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); - { - generateNormalMapFromAlpha(src, nrm_image); - } - src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); - { - src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); - } - } + LLPointer nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); + { + generateNormalMapFromAlpha(src, nrm_image); + } + src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); + { + src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); + } + } } void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image) { - U8* nrm_data = nrm_image->getData(); - S32 resX = src->getWidth(); - S32 resY = src->getHeight(); - - U8* src_data = src->getData(); - - S32 src_cmp = src->getComponents(); - - F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale"); - - U32 idx = 0; - //generate normal map from pseudo-heightfield - for (S32 j = 0; j < resY; ++j) - { - for (S32 i = 0; i < resX; ++i) - { - S32 rX = (i+1)%resX; - S32 rY = (j+1)%resY; - S32 lX = (i-1)%resX; - S32 lY = (j-1)%resY; - - if (lX < 0) - { - lX += resX; - } - if (lY < 0) - { - lY += resY; - } - - F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1]; - - LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH); - LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH); - LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); - LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH); - - LLVector3 norm = right%down + down%left + left%up + up%right; - - norm.normVec(); - - norm *= 0.5f; - norm += LLVector3(0.5f,0.5f,0.5f); - - idx = (j*resX+i)*4; - nrm_data[idx+0]= (U8) (norm.mV[0]*255); - nrm_data[idx+1]= (U8) (norm.mV[1]*255); - nrm_data[idx+2]= (U8) (norm.mV[2]*255); - nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1]; - } - } + U8* nrm_data = nrm_image->getData(); + S32 resX = src->getWidth(); + S32 resY = src->getHeight(); + + U8* src_data = src->getData(); + + S32 src_cmp = src->getComponents(); + + F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale"); + + U32 idx = 0; + //generate normal map from pseudo-heightfield + for (S32 j = 0; j < resY; ++j) + { + for (S32 i = 0; i < resX; ++i) + { + S32 rX = (i+1)%resX; + S32 rY = (j+1)%resY; + S32 lX = (i-1)%resX; + S32 lY = (j-1)%resY; + + if (lX < 0) + { + lX += resX; + } + if (lY < 0) + { + lY += resY; + } + + F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1]; + + LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH); + LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH); + LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); + LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH); + + LLVector3 norm = right%down + down%left + left%up + up%right; + + norm.normVec(); + + norm *= 0.5f; + norm += LLVector3(0.5f,0.5f,0.5f); + + idx = (j*resX+i)*4; + nrm_data[idx+0]= (U8) (norm.mV[0]*255); + nrm_data[idx+1]= (U8) (norm.mV[1]*255); + nrm_data[idx+2]= (U8) (norm.mV[2]*255); + nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1]; + } + } } // static @@ -908,147 +908,147 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { LL_PROFILE_ZONE_SCOPED; - if( success ) - { + if( success ) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); - bump_image_map_t::iterator iter = entries_list.find(source_asset_id); - - { - if (iter == entries_list.end() || - iter->second.isNull() || - iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { //make sure an entry exists for this image - entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); - iter = entries_list.find(src_vi->getID()); - } - } - - if (iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { - LLPointer dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); - U8* dst_data = dst_image->getData(); - S32 dst_data_size = dst_image->getDataSize(); - - U8* src_data = src->getData(); - S32 src_data_size = src->getDataSize(); - - S32 src_components = src->getComponents(); - - // Convert to luminance and then scale and bias that to get ready for - // embossed bump mapping. (0-255 maps to 127-255) - - // Convert to fixed point so we don't have to worry about precision/clamping. - const S32 FIXED_PT = 8; - const S32 R_WEIGHT = S32(0.2995f * (1< maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - case 3: - case 4: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - // RGB to luminance - dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; - //llassert( dst_data[i] <= 255 );true because it's 8bit - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - default: - llassert(0); - dst_image->clear(); - break; - } - - if( maximum > minimum ) - { - U8 bias_and_scale_lut[256]; - F32 twice_one_over_range = 2.f / (maximum - minimum); - S32 i; - - const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. - if (BE_DARKNESS == bump_code) - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - else - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - - for( i = 0; i < dst_data_size; i++ ) - { - dst_data[i] = bias_and_scale_lut[dst_data[i]]; - } - } - - //--------------------------------------------------- - // immediately assign bump to a smart pointer in case some local smart pointer - // accidentally releases it. + bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); + bump_image_map_t::iterator iter = entries_list.find(source_asset_id); + + { + if (iter == entries_list.end() || + iter->second.isNull() || + iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { //make sure an entry exists for this image + entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); + iter = entries_list.find(src_vi->getID()); + } + } + + if (iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { + LLPointer dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); + U8* dst_data = dst_image->getData(); + S32 dst_data_size = dst_image->getDataSize(); + + U8* src_data = src->getData(); + S32 src_data_size = src->getDataSize(); + + S32 src_components = src->getComponents(); + + // Convert to luminance and then scale and bias that to get ready for + // embossed bump mapping. (0-255 maps to 127-255) + + // Convert to fixed point so we don't have to worry about precision/clamping. + const S32 FIXED_PT = 8; + const S32 R_WEIGHT = S32(0.2995f * (1< maximum ) + { + maximum = dst_data[i]; + } + } + } + else + { + llassert(0); + dst_image->clear(); + } + } + break; + case 3: + case 4: + { + if( src_data_size == dst_data_size * src_components ) + { + for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) + { + // RGB to luminance + dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; + //llassert( dst_data[i] <= 255 );true because it's 8bit + if( dst_data[i] < minimum ) + { + minimum = dst_data[i]; + } + if( dst_data[i] > maximum ) + { + maximum = dst_data[i]; + } + } + } + else + { + llassert(0); + dst_image->clear(); + } + } + break; + default: + llassert(0); + dst_image->clear(); + break; + } + + if( maximum > minimum ) + { + U8 bias_and_scale_lut[256]; + F32 twice_one_over_range = 2.f / (maximum - minimum); + S32 i; + + const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. + if (BE_DARKNESS == bump_code) + { + for( i = minimum; i <= maximum; i++ ) + { + F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; + bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); + } + } + else + { + for( i = minimum; i <= maximum; i++ ) + { + F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; + bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); + } + } + + for( i = 0; i < dst_data_size; i++ ) + { + dst_data[i] = bias_and_scale_lut[dst_data[i]]; + } + } + + //--------------------------------------------------- + // immediately assign bump to a smart pointer in case some local smart pointer + // accidentally releases it. LLPointer bump = iter->second; - if (!LLPipeline::sRenderDeferred) - { - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + if (!LLPipeline::sRenderDeferred) + { + bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); #if LL_BUMPLIST_MULTITHREADED auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr; @@ -1074,9 +1074,9 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { bump->createGLTexture(0, dst_image); } - } - else - { //convert to normal map + } + else + { //convert to normal map LL_PROFILE_ZONE_NAMED("bil - create normal map"); LLImageGL* img = bump->getGLTexture(); LLImageRaw* dst_ptr = dst_image.get(); @@ -1180,16 +1180,16 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI } - } + } - iter->second = bump; // derefs (and deletes) old image - //--------------------------------------------------- - } - } + iter->second = bump; // derefs (and deletes) old image + //--------------------------------------------------- + } + } } void LLDrawPoolBump::pushBumpBatches(U32 type) -{ +{ LLVOAvatar* avatar = nullptr; U64 skin = 0; @@ -1201,12 +1201,12 @@ void LLDrawPoolBump::pushBumpBatches(U32 type) LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) - { - LLDrawInfo& params = **i; + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) + { + LLDrawInfo& params = **i; - if (LLDrawPoolBump::bindBumpMap(params)) - { + if (LLDrawPoolBump::bindBumpMap(params)) + { if (mRigged) { if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) @@ -1222,80 +1222,80 @@ void LLDrawPoolBump::pushBumpBatches(U32 type) } } } - pushBumpBatch(params, false); - } - } + pushBumpBatch(params, false); + } + } } void LLRenderPass::pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - applyModelMatrix(params); - - bool tex_setup = false; - - if (batch_textures && params.mTextureList.size() > 1) - { - for (U32 i = 0; i < params.mTextureList.size(); ++i) - { - if (params.mTextureList[i].notNull()) - { - gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); - } - } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (params.mTextureMatrix) - { - if (shiny) - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - else - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - - tex_setup = true; - } - - if (shiny && mShaderLevel > 1 && texture) - { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); - } - else - { - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - } - } - } - - params.mVertexBuffer->setBuffer(); - params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + applyModelMatrix(params); + + bool tex_setup = false; + + if (batch_textures && params.mTextureList.size() > 1) + { + for (U32 i = 0; i < params.mTextureList.size(); ++i) + { + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); + } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTextureMatrix) + { + if (shiny) + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + } + else + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + + tex_setup = true; + } + + if (shiny && mShaderLevel > 1 && texture) + { + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); + } + else + { + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + } + } + } + + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) - { - if (shiny) - { - gGL.getTexUnit(0)->activate(); - } - else - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } + { + if (shiny) + { + gGL.getTexUnit(0)->activate(); + } + else + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + } + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index c5932a6ad9..1b8097c3a4 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolterrain.cpp * @brief LLDrawPoolTerrain class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,7 +39,7 @@ #include "llsurfacepatch.h" #include "llviewerregion.h" #include "llvlcomposition.h" -#include "llviewerparcelmgr.h" // for gRenderParcelOwnership +#include "llviewerparcelmgr.h" // for gRenderParcelOwnership #include "llviewerparceloverlay.h" #include "llvosurfacepatch.h" #include "llviewercamera.h" @@ -62,47 +62,47 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow"); LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : - LLFacePool(POOL_TERRAIN), - mTexturep(texturep) + LLFacePool(POOL_TERRAIN), + mTexturep(texturep) { - // Hack! - sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); - sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); - sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); - mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); - - //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); - mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - - m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD_2D); - - //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); - m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - - mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN); - - //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + // Hack! + sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); + sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); + sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); + mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); + + //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + + m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD_2D); + + //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + + mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } LLDrawPoolTerrain::~LLDrawPoolTerrain() { - llassert( gPipeline.findPool( getType(), getTexture() ) == NULL ); + llassert( gPipeline.findPool( getType(), getTexture() ) == NULL ); } -U32 LLDrawPoolTerrain::getVertexDataMask() -{ - if (LLPipeline::sShadowRender) - { - return LLVertexBuffer::MAP_VERTEX; - } - else if (LLGLSLShader::sCurBoundShaderPtr) - { - return VERTEX_DATA_MASK & ~(LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_TEXCOORD3); - } - else - { - return VERTEX_DATA_MASK; - } +U32 LLDrawPoolTerrain::getVertexDataMask() +{ + if (LLPipeline::sShadowRender) + { + return LLVertexBuffer::MAP_VERTEX; + } + else if (LLGLSLShader::sCurBoundShaderPtr) + { + return VERTEX_DATA_MASK & ~(LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_TEXCOORD3); + } + else + { + return VERTEX_DATA_MASK; + } } void LLDrawPoolTerrain::prerender() @@ -113,50 +113,50 @@ void LLDrawPoolTerrain::prerender() void LLDrawPoolTerrain::boostTerrainDetailTextures() { // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); compp->boost(); } void LLDrawPoolTerrain::beginDeferredPass(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); - LLFacePool::beginRenderPass(pass); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LLFacePool::beginRenderPass(pass); } void LLDrawPoolTerrain::endDeferredPass(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); - LLFacePool::endRenderPass(pass); - sShader->unbind(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LLFacePool::endRenderPass(pass); + sShader->unbind(); } void LLDrawPoolTerrain::renderDeferred(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); - if (mDrawFace.empty()) - { - return; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + if (mDrawFace.empty()) + { + return; + } boostTerrainDetailTextures(); - renderFullShader(); + renderFullShader(); - // Special-case for land ownership feedback - if (gSavedSettings.getBOOL("ShowParcelOwners")) - { - hilightParcelOwners(); - } + // Special-case for land ownership feedback + if (gSavedSettings.getBOOL("ShowParcelOwners")) + { + hilightParcelOwners(); + } } void LLDrawPoolTerrain::beginShadowPass(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); - LLFacePool::beginRenderPass(pass); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gDeferredShadowProgram.bind(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + LLFacePool::beginRenderPass(pass); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gDeferredShadowProgram.bind(); LLEnvironment& environment = LLEnvironment::instance(); gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); @@ -164,50 +164,50 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass) void LLDrawPoolTerrain::endShadowPass(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); - LLFacePool::endRenderPass(pass); - gDeferredShadowProgram.unbind(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + LLFacePool::endRenderPass(pass); + gDeferredShadowProgram.unbind(); } void LLDrawPoolTerrain::renderShadow(S32 pass) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); - if (mDrawFace.empty()) - { - return; - } - //LLGLEnable offset(GL_POLYGON_OFFSET); - //glCullFace(GL_FRONT); - drawLoop(); - //glCullFace(GL_BACK); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + if (mDrawFace.empty()) + { + return; + } + //LLGLEnable offset(GL_POLYGON_OFFSET); + //glCullFace(GL_FRONT); + drawLoop(); + //glCullFace(GL_BACK); } void LLDrawPoolTerrain::drawLoop() { - if (!mDrawFace.empty()) - { - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *facep = *iter; + if (!mDrawFace.empty()) + { + for (std::vector::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *facep = *iter; llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix); - facep->renderIndexed(); - } - } + facep->renderIndexed(); + } + } } void LLDrawPoolTerrain::renderFullShader() { const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false); - // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::Type::TEXTURE); - + if (use_textures) { // Use textures @@ -226,129 +226,129 @@ void LLDrawPoolTerrain::renderFullShader() void LLDrawPoolTerrain::renderFullShaderTextures() { - // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); - - LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; - LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; - LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; - LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; - - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; - - LLVector4 tp0, tp1; - - tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - - // - // detail texture 0 - // - S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); - gGL.getTexUnit(detail0)->bind(detail_texture0p); + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + + LLVector4 tp0, tp1; + + tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + + // + // detail texture 0 + // + S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); + gGL.getTexUnit(detail0)->bind(detail_texture0p); gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail0)->activate(); + gGL.getTexUnit(detail0)->activate(); - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader); - - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - // - // detail texture 1 - // - S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); - gGL.getTexUnit(detail1)->bind(detail_texture1p); - gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail1)->activate(); - - // detail texture 2 - // - S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); - gGL.getTexUnit(detail2)->bind(detail_texture2p); + // + // detail texture 1 + // + S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); + gGL.getTexUnit(detail1)->bind(detail_texture1p); + gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail1)->activate(); + + // detail texture 2 + // + S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); + gGL.getTexUnit(detail2)->bind(detail_texture2p); gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail2)->activate(); - - - // detail texture 3 - // - S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); - gGL.getTexUnit(detail3)->bind(detail_texture3p); - gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail3)->activate(); - - // - // Alpha Ramp - // - S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); + gGL.getTexUnit(detail2)->activate(); + + + // detail texture 3 + // + S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); + gGL.getTexUnit(detail3)->bind(detail_texture3p); + gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail3)->activate(); + + // + // Alpha Ramp + // + S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - // GL_BLEND disabled by default - drawLoop(); - - // Disable multitexture - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); - - gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(alpha_ramp)->disable(); - gGL.getTexUnit(alpha_ramp)->activate(); - - gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail3)->disable(); - gGL.getTexUnit(detail3)->activate(); - - gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail2)->disable(); - gGL.getTexUnit(detail2)->activate(); - - gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail1)->disable(); - gGL.getTexUnit(detail1)->activate(); - - //---------------------------------------------------------------------------- - // Restore Texture Unit 0 defaults - - gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail0)->activate(); + // GL_BLEND disabled by default + drawLoop(); + + // Disable multitexture + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); + + gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(alpha_ramp)->disable(); + gGL.getTexUnit(alpha_ramp)->activate(); + + gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail3)->disable(); + gGL.getTexUnit(detail3)->activate(); + + gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail2)->disable(); + gGL.getTexUnit(detail2)->activate(); + + gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail1)->disable(); + gGL.getTexUnit(detail1)->activate(); + + //---------------------------------------------------------------------------- + // Restore Texture Unit 0 defaults + + gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail0)->activate(); } // *TODO: Investigate use of bindFast for PBR terrain textures void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) { - // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); - LLPointer (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + LLPointer (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; - constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT; + constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT; #ifdef SHOW_ASSERT - constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; - llassert(shader_material_count == terrain_material_count); + constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; + llassert(shader_material_count == terrain_material_count); #endif if (local_materials) { // Override region terrain with the global local override terrain - fetched_materials = &gLocalTerrainMaterials.mDetailMaterials; + fetched_materials = &gLocalTerrainMaterials.mDetailMaterials; + } + const LLGLTFMaterial* materials[terrain_material_count]; + for (U32 i = 0; i < terrain_material_count; ++i) + { + materials[i] = (*fetched_materials)[i].get(); + if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; } } - const LLGLTFMaterial* materials[terrain_material_count]; - for (U32 i = 0; i < terrain_material_count; ++i) - { - materials[i] = (*fetched_materials)[i].get(); - if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; } - } S32 detail_basecolor[terrain_material_count]; S32 detail_normal[terrain_material_count]; @@ -357,19 +357,19 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) for (U32 i = 0; i < terrain_material_count; ++i) { - LLViewerTexture* detail_basecolor_texturep = nullptr; - LLViewerTexture* detail_normal_texturep = nullptr; - LLViewerTexture* detail_metalrough_texturep = nullptr; - LLViewerTexture* detail_emissive_texturep = nullptr; - - const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get(); - if (fetched_material) - { - detail_basecolor_texturep = fetched_material->mBaseColorTexture; - detail_normal_texturep = fetched_material->mNormalTexture; - detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture; - detail_emissive_texturep = fetched_material->mEmissiveTexture; - } + LLViewerTexture* detail_basecolor_texturep = nullptr; + LLViewerTexture* detail_normal_texturep = nullptr; + LLViewerTexture* detail_metalrough_texturep = nullptr; + LLViewerTexture* detail_emissive_texturep = nullptr; + + const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get(); + if (fetched_material) + { + detail_basecolor_texturep = fetched_material->mBaseColorTexture; + detail_normal_texturep = fetched_material->mNormalTexture; + detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture; + detail_emissive_texturep = fetched_material->mEmissiveTexture; + } detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); if (detail_basecolor_texturep) @@ -429,16 +429,16 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) } } - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader); - + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + // *TODO: Figure out why this offset is *sometimes* producing seams at the // region edge, and repeat jumps when crossing regions, when // RenderTerrainPBRScale is not a factor of the region scale. - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; LLGLTFMaterial::TextureTransform base_color_transform; base_color_transform.mScale = LLVector2(sPBRDetailScale, sPBRDetailScale); @@ -451,11 +451,11 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - // - // Alpha Ramp - // - S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); + // + // Alpha Ramp + // + S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); // @@ -500,16 +500,16 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) } shader->uniform4f(LLShaderMgr::TERRAIN_MINIMUM_ALPHAS, minimum_alphas[0], minimum_alphas[1], minimum_alphas[2], minimum_alphas[3]); - // GL_BLEND disabled by default - drawLoop(); + // GL_BLEND disabled by default + drawLoop(); - // Disable multitexture + // Disable multitexture - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(alpha_ramp)->disable(); - gGL.getTexUnit(alpha_ramp)->activate(); + gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(alpha_ramp)->disable(); + gGL.getTexUnit(alpha_ramp)->activate(); for (U32 i = 0; i < terrain_material_count; ++i) { @@ -556,466 +556,466 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) void LLDrawPoolTerrain::hilightParcelOwners() { - { //use fullbright shader for highlighting - LLGLSLShader* old_shader = sShader; - sShader->unbind(); - sShader = &gDeferredHighlightProgram; - sShader->bind(); - gGL.diffuseColor4f(1, 1, 1, 1); - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - renderOwnership(); - sShader = old_shader; - sShader->bind(); - } - + { //use fullbright shader for highlighting + LLGLSLShader* old_shader = sShader; + sShader->unbind(); + sShader = &gDeferredHighlightProgram; + sShader->bind(); + gGL.diffuseColor4f(1, 1, 1, 1); + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + renderOwnership(); + sShader = old_shader; + sShader->bind(); + } + } void LLDrawPoolTerrain::renderFull4TU() { - // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); - LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; - LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; - LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; - LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; - - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; - - LLVector4 tp0, tp1; - - tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - - gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA); - - //---------------------------------------------------------------------------- - // Pass 1/1 - - // - // Stage 0: detail texture 0 - // - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(detail_texture0p); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - // - // Stage 1: Generate alpha ramp for detail0/detail1 transition - // - - gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get()); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->activate(); - - // - // Stage 2: Interpolate detail1 with existing based on ramp - // - gGL.getTexUnit(2)->bind(detail_texture1p); - gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(2)->activate(); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - // - // Stage 3: Modulate with primary (vertex) color for lighting - // - gGL.getTexUnit(3)->bind(detail_texture1p); - gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(3)->activate(); - - gGL.getTexUnit(0)->activate(); - - // GL_BLEND disabled by default - drawLoop(); - - //---------------------------------------------------------------------------- - // Second pass - - // Stage 0: Write detail3 into base - // - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(detail_texture3p); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - // - // Stage 1: Generate alpha ramp for detail2/detail3 transition - // - gGL.getTexUnit(1)->bind(m2DAlphaRampImagep); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->activate(); - - // Set the texture matrix - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.translatef(-2.f, 0.f, 0.f); - - // - // Stage 2: Interpolate detail2 with existing based on ramp - // - gGL.getTexUnit(2)->bind(detail_texture2p); - gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(2)->activate(); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - // - // Stage 3: Generate alpha ramp for detail1/detail2 transition - // - gGL.getTexUnit(3)->bind(m2DAlphaRampImagep); - gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(3)->activate(); - - // Set the texture matrix - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.translatef(-1.f, 0.f, 0.f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - gGL.getTexUnit(0)->activate(); - { - LLGLEnable blend(GL_BLEND); - drawLoop(); - } - - LLVertexBuffer::unbind(); - // Disable multitexture - gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(3)->disable(); - gGL.getTexUnit(3)->activate(); - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(2)->disable(); - gGL.getTexUnit(2)->activate(); - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->activate(); - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - // Restore blend state - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - //---------------------------------------------------------------------------- - // Restore Texture Unit 0 defaults - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + + LLVector4 tp0, tp1; + + tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + + gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA); + + //---------------------------------------------------------------------------- + // Pass 1/1 + + // + // Stage 0: detail texture 0 + // + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->bind(detail_texture0p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + // + // Stage 1: Generate alpha ramp for detail0/detail1 transition + // + + gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->activate(); + + // + // Stage 2: Interpolate detail1 with existing based on ramp + // + gGL.getTexUnit(2)->bind(detail_texture1p); + gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->activate(); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + // + // Stage 3: Modulate with primary (vertex) color for lighting + // + gGL.getTexUnit(3)->bind(detail_texture1p); + gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(3)->activate(); + + gGL.getTexUnit(0)->activate(); + + // GL_BLEND disabled by default + drawLoop(); + + //---------------------------------------------------------------------------- + // Second pass + + // Stage 0: Write detail3 into base + // + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->bind(detail_texture3p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + // + // Stage 1: Generate alpha ramp for detail2/detail3 transition + // + gGL.getTexUnit(1)->bind(m2DAlphaRampImagep); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->activate(); + + // Set the texture matrix + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.translatef(-2.f, 0.f, 0.f); + + // + // Stage 2: Interpolate detail2 with existing based on ramp + // + gGL.getTexUnit(2)->bind(detail_texture2p); + gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->activate(); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + // + // Stage 3: Generate alpha ramp for detail1/detail2 transition + // + gGL.getTexUnit(3)->bind(m2DAlphaRampImagep); + gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(3)->activate(); + + // Set the texture matrix + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.translatef(-1.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + gGL.getTexUnit(0)->activate(); + { + LLGLEnable blend(GL_BLEND); + drawLoop(); + } + + LLVertexBuffer::unbind(); + // Disable multitexture + gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(3)->disable(); + gGL.getTexUnit(3)->activate(); + + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->disable(); + gGL.getTexUnit(2)->activate(); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->activate(); + + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + // Restore blend state + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + //---------------------------------------------------------------------------- + // Restore Texture Unit 0 defaults + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); } void LLDrawPoolTerrain::renderFull2TU() { - // Hack! Get the region that this draw pool is rendering from! - LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); - LLVLComposition *compp = regionp->getComposition(); - LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; - LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; - LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; - LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; - - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; - - LLVector4 tp0, tp1; - - tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - - gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA); - - //---------------------------------------------------------------------------- - // Pass 1/4 - - // - // Stage 0: Render detail 0 into base - // - gGL.getTexUnit(0)->bind(detail_texture0p); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - drawLoop(); - - //---------------------------------------------------------------------------- - // Pass 2/4 - - // - // Stage 0: Generate alpha ramp for detail0/detail1 transition - // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - - // - // Stage 1: Write detail1 - // - gGL.getTexUnit(1)->bind(detail_texture1p); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->activate(); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - gGL.getTexUnit(0)->activate(); - { - LLGLEnable blend(GL_BLEND); - drawLoop(); - } - //---------------------------------------------------------------------------- - // Pass 3/4 - - // - // Stage 0: Generate alpha ramp for detail1/detail2 transition - // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); - - // Set the texture matrix - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.translatef(-1.f, 0.f, 0.f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - // - // Stage 1: Write detail2 - // - gGL.getTexUnit(1)->bind(detail_texture2p); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->activate(); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - { - LLGLEnable blend(GL_BLEND); - drawLoop(); - } - - //---------------------------------------------------------------------------- - // Pass 4/4 - - // - // Stage 0: Generate alpha ramp for detail2/detail3 transition - // - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); - // Set the texture matrix - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.translatef(-2.f, 0.f, 0.f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - // Stage 1: Write detail3 - gGL.getTexUnit(1)->bind(detail_texture3p); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->activate(); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - - gGL.getTexUnit(0)->activate(); - { - LLGLEnable blend(GL_BLEND); - drawLoop(); - } - - // Restore blend state - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - // Disable multitexture - - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->activate(); - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - //---------------------------------------------------------------------------- - // Restore Texture Unit 0 defaults - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + + LLVector4 tp0, tp1; + + tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + + gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA); + + //---------------------------------------------------------------------------- + // Pass 1/4 + + // + // Stage 0: Render detail 0 into base + // + gGL.getTexUnit(0)->bind(detail_texture0p); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + drawLoop(); + + //---------------------------------------------------------------------------- + // Pass 2/4 + + // + // Stage 0: Generate alpha ramp for detail0/detail1 transition + // + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + + // + // Stage 1: Write detail1 + // + gGL.getTexUnit(1)->bind(detail_texture1p); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->activate(); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + gGL.getTexUnit(0)->activate(); + { + LLGLEnable blend(GL_BLEND); + drawLoop(); + } + //---------------------------------------------------------------------------- + // Pass 3/4 + + // + // Stage 0: Generate alpha ramp for detail1/detail2 transition + // + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); + + // Set the texture matrix + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.translatef(-1.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + // + // Stage 1: Write detail2 + // + gGL.getTexUnit(1)->bind(detail_texture2p); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->activate(); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + { + LLGLEnable blend(GL_BLEND); + drawLoop(); + } + + //---------------------------------------------------------------------------- + // Pass 4/4 + + // + // Stage 0: Generate alpha ramp for detail2/detail3 transition + // + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); + // Set the texture matrix + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.translatef(-2.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + // Stage 1: Write detail3 + gGL.getTexUnit(1)->bind(detail_texture3p); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->activate(); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + + gGL.getTexUnit(0)->activate(); + { + LLGLEnable blend(GL_BLEND); + drawLoop(); + } + + // Restore blend state + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + // Disable multitexture + + gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->activate(); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + //---------------------------------------------------------------------------- + // Restore Texture Unit 0 defaults + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); } void LLDrawPoolTerrain::renderSimple() { - LLVector4 tp0, tp1; - - //---------------------------------------------------------------------------- - // Pass 1/1 - - // Stage 0: Base terrain texture pass - mTexturep->addTextureStats(1024.f*1024.f); - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->bind(mTexturep); - - LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent(); - F32 tscale = 1.f/256.f; - tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f)); - tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f)); - - sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); - sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); - - drawLoop(); - - //---------------------------------------------------------------------------- - // Restore Texture Unit 0 defaults - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); + LLVector4 tp0, tp1; + + //---------------------------------------------------------------------------- + // Pass 1/1 + + // Stage 0: Base terrain texture pass + mTexturep->addTextureStats(1024.f*1024.f); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->bind(mTexturep); + + LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent(); + F32 tscale = 1.f/256.f; + tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f)); + tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f)); + + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + + drawLoop(); + + //---------------------------------------------------------------------------- + // Restore Texture Unit 0 defaults + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); } //============================================================================ void LLDrawPoolTerrain::renderOwnership() { - LLGLSPipelineAlpha gls_pipeline_alpha; - - llassert(!mDrawFace.empty()); - - // Each terrain pool is associated with a single region. - // We need to peek back into the viewer's data to find out - // which ownership overlay texture to use. - LLFace *facep = mDrawFace[0]; - LLDrawable *drawablep = facep->getDrawable(); - const LLViewerObject *objectp = drawablep->getVObj(); - const LLVOSurfacePatch *vo_surface_patchp = (LLVOSurfacePatch *)objectp; - LLSurfacePatch *surface_patchp = vo_surface_patchp->getPatch(); - LLSurface *surfacep = surface_patchp->getSurface(); - LLViewerRegion *regionp = surfacep->getRegion(); - LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay(); - LLViewerTexture *texturep = overlayp->getTexture(); - - gGL.getTexUnit(0)->bind(texturep); - - // *NOTE: Because the region is 256 meters wide, but has 257 pixels, the - // texture coordinates for pixel 256x256 is not 1,1. This makes the - // ownership map not line up with the selection. We address this with - // a texture matrix multiply. - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.pushMatrix(); - - const F32 TEXTURE_FUDGE = 257.f / 256.f; - gGL.scalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f ); - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *facep = *iter; - facep->renderIndexed(); - } - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); + LLGLSPipelineAlpha gls_pipeline_alpha; + + llassert(!mDrawFace.empty()); + + // Each terrain pool is associated with a single region. + // We need to peek back into the viewer's data to find out + // which ownership overlay texture to use. + LLFace *facep = mDrawFace[0]; + LLDrawable *drawablep = facep->getDrawable(); + const LLViewerObject *objectp = drawablep->getVObj(); + const LLVOSurfacePatch *vo_surface_patchp = (LLVOSurfacePatch *)objectp; + LLSurfacePatch *surface_patchp = vo_surface_patchp->getPatch(); + LLSurface *surfacep = surface_patchp->getSurface(); + LLViewerRegion *regionp = surfacep->getRegion(); + LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay(); + LLViewerTexture *texturep = overlayp->getTexture(); + + gGL.getTexUnit(0)->bind(texturep); + + // *NOTE: Because the region is 256 meters wide, but has 257 pixels, the + // texture coordinates for pixel 256x256 is not 1,1. This makes the + // ownership map not line up with the selection. We address this with + // a texture matrix multiply. + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.pushMatrix(); + + const F32 TEXTURE_FUDGE = 257.f / 256.f; + gGL.scalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f ); + for (std::vector::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *facep = *iter; + facep->renderIndexed(); + } + + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); } void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ; - if (tex && textures.find(tex) != textures.end()) - { - for (std::vector::iterator iter = mReferences.begin(); - iter != mReferences.end(); iter++) - { - LLFace *facep = *iter; - gPipeline.markTextured(facep->getDrawable()); - } - } + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ; + if (tex && textures.find(tex) != textures.end()) + { + for (std::vector::iterator iter = mReferences.begin(); + iter != mReferences.end(); iter++) + { + LLFace *facep = *iter; + gPipeline.markTextured(facep->getDrawable()); + } + } } LLViewerTexture *LLDrawPoolTerrain::getTexture() { - return mTexturep; + return mTexturep; } LLViewerTexture *LLDrawPoolTerrain::getDebugTexture() { - return mTexturep; + return mTexturep; } LLColor3 LLDrawPoolTerrain::getDebugColor() const { - return LLColor3(0.f, 0.f, 1.f); + return LLColor3(0.f, 0.f, 1.f); } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 13f031c8e7..5ee91eb47c 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolterrain.h * @brief LLDrawPoolTerrain class definition * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,7 +31,7 @@ class LLDrawPoolTerrain : public LLFacePool { - LLPointer mTexturep; + LLPointer mTexturep; public: enum { @@ -40,51 +40,51 @@ public: LLVertexBuffer::MAP_TANGENT | // Only PBR terrain uses this currently LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 - }; + }; - virtual U32 getVertexDataMask(); - LLDrawPoolTerrain(LLViewerTexture *texturep); - virtual ~LLDrawPoolTerrain(); + virtual U32 getVertexDataMask(); + LLDrawPoolTerrain(LLViewerTexture *texturep); + virtual ~LLDrawPoolTerrain(); - /*virtual*/ S32 getNumDeferredPasses() { return 1; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); + /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); - /*virtual*/ S32 getNumShadowPasses() { return 1; } - /*virtual*/ void beginShadowPass(S32 pass); - /*virtual*/ void endShadowPass(S32 pass); - /*virtual*/ void renderShadow(S32 pass); + /*virtual*/ S32 getNumShadowPasses() { return 1; } + /*virtual*/ void beginShadowPass(S32 pass); + /*virtual*/ void endShadowPass(S32 pass); + /*virtual*/ void renderShadow(S32 pass); - /*virtual*/ void prerender(); - /*virtual*/ void dirtyTextures(const std::set& textures); - /*virtual*/ LLViewerTexture *getTexture(); - /*virtual*/ LLViewerTexture *getDebugTexture(); - /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display + /*virtual*/ void prerender(); + /*virtual*/ void dirtyTextures(const std::set& textures); + /*virtual*/ LLViewerTexture *getTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); + /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - LLPointer mAlphaRampImagep; - LLPointer m2DAlphaRampImagep; - LLPointer mAlphaNoiseImagep; + LLPointer mAlphaRampImagep; + LLPointer m2DAlphaRampImagep; + LLPointer mAlphaNoiseImagep; - static S32 sPBRDetailMode; - static F32 sDetailScale; // textures per meter - static F32 sPBRDetailScale; // textures per meter + static S32 sPBRDetailMode; + static F32 sDetailScale; // textures per meter + static F32 sPBRDetailScale; // textures per meter protected: void boostTerrainDetailTextures(); - void renderSimple(); - void renderOwnership(); + void renderSimple(); + void renderOwnership(); - void renderFull2TU(); - void renderFull4TU(); - void renderFullShader(); - void renderFullShaderTextures(); - void renderFullShaderPBR(BOOL local_materials = false); - void drawLoop(); + void renderFull2TU(); + void renderFull4TU(); + void renderFullShader(); + void renderFullShaderTextures(); + void renderFullShaderPBR(BOOL local_materials = false); + void drawLoop(); private: - void hilightParcelOwners(); + void hilightParcelOwners(); }; #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 50c4a2c1b3..43620747d4 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpooltree.cpp * @brief LLDrawPoolTree class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,10 +44,10 @@ S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : - LLFacePool(POOL_TREE), - mTexturep(texturep) + LLFacePool(POOL_TREE), + mTexturep(texturep) { - mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); + mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } //============================================ @@ -55,11 +55,11 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : //============================================ void LLDrawPoolTree::beginDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); - - shader = &gDeferredTreeProgram; - shader->bind(); - shader->setMinimumAlpha(0.5f); + LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); + + shader = &gDeferredTreeProgram; + shader->bind(); + shader->setMinimumAlpha(0.5f); } void LLDrawPoolTree::renderDeferred(S32 pass) @@ -96,9 +96,9 @@ void LLDrawPoolTree::renderDeferred(S32 pass) void LLDrawPoolTree::endDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); - - shader->unbind(); + LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); + + shader->unbind(); } //============================================ @@ -107,49 +107,49 @@ void LLDrawPoolTree::endDeferredPass(S32 pass) void LLDrawPoolTree::beginShadowPass(S32 pass) { LL_PROFILE_ZONE_SCOPED; - - glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), - gSavedSettings.getF32("RenderDeferredTreeShadowBias")); + + glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), + gSavedSettings.getF32("RenderDeferredTreeShadowBias")); LLEnvironment& environment = LLEnvironment::instance(); - gDeferredTreeShadowProgram.bind(); + gDeferredTreeShadowProgram.bind(); gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - gDeferredTreeShadowProgram.setMinimumAlpha(0.5f); + gDeferredTreeShadowProgram.setMinimumAlpha(0.5f); } void LLDrawPoolTree::renderShadow(S32 pass) { - renderDeferred(pass); + renderDeferred(pass); } void LLDrawPoolTree::endShadowPass(S32 pass) { LL_PROFILE_ZONE_SCOPED; - - glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), - gSavedSettings.getF32("RenderDeferredSpotShadowBias")); - gDeferredTreeShadowProgram.unbind(); + + glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), + gSavedSettings.getF32("RenderDeferredSpotShadowBias")); + gDeferredTreeShadowProgram.unbind(); } BOOL LLDrawPoolTree::verify() const { - return TRUE; + return TRUE; } LLViewerTexture *LLDrawPoolTree::getTexture() { - return mTexturep; + return mTexturep; } LLViewerTexture *LLDrawPoolTree::getDebugTexture() { - return mTexturep; + return mTexturep; } LLColor3 LLDrawPoolTree::getDebugColor() const { - return LLColor3(1.f, 0.f, 1.f); + return LLColor3(1.f, 0.f, 1.f); } diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 68be354533..c16b6408d7 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolwlsky.cpp * @brief LLDrawPoolWLSky class implementation * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,7 +33,7 @@ #include "llimage.h" #include "llrender.h" #include "llatmosphere.h" -#include "llenvironment.h" +#include "llenvironment.h" #include "llglslshader.h" #include "llgl.h" @@ -59,7 +59,7 @@ static LLGLSLShader* moon_shader = NULL; static float sStarTime; LLDrawPoolWLSky::LLDrawPoolWLSky(void) : - LLDrawPool(POOL_WL_SKY) + LLDrawPool(POOL_WL_SKY) { } @@ -69,13 +69,13 @@ LLDrawPoolWLSky::~LLDrawPoolWLSky() LLViewerTexture *LLDrawPoolWLSky::getDebugTexture() { - return NULL; + return NULL; } void LLDrawPoolWLSky::beginDeferredPass(S32 pass) { - sky_shader = &gDeferredWLSkyProgram; - cloud_shader = &gDeferredWLCloudProgram; + sky_shader = &gDeferredWLSkyProgram; + cloud_shader = &gDeferredWLCloudProgram; sun_shader = &gDeferredWLSunProgram; @@ -98,34 +98,34 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca llassert_always(NULL != shader); gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - - //chop off translation - if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f) - { - gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f); - } - else - { - gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); - } - - - // the windlight sky dome works most conveniently in a coordinate system - // where Y is up, so permute our basis vectors accordingly. - gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); - - gGL.scalef(0.333f, 0.333f, 0.333f); - - gGL.translatef(0.f,-camHeightLocal, 0.f); - - // Draw WL Sky - shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); + gGL.pushMatrix(); + + //chop off translation + if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f) + { + gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f); + } + else + { + gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); + } + + + // the windlight sky dome works most conveniently in a coordinate system + // where Y is up, so permute our basis vectors accordingly. + gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + + gGL.scalef(0.333f, 0.333f, 0.333f); + + gGL.translatef(0.f,-camHeightLocal, 0.f); + + // Draw WL Sky + shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); gSky.mVOWLSkyp->drawDome(); gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gGL.popMatrix(); } extern LLPointer gEXRImage; @@ -150,8 +150,8 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) - { + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) + { if (use_hdri_sky()) { sky_shader = &gEnvironmentMapProgram; @@ -211,9 +211,9 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0); /// Render the skydome - renderDome(origin, camHeightLocal, sky_shader); + renderDome(origin, camHeightLocal, sky_shader); - sky_shader->unbind(); + sky_shader->unbind(); } } @@ -224,30 +224,30 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const return; } - LLGLSPipelineBlendSkyBox gls_sky(true, false); + LLGLSPipelineBlendSkyBox gls_sky(true, false); - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); F32 star_alpha = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 500.0f; - // If start_brightness is not set, exit - if(star_alpha < 0.001f) - { - LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL; - return; - } + // If start_brightness is not set, exit + if(star_alpha < 0.001f) + { + LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL; + return; + } - gDeferredStarProgram.bind(); + gDeferredStarProgram.bind(); LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex(); LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext(); F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor(); - + if (tex_a && (!tex_b || (tex_a == tex_b))) { // Bind current and next sun textures - gGL.getTexUnit(0)->bind(tex_a); + gGL.getTexUnit(0)->bind(tex_a); gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); blend_factor = 0; } @@ -263,29 +263,29 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const gGL.getTexUnit(1)->bind(tex_b); } - gGL.pushMatrix(); - gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); - gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); + gGL.pushMatrix(); + gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); + gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); if (LLPipeline::sReflectionRender) { star_alpha = 1.0f; } - gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha); + gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha); sStarTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f; gDeferredStarProgram.uniform1f(LLShaderMgr::WATER_TIME, sStarTime); - gSky.mVOWLSkyp->drawStars(); + gSky.mVOWLSkyp->drawStars(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); gDeferredStarProgram.unbind(); - gGL.popMatrix(); + gGL.popMatrix(); } void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const @@ -295,13 +295,13 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 return; } - if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex()) - { + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex()) + { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLGLSPipelineBlendSkyBox pipeline(true, true); - - cloudshader->bind(); + LLGLSPipelineBlendSkyBox pipeline(true, true); + + cloudshader->bind(); LLPointer cloud_noise = gSky.mVOSkyp->getCloudNoiseTex(); LLPointer cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext(); @@ -342,14 +342,14 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance); cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); - /// Render the skydome + /// Render the skydome renderDome(camPosLocal, camHeightLocal, cloudshader); - cloudshader->unbind(); + cloudshader->unbind(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - } + } } void LLDrawPoolWLSky::renderHeavenlyBodies() @@ -359,19 +359,19 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - gGL.pushMatrix(); - gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); + gGL.pushMatrix(); + gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; + LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor(); bool can_use_vertex_shaders = gPipeline.shadersLoaded(); bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders(); - if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount()) - { - LLPointer tex_a = face->getTexture(LLRender::DIFFUSE_MAP); + if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount()) + { + LLPointer tex_a = face->getTexture(LLRender::DIFFUSE_MAP); LLPointer tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -415,17 +415,17 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() sun_shader->unbind(); } } - } + } - face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; + face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; - if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader) - { + if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader) + { LLViewerTexture* tex_a = face->getTexture(LLRender::DIFFUSE_MAP); LLViewerTexture* tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP); - LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); - + LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); + if (can_use_vertex_shaders && can_use_windlight_shaders && (tex_a || tex_b)) { moon_shader->bind(); @@ -472,10 +472,10 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() void LLDrawPoolWLSky::renderDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull()) - { - return; - } + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull()) + { + return; + } // TODO: remove gSky.mVOSkyp and fold sun/moon into LLVOWLSky gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); @@ -504,7 +504,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) LLViewerTexture* LLDrawPoolWLSky::getTexture() { - return NULL; + return NULL; } void LLDrawPoolWLSky::resetDrawOrders() diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 24818241ab..f1145948a7 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldynamictexture.cpp * @brief Implementation of LLViewerDynamicTexture class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,7 +30,7 @@ // Linden library includes #include "llglheaders.h" -#include "llwindow.h" // getPosition() +#include "llwindow.h" // getPosition() // Viewer includes #include "llviewerwindow.h" @@ -50,16 +50,16 @@ S32 LLViewerDynamicTexture::sNumRenders = 0; //----------------------------------------------------------------------------- // LLViewerDynamicTexture() //----------------------------------------------------------------------------- -LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : - LLViewerTexture(width, height, components, FALSE), - mClamp(clamp) +LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : + LLViewerTexture(width, height, components, FALSE), + mClamp(clamp) { - llassert((1 <= components) && (components <= 4)); + llassert((1 <= components) && (components <= 4)); - generateGLTexture(); + generateGLTexture(); - llassert( 0 <= order && order < ORDER_COUNT ); - LLViewerDynamicTexture::sInstances[ order ].insert(this); + llassert( 0 <= order && order < ORDER_COUNT ); + LLViewerDynamicTexture::sInstances[ order ].insert(this); } //----------------------------------------------------------------------------- @@ -67,16 +67,16 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon //----------------------------------------------------------------------------- LLViewerDynamicTexture::~LLViewerDynamicTexture() { - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. - } + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. + } } -//virtual +//virtual S8 LLViewerDynamicTexture::getType() const { - return LLViewerTexture::DYNAMIC_TEXTURE ; + return LLViewerTexture::DYNAMIC_TEXTURE ; } //----------------------------------------------------------------------------- @@ -84,25 +84,25 @@ S8 LLViewerDynamicTexture::getType() const //----------------------------------------------------------------------------- void LLViewerDynamicTexture::generateGLTexture() { - LLViewerTexture::generateGLTexture() ; - generateGLTexture(-1, 0, 0, FALSE); + LLViewerTexture::generateGLTexture() ; + generateGLTexture(-1, 0, 0, FALSE); } void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { - if (mComponents < 1 || mComponents > 4) - { - LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL; - } - - LLPointer raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents); - if (internal_format >= 0) - { - setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); - } - createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX); - setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); - mGLTexturep->setGLTextureCreated(false); + if (mComponents < 1 || mComponents > 4) + { + LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL; + } + + LLPointer raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents); + if (internal_format >= 0) + { + setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); + } + createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX); + setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); + mGLTexturep->setGLTextureCreated(false); } //----------------------------------------------------------------------------- @@ -110,7 +110,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum //----------------------------------------------------------------------------- BOOL LLViewerDynamicTexture::render() { - return FALSE; + return FALSE; } //----------------------------------------------------------------------------- @@ -121,22 +121,22 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //use the bottom left corner - mOrigin.set(0, 0); + mOrigin.set(0, 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // Set up camera - LLViewerCamera* camera = LLViewerCamera::getInstance(); - mCamera.setOrigin(*camera); - mCamera.setAxes(*camera); - mCamera.setAspect(camera->getAspect()); - mCamera.setView(camera->getView()); - mCamera.setNear(camera->getNear()); - - glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); - if (clear_depth) - { - glClear(GL_DEPTH_BUFFER_BIT); - } + // Set up camera + LLViewerCamera* camera = LLViewerCamera::getInstance(); + mCamera.setOrigin(*camera); + mCamera.setAxes(*camera); + mCamera.setAspect(camera->getAspect()); + mCamera.setView(camera->getView()); + mCamera.setNear(camera->getNear()); + + glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); + if (clear_depth) + { + glClear(GL_DEPTH_BUFFER_BIT); + } } //----------------------------------------------------------------------------- @@ -144,36 +144,36 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) //----------------------------------------------------------------------------- void LLViewerDynamicTexture::postRender(BOOL success) { - { - if (success) - { - if(mGLTexturep.isNull()) - { - generateGLTexture() ; - } - else if(!mGLTexturep->getHasGLTexture()) - { - generateGLTexture() ; - } - else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does. - { - generateGLTexture() ; - } - - success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); - } - } - - // restore viewport - gViewerWindow->setup2DViewport(); - - // restore camera - LLViewerCamera* camera = LLViewerCamera::getInstance(); - camera->setOrigin(mCamera); - camera->setAxes(mCamera); - camera->setAspect(mCamera.getAspect()); - camera->setViewNoBroadcast(mCamera.getView()); - camera->setNear(mCamera.getNear()); + { + if (success) + { + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + else if(!mGLTexturep->getHasGLTexture()) + { + generateGLTexture() ; + } + else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does. + { + generateGLTexture() ; + } + + success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); + } + } + + // restore viewport + gViewerWindow->setup2DViewport(); + + // restore camera + LLViewerCamera* camera = LLViewerCamera::getInstance(); + camera->setOrigin(mCamera); + camera->setAxes(mCamera); + camera->setAspect(mCamera.getAspect()); + camera->setViewNoBroadcast(mCamera.getView()); + camera->setNear(mCamera.getNear()); } //----------------------------------------------------------------------------- @@ -185,18 +185,18 @@ BOOL LLViewerDynamicTexture::updateAllInstances() { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; - sNumRenders = 0; - if (gGLManager.mIsDisabled) - { - return TRUE; - } + sNumRenders = 0; + if (gGLManager.mIsDisabled) + { + return TRUE; + } LLRenderTarget& bake_target = gPipeline.mAuxillaryRT.deferredScreen; - if (!bake_target.isComplete()) + if (!bake_target.isComplete()) { llassert(false); - return FALSE; + return FALSE; } llassert(bake_target.getWidth() >= LLPipeline::MAX_BAKE_WIDTH); llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH); @@ -204,47 +204,47 @@ BOOL LLViewerDynamicTexture::updateAllInstances() bake_target.bindTarget(); bake_target.clear(); - LLGLSLShader::unbind(); - LLVertexBuffer::unbind(); - - BOOL result = FALSE; - BOOL ret = FALSE ; - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); - iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) - { - LLViewerDynamicTexture *dynamicTexture = *iter; - if (dynamicTexture->needsRender()) - { + LLGLSLShader::unbind(); + LLVertexBuffer::unbind(); + + BOOL result = FALSE; + BOOL ret = FALSE ; + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) + { + LLViewerDynamicTexture *dynamicTexture = *iter; + if (dynamicTexture->needsRender()) + { llassert(dynamicTexture->getFullWidth() <= LLPipeline::MAX_BAKE_WIDTH); llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH); - glClear(GL_DEPTH_BUFFER_BIT); - - gGL.color4f(1,1,1,1); + glClear(GL_DEPTH_BUFFER_BIT); + + gGL.color4f(1,1,1,1); dynamicTexture->setBoundTarget(&bake_target); - dynamicTexture->preRender(); // Must be called outside of startRender() - result = FALSE; - if (dynamicTexture->render()) - { - ret = TRUE ; - result = TRUE; - sNumRenders++; - } - gGL.flush(); - LLVertexBuffer::unbind(); - dynamicTexture->setBoundTarget(nullptr); - dynamicTexture->postRender(result); - } - } - } - - bake_target.flush(); + dynamicTexture->preRender(); // Must be called outside of startRender() + result = FALSE; + if (dynamicTexture->render()) + { + ret = TRUE ; + result = TRUE; + sNumRenders++; + } + gGL.flush(); + LLVertexBuffer::unbind(); + dynamicTexture->setBoundTarget(nullptr); + dynamicTexture->postRender(result); + } + } + } + + bake_target.flush(); gGL.flush(); - return ret; + return ret; } //----------------------------------------------------------------------------- @@ -253,15 +253,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::destroyGL() { - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); - iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) - { - LLViewerDynamicTexture *dynamicTexture = *iter; - dynamicTexture->destroyGLTexture() ; - } - } + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) + { + LLViewerDynamicTexture *dynamicTexture = *iter; + dynamicTexture->destroyGLTexture() ; + } + } } //----------------------------------------------------------------------------- @@ -270,18 +270,18 @@ void LLViewerDynamicTexture::destroyGL() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::restoreGL() { - if (gGLManager.mIsDisabled) - { - return ; - } - - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); - iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) - { - LLViewerDynamicTexture *dynamicTexture = *iter; - dynamicTexture->restoreGLTexture() ; - } - } + if (gGLManager.mIsDisabled) + { + return ; + } + + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) + { + LLViewerDynamicTexture *dynamicTexture = *iter; + dynamicTexture->restoreGLTexture() ; + } + } } diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 0b535e15b0..247a487ace 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -94,7 +94,7 @@ namespace const std::string KEY_ACTION("action"); const std::string KEY_ACTIONDATA("action_data"); const std::string KEY_EXPERIENCEID("public_id"); - const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format. + const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format. const std::string KEY_PARCELNAME("ParcelName"); // But changing these would also alter the Experience Log requirements. const std::string KEY_COUNT("Count"); @@ -370,13 +370,13 @@ namespace virtual ~LLSettingsInjected() {}; typename SETTINGT::ptr_t getSource() const { return this->mSource; } - void setSource(const typename SETTINGT::ptr_t &source) + void setSource(const typename SETTINGT::ptr_t &source) { if (source.get() == this) // do not set a source to itself. return; - this->mSource = source; - this->setDirtyFlag(true); - this->mLastSourceHash = 0; + this->mSource = source; + this->setDirtyFlag(true); + this->mLastSourceHash = 0; } virtual bool isDirty() const override { return SETTINGT::isDirty() || (this->mSource->isDirty()); } @@ -565,7 +565,7 @@ namespace if (!this->mSource) return; - // clears the dirty flag on this object. Need to prevent triggering + // clears the dirty flag on this object. Need to prevent triggering // more calls into this updateSettings LLSettingsBase::updateSettings(); @@ -824,7 +824,7 @@ const S32 LLEnvironment::NO_TRACK(-1); const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups -const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg +const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01); @@ -929,9 +929,9 @@ bool LLEnvironment::canEdit() const return true; } -LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const -{ - LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky(); +LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const +{ + LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky(); if (!psky && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT) { @@ -947,9 +947,9 @@ LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const return psky; } -LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const +LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const { - LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater(); + LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater(); if (!pwater && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT) { @@ -1235,7 +1235,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm } } } - + if (fixed.second) { logEnvironment(env, fixed.second, env_version); @@ -1531,12 +1531,12 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f { if (transition != TRANSITION_INSTANT) { - DayInstance::ptr_t trans = std::make_shared( - mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition); - - trans->animate(); - - mCurrentEnvironment = trans; + DayInstance::ptr_t trans = std::make_shared( + mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition); + + trans->animate(); + + mCurrentEnvironment = trans; } else { @@ -1696,12 +1696,12 @@ void LLEnvironment::update(const LLViewerCamera * cam) void LLEnvironment::updateCloudScroll() { - // This is a function of the environment rather than the sky, since it should + // This is a function of the environment rather than the sky, since it should // persist through sky transitions. static LLTimer s_cloud_timer; F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64(); - + if (mCurrentEnvironment->getSky() && !mCloudScrollPaused) { LLVector2 rate = mCurrentEnvironment->getSky()->getCloudScrollRate(); @@ -1786,7 +1786,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con }; switch (it.second.getShaderKey()) - { + { case LLShaderMgr::BLUE_HORIZON: case LLShaderMgr::BLUE_DENSITY: vect4 = max_vec(vect4); @@ -2188,7 +2188,7 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf query << "&"; } if (track_no != NO_TRACK) - { + { query << "trackno=" << track_no; } url += query.str(); @@ -2271,7 +2271,7 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url); // results that come back may contain the new settings - LLSD notify; + LLSD notify; LLSD httpResults = result["http_result"]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -2551,7 +2551,7 @@ void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos) S32 LLEnvironment::calculateSkyTrackForAltitude(F64 altitude) { auto it = std::find_if_not(mTrackAltitudes.begin(), mTrackAltitudes.end(), [altitude](F32 test) { return altitude > test; }); - + if (it == mTrackAltitudes.begin()) return 1; else if (it == mTrackAltitudes.end()) @@ -2575,19 +2575,19 @@ void LLEnvironment::handleEnvironmentPush(LLSD &message) if (action == ACTION_CLEARENVIRONMENT) - { + { handleEnvironmentPushClear(experience_id, action_data, transition_time); } else if (action == ACTION_PUSHFULLENVIRONMENT) - { + { handleEnvironmentPushFull(experience_id, action_data, transition_time); } else if (action == ACTION_PUSHPARTIALENVIRONMENT) - { + { handleEnvironmentPushPartial(experience_id, action_data, transition_time); } else - { + { LL_WARNS("ENVIRONMENT", "GENERICMESSAGES") << "Unknown environment push action '" << action << "'" << LL_ENDL; } } @@ -2801,9 +2801,9 @@ bool LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky) mInitialized = false; bool changed = psky == nullptr || mSky == nullptr || mSky->getHash() != psky->getHash(); - + bool different_sky = mSky != psky; - + mSky = psky; mSky->mReplaced |= different_sky; mSky->update(); @@ -2938,7 +2938,7 @@ LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart mNextInstance(end), mTransitionTime(time) { - + } bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& delta) @@ -2950,14 +2950,14 @@ bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& return changed; } -void LLEnvironment::DayTransition::animate() +void LLEnvironment::DayTransition::animate() { mNextInstance->animate(); mWater = mStartWater->buildClone(); mBlenderWater = std::make_shared(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime); mBlenderWater->setOnFinished( - [this](LLSettingsBlender::ptr_t blender) { + [this](LLSettingsBlender::ptr_t blender) { mBlenderWater.reset(); if (!mBlenderSky && !mBlenderWater) @@ -3366,8 +3366,8 @@ namespace return changed; } - void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday) - { + void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday) + { mBaseDayInstance = baseday; if (mSkyExperience.isNull()) @@ -3576,7 +3576,7 @@ namespace mBlenderSky = std::make_shared(target_sky, start_sky, psky, transition); mBlenderSky->setOnFinished( - [this, psky](LLSettingsBlender::ptr_t blender) + [this, psky](LLSettingsBlender::ptr_t blender) { mBlenderSky.reset(); mInjectedSky->setSource(psky); @@ -3600,7 +3600,7 @@ namespace return; } if (transition == LLEnvironment::TRANSITION_INSTANT) - { + { mBlenderWater.reset(); mInjectedWater->setSource(pwater); } @@ -3612,7 +3612,7 @@ namespace mBlenderWater = std::make_shared(scratch_Water, start_Water, pwater, transition); mBlenderWater->setOnFinished( - [this, pwater](LLSettingsBlender::ptr_t blender) + [this, pwater](LLSettingsBlender::ptr_t blender) { mBlenderWater.reset(); mInjectedWater->setSource(pwater); @@ -3633,7 +3633,7 @@ namespace LLEnvironment::EnvSelection_t base_env(mBaseDayInstance->getEnvironmentSelection()); LLEnvironment::DayInstance::ptr_t nextbase = LLEnvironment::instance().getSharedEnvironmentInstance(); - if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) || + if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) || (!mSkyExperience.isNull() && !mWaterExperience.isNull())) { // base instance completely overridden, or not changed no transition will happen return; @@ -3665,7 +3665,7 @@ namespace void DayInjection::checkExperience() { if ((!mDayExperience.isNull()) && (mSkyExperience != mDayExperience) && (mWaterExperience != mDayExperience)) - { // There was a day experience but we've replaced it with a water and a sky experience. + { // There was a day experience but we've replaced it with a water and a sky experience. mDayExperience.setNull(); mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance(); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index ccee57cf69..0b1ceaa977 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llface.cpp * @brief LLFace class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -75,49 +75,49 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE /* For each vertex, given: - B - binormal - T - tangent - N - normal - P - position + B - binormal + T - tangent + N - normal + P - position The resulting texture coordinate is: - u = 2(B dot P) - v = 2(T dot P) + u = 2(B dot P) + v = 2(T dot P) */ void planarProjection(LLVector2 &tc, const LLVector4a& normal, - const LLVector4a ¢er, const LLVector4a& vec) -{ - LLVector4a binormal; - F32 d = normal[0]; - - if (d >= 0.5f || d <= -0.5f) - { - if (d < 0) - { - binormal.set(0,-1,0); - } - else - { - binormal.set(0, 1, 0); - } - } - else - { + const LLVector4a ¢er, const LLVector4a& vec) +{ + LLVector4a binormal; + F32 d = normal[0]; + + if (d >= 0.5f || d <= -0.5f) + { + if (d < 0) + { + binormal.set(0,-1,0); + } + else + { + binormal.set(0, 1, 0); + } + } + else + { if (normal[1] > 0) - { - binormal.set(-1,0,0); - } - else - { - binormal.set(1,0,0); - } - } - LLVector4a tangent; - tangent.setCross3(binormal,normal); - - tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f); - tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f); + { + binormal.set(-1,0,0); + } + else + { + binormal.set(1,0,0); + } + } + LLVector4a tangent; + tangent.setCross3(binormal,normal); + + tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f); + tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f); } //////////////////// @@ -128,174 +128,174 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal, void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - mLastUpdateTime = gFrameTimeSeconds; - mLastMoveTime = 0.f; - mLastSkinTime = gFrameTimeSeconds; - mVSize = 0.f; - mPixelArea = 16.f; - mState = GLOBAL; - mDrawPoolp = NULL; - mPoolType = 0; - mCenterLocal = objp->getPosition(); - mCenterAgent = drawablep->getPositionAgent(); - mDistance = 0.f; - - mGeomCount = 0; - mGeomIndex = 0; - mIndicesCount = 0; - - //special value to indicate uninitialized position - mIndicesIndex = 0xFFFFFFFF; - - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - mIndexInTex[i] = 0; - mTexture[i] = NULL; - } - - mTEOffset = -1; - mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES; - - setDrawable(drawablep); - mVObjp = objp; - - mReferenceIndex = -1; - - mTextureMatrix = NULL; - mDrawInfo = NULL; - - mFaceColor = LLColor4(1,0,0,1); - - mImportanceToCamera = 0.f ; - mBoundingSphereRadius = 0.0f ; - - mHasMedia = false ; - mIsMediaAllowed = true; + mLastUpdateTime = gFrameTimeSeconds; + mLastMoveTime = 0.f; + mLastSkinTime = gFrameTimeSeconds; + mVSize = 0.f; + mPixelArea = 16.f; + mState = GLOBAL; + mDrawPoolp = NULL; + mPoolType = 0; + mCenterLocal = objp->getPosition(); + mCenterAgent = drawablep->getPositionAgent(); + mDistance = 0.f; + + mGeomCount = 0; + mGeomIndex = 0; + mIndicesCount = 0; + + //special value to indicate uninitialized position + mIndicesIndex = 0xFFFFFFFF; + + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + mIndexInTex[i] = 0; + mTexture[i] = NULL; + } + + mTEOffset = -1; + mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES; + + setDrawable(drawablep); + mVObjp = objp; + + mReferenceIndex = -1; + + mTextureMatrix = NULL; + mDrawInfo = NULL; + + mFaceColor = LLColor4(1,0,0,1); + + mImportanceToCamera = 0.f ; + mBoundingSphereRadius = 0.0f ; + + mHasMedia = false ; + mIsMediaAllowed = true; } void LLFace::destroy() { - if (gDebugGL) - { - gPipeline.checkReferences(this); - } - - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - if(mTexture[i].notNull()) - { - mTexture[i]->removeFace(i, this) ; - mTexture[i] = NULL; - } - } - - if (isState(LLFace::PARTICLE)) - { - clearState(LLFace::PARTICLE); - } - - if (mDrawPoolp) - { - mDrawPoolp->removeFace(this); - mDrawPoolp = NULL; - } - - if (mTextureMatrix) - { - delete mTextureMatrix; - mTextureMatrix = NULL; - - if (mDrawablep) - { - LLSpatialGroup* group = mDrawablep->getSpatialGroup(); - if (group) - { - group->dirtyGeom(); - gPipeline.markRebuild(group); - } - } - } - - setDrawInfo(NULL); - - mDrawablep = NULL; - mVObjp = NULL; + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + if(mTexture[i].notNull()) + { + mTexture[i]->removeFace(i, this) ; + mTexture[i] = NULL; + } + } + + if (isState(LLFace::PARTICLE)) + { + clearState(LLFace::PARTICLE); + } + + if (mDrawPoolp) + { + mDrawPoolp->removeFace(this); + mDrawPoolp = NULL; + } + + if (mTextureMatrix) + { + delete mTextureMatrix; + mTextureMatrix = NULL; + + if (mDrawablep) + { + LLSpatialGroup* group = mDrawablep->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + gPipeline.markRebuild(group); + } + } + } + + setDrawInfo(NULL); + + mDrawablep = NULL; + mVObjp = NULL; } void LLFace::setWorldMatrix(const LLMatrix4 &mat) { - LL_ERRS() << "Faces on this drawable are not independently modifiable\n" << LL_ENDL; + LL_ERRS() << "Faces on this drawable are not independently modifiable\n" << LL_ENDL; } void LLFace::setPool(LLFacePool* pool) { - mDrawPoolp = pool; + mDrawPoolp = pool; } void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - if (!new_pool) - { - LL_ERRS() << "Setting pool to null!" << LL_ENDL; - } - - if (new_pool != mDrawPoolp) - { - // Remove from old pool - if (mDrawPoolp) - { - mDrawPoolp->removeFace(this); - - if (mDrawablep) - { - gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL); - } - } - mGeomIndex = 0; - - // Add to new pool - if (new_pool) - { - new_pool->addFace(this); - } - mDrawPoolp = new_pool; - } - - setTexture(texturep) ; + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + + if (!new_pool) + { + LL_ERRS() << "Setting pool to null!" << LL_ENDL; + } + + if (new_pool != mDrawPoolp) + { + // Remove from old pool + if (mDrawPoolp) + { + mDrawPoolp->removeFace(this); + + if (mDrawablep) + { + gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL); + } + } + mGeomIndex = 0; + + // Add to new pool + if (new_pool) + { + new_pool->addFace(this); + } + mDrawPoolp = new_pool; + } + + setTexture(texturep) ; } -void LLFace::setTexture(U32 ch, LLViewerTexture* tex) +void LLFace::setTexture(U32 ch, LLViewerTexture* tex) { - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - - if(mTexture[ch] == tex) - { - return ; - } - - if(mTexture[ch].notNull()) - { - mTexture[ch]->removeFace(ch, this) ; - } - - if(tex) - { - tex->addFace(ch, this) ; - } - - mTexture[ch] = tex ; + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + + if(mTexture[ch] == tex) + { + return ; + } + + if(mTexture[ch].notNull()) + { + mTexture[ch]->removeFace(ch, this) ; + } + + if(tex) + { + tex->addFace(ch, this) ; + } + + mTexture[ch] = tex ; } -void LLFace::setTexture(LLViewerTexture* tex) +void LLFace::setTexture(LLViewerTexture* tex) { - setDiffuseMap(tex); + setDiffuseMap(tex); } void LLFace::setDiffuseMap(LLViewerTexture* tex) { - setTexture(LLRender::DIFFUSE_MAP, tex); + setTexture(LLRender::DIFFUSE_MAP, tex); } void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex) @@ -305,278 +305,278 @@ void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex) void LLFace::setNormalMap(LLViewerTexture* tex) { - setTexture(LLRender::NORMAL_MAP, tex); + setTexture(LLRender::NORMAL_MAP, tex); } void LLFace::setSpecularMap(LLViewerTexture* tex) { - setTexture(LLRender::SPECULAR_MAP, tex); + setTexture(LLRender::SPECULAR_MAP, tex); } void LLFace::dirtyTexture() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - LLDrawable* drawablep = getDrawable(); + LLDrawable* drawablep = getDrawable(); - if (mVObjp.notNull() && mVObjp->getVolume()) - { - for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) - { - if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4) - { //dirty texture on an alpha object should be treated as an LoD update - LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj) - { - vobj->mLODChanged = TRUE; + if (mVObjp.notNull() && mVObjp->getVolume()) + { + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4) + { //dirty texture on an alpha object should be treated as an LoD update + LLVOVolume* vobj = drawablep->getVOVolume(); + if (vobj) + { + vobj->mLODChanged = TRUE; vobj->updateVisualComplexity(); - } - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); - } - } - } + } + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); + } + } + } - gPipeline.markTextured(drawablep); + gPipeline.markTextured(drawablep); } void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture) { - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - if(mTexture[ch] == new_texture) - { - return ; - } + if(mTexture[ch] == new_texture) + { + return ; + } - if(!new_texture) - { - LL_ERRS() << "Can not switch to a null texture." << LL_ENDL; - return; - } + if(!new_texture) + { + LL_ERRS() << "Can not switch to a null texture." << LL_ENDL; + return; + } - llassert(mTexture[ch].notNull()); + llassert(mTexture[ch].notNull()); - if (ch == LLRender::DIFFUSE_MAP) - { - getViewerObject()->changeTEImage(mTEOffset, new_texture) ; - } + if (ch == LLRender::DIFFUSE_MAP) + { + getViewerObject()->changeTEImage(mTEOffset, new_texture) ; + } - setTexture(ch, new_texture) ; - dirtyTexture(); + setTexture(ch, new_texture) ; + dirtyTexture(); } void LLFace::setTEOffset(const S32 te_offset) { - mTEOffset = te_offset; + mTEOffset = te_offset; } void LLFace::setFaceColor(const LLColor4& color) { - mFaceColor = color; - setState(USE_FACE_COLOR); + mFaceColor = color; + setState(USE_FACE_COLOR); } void LLFace::unsetFaceColor() { - clearState(USE_FACE_COLOR); + clearState(USE_FACE_COLOR); } void LLFace::setDrawable(LLDrawable *drawable) { - mDrawablep = drawable; - mXform = &drawable->mXform; + mDrawablep = drawable; + mXform = &drawable->mXform; } void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) { - if (align) - { - //allocate vertices in blocks of 4 for alignment - num_vertices = (num_vertices + 0x3) & ~0x3; - } - - if (mGeomCount != num_vertices || - mIndicesCount != num_indices) - { - mGeomCount = num_vertices; - mIndicesCount = num_indices; - mVertexBuffer = NULL; - } - - llassert(verify()); + if (align) + { + //allocate vertices in blocks of 4 for alignment + num_vertices = (num_vertices + 0x3) & ~0x3; + } + + if (mGeomCount != num_vertices || + mIndicesCount != num_indices) + { + mGeomCount = num_vertices; + mIndicesCount = num_indices; + mVertexBuffer = NULL; + } + + llassert(verify()); } -void LLFace::setGeomIndex(U16 idx) -{ - if (mGeomIndex != idx) - { - mGeomIndex = idx; - mVertexBuffer = NULL; - } +void LLFace::setGeomIndex(U16 idx) +{ + if (mGeomIndex != idx) + { + mGeomIndex = idx; + mVertexBuffer = NULL; + } } void LLFace::setTextureIndex(U8 index) { - if (index != mTextureIndex) - { - mTextureIndex = index; - - if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES) - { - mDrawablep->setState(LLDrawable::REBUILD_POSITION); - } - else - { - if (mDrawInfo && !mDrawInfo->mTextureList.empty()) - { - LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL; - } - } - } + if (index != mTextureIndex) + { + mTextureIndex = index; + + if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES) + { + mDrawablep->setState(LLDrawable::REBUILD_POSITION); + } + else + { + if (mDrawInfo && !mDrawInfo->mTextureList.empty()) + { + LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL; + } + } + } } -void LLFace::setIndicesIndex(S32 idx) -{ - if (mIndicesIndex != idx) - { - mIndicesIndex = idx; - mVertexBuffer = NULL; - } +void LLFace::setIndicesIndex(S32 idx) +{ + if (mIndicesIndex != idx) + { + mIndicesIndex = idx; + mVertexBuffer = NULL; + } } - + //============================================================================ U16 LLFace::getGeometryAvatar( - LLStrider &vertices, - LLStrider &normals, - LLStrider &tex_coords, - LLStrider &vertex_weights, - LLStrider &clothing_weights) + LLStrider &vertices, + LLStrider &normals, + LLStrider &tex_coords, + LLStrider &vertex_weights, + LLStrider &clothing_weights) { - if (mVertexBuffer.notNull()) - { - mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount); - mVertexBuffer->getNormalStrider (normals, mGeomIndex, mGeomCount); - mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex, mGeomCount); - mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount); - mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount); - } - - return mGeomIndex; + if (mVertexBuffer.notNull()) + { + mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount); + mVertexBuffer->getNormalStrider (normals, mGeomIndex, mGeomCount); + mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex, mGeomCount); + mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount); + mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount); + } + + return mGeomIndex; } U16 LLFace::getGeometry(LLStrider &vertices, LLStrider &normals, - LLStrider &tex_coords, LLStrider &indicesp) + LLStrider &tex_coords, LLStrider &indicesp) { - if (mVertexBuffer.notNull()) - { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount); - if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) - { - mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount); - } - if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0)) - { - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); - } - - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); - } - - return mGeomIndex; + if (mVertexBuffer.notNull()) + { + mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount); + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) + { + mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount); + } + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0)) + { + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + } + + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); + } + + return mGeomIndex; } void LLFace::updateCenterAgent() { - if (mDrawablep->isActive()) - { - mCenterAgent = mCenterLocal * getRenderMatrix(); - } - else - { - mCenterAgent = mCenterLocal; - } + if (mDrawablep->isActive()) + { + mCenterAgent = mCenterLocal * getRenderMatrix(); + } + else + { + mCenterAgent = mCenterLocal; + } } void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) - { - return; - } - - mDrawablep->getSpatialGroup()->rebuildGeom(); - mDrawablep->getSpatialGroup()->rebuildMesh(); - - if(mVertexBuffer.isNull()) - { - return; - } - - if (mGeomCount > 0 && mIndicesCount > 0) - { - gGL.getTexUnit(0)->bind(imagep); - - gGL.pushMatrix(); - if (mDrawablep->isActive()) - { - gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); - } - else - { - gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); - } - - gGL.diffuseColor4fv(color.mV); - - if (mDrawablep->isState(LLDrawable::RIGGED)) - { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) + { + return; + } + + mDrawablep->getSpatialGroup()->rebuildGeom(); + mDrawablep->getSpatialGroup()->rebuildMesh(); + + if(mVertexBuffer.isNull()) + { + return; + } + + if (mGeomCount > 0 && mIndicesCount > 0) + { + gGL.getTexUnit(0)->bind(imagep); + + gGL.pushMatrix(); + if (mDrawablep->isActive()) + { + gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); + } + else + { + gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); + } + + gGL.diffuseColor4fv(color.mV); + + if (mDrawablep->isState(LLDrawable::RIGGED)) + { #if 0 // TODO -- there is no way this won't destroy our GL machine as implemented, rewrite it to not rely on software skinning - LLVOVolume* volume = mDrawablep->getVOVolume(); - if (volume) - { - LLRiggedVolume* rigged = volume->getRiggedVolume(); - if (rigged) - { + LLVOVolume* volume = mDrawablep->getVOVolume(); + if (volume) + { + LLRiggedVolume* rigged = volume->getRiggedVolume(); + if (rigged) + { // called when selecting a face during edit of a mesh object - LLGLEnable offset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.f, -1.f); - gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); - const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); - LLVertexBuffer::unbind(); - glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); - if (vol_face.mTexCoords) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); - } - gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } + LLGLEnable offset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.f, -1.f); + gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); + const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); + if (vol_face.mTexCoords) + { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); + } + gGL.syncMatrices(); + glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } #endif - } - else - { - // cheaters sometimes prosper... - // - mVertexBuffer->setBuffer(); - mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); - } - - gGL.popMatrix(); - } + } + else + { + // cheaters sometimes prosper... + // + mVertexBuffer->setBuffer(); + mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + } + + gGL.popMatrix(); + } } void renderFace(LLDrawable* drawable, LLFace *face) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) @@ -646,234 +646,234 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram void LLFace::setDrawInfo(LLDrawInfo* draw_info) { - mDrawInfo = draw_info; + mDrawInfo = draw_info; } void LLFace::printDebugInfo() const { - LLFacePool *poolp = getPool(); - LL_INFOS() << "Object: " << getViewerObject()->mID << LL_ENDL; - if (getDrawable()) - { - LL_INFOS() << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << LL_ENDL; - } - if (getTexture()) - { - LL_INFOS() << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << LL_ENDL; - } - else - { - LL_INFOS() << "No texture: " << LL_ENDL; - } - - LL_INFOS() << "Face: " << this << LL_ENDL; - LL_INFOS() << "State: " << getState() << LL_ENDL; - LL_INFOS() << "Geom Index Data:" << LL_ENDL; - LL_INFOS() << "--------------------" << LL_ENDL; - LL_INFOS() << "GI: " << mGeomIndex << " Count:" << mGeomCount << LL_ENDL; - LL_INFOS() << "Face Index Data:" << LL_ENDL; - LL_INFOS() << "--------------------" << LL_ENDL; - LL_INFOS() << "II: " << mIndicesIndex << " Count:" << mIndicesCount << LL_ENDL; - LL_INFOS() << LL_ENDL; - - if (poolp) - { - poolp->printDebugInfo(); - - S32 pool_references = 0; - for (std::vector::iterator iter = poolp->mReferences.begin(); - iter != poolp->mReferences.end(); iter++) - { - LLFace *facep = *iter; - if (facep == this) - { - LL_INFOS() << "Pool reference: " << pool_references << LL_ENDL; - pool_references++; - } - } - - if (pool_references != 1) - { - LL_INFOS() << "Incorrect number of pool references!" << LL_ENDL; - } - } + LLFacePool *poolp = getPool(); + LL_INFOS() << "Object: " << getViewerObject()->mID << LL_ENDL; + if (getDrawable()) + { + LL_INFOS() << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << LL_ENDL; + } + if (getTexture()) + { + LL_INFOS() << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << LL_ENDL; + } + else + { + LL_INFOS() << "No texture: " << LL_ENDL; + } + + LL_INFOS() << "Face: " << this << LL_ENDL; + LL_INFOS() << "State: " << getState() << LL_ENDL; + LL_INFOS() << "Geom Index Data:" << LL_ENDL; + LL_INFOS() << "--------------------" << LL_ENDL; + LL_INFOS() << "GI: " << mGeomIndex << " Count:" << mGeomCount << LL_ENDL; + LL_INFOS() << "Face Index Data:" << LL_ENDL; + LL_INFOS() << "--------------------" << LL_ENDL; + LL_INFOS() << "II: " << mIndicesIndex << " Count:" << mIndicesCount << LL_ENDL; + LL_INFOS() << LL_ENDL; + + if (poolp) + { + poolp->printDebugInfo(); + + S32 pool_references = 0; + for (std::vector::iterator iter = poolp->mReferences.begin(); + iter != poolp->mReferences.end(); iter++) + { + LLFace *facep = *iter; + if (facep == this) + { + LL_INFOS() << "Pool reference: " << pool_references << LL_ENDL; + pool_references++; + } + } + + if (pool_references != 1) + { + LL_INFOS() << "Incorrect number of pool references!" << LL_ENDL; + } + } #if 0 - LL_INFOS() << "Indices:" << LL_ENDL; - LL_INFOS() << "--------------------" << LL_ENDL; - - const U32 *indicesp = getRawIndices(); - S32 indices_count = getIndicesCount(); - S32 geom_start = getGeomStart(); - - for (S32 i = 0; i < indices_count; i++) - { - LL_INFOS() << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << LL_ENDL; - } - LL_INFOS() << LL_ENDL; - - LL_INFOS() << "Vertices:" << LL_ENDL; - LL_INFOS() << "--------------------" << LL_ENDL; - for (S32 i = 0; i < mGeomCount; i++) - { - LL_INFOS() << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << LL_ENDL; - } - LL_INFOS() << LL_ENDL; + LL_INFOS() << "Indices:" << LL_ENDL; + LL_INFOS() << "--------------------" << LL_ENDL; + + const U32 *indicesp = getRawIndices(); + S32 indices_count = getIndicesCount(); + S32 geom_start = getGeomStart(); + + for (S32 i = 0; i < indices_count; i++) + { + LL_INFOS() << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << LL_ENDL; + } + LL_INFOS() << LL_ENDL; + + LL_INFOS() << "Vertices:" << LL_ENDL; + LL_INFOS() << "--------------------" << LL_ENDL; + for (S32 i = 0; i < mGeomCount; i++) + { + LL_INFOS() << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << LL_ENDL; + } + LL_INFOS() << LL_ENDL; #endif } // Transform the texture coordinates for this face. static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT) { - // New, good way - F32 s = tex_coord.mV[0]; - F32 t = tex_coord.mV[1]; + // New, good way + F32 s = tex_coord.mV[0]; + F32 t = tex_coord.mV[1]; - // Texture transforms are done about the center of the face. - s -= 0.5; - t -= 0.5; + // Texture transforms are done about the center of the face. + s -= 0.5; + t -= 0.5; - // Handle rotation - F32 temp = s; - s = s * cosAng + t * sinAng; - t = -temp * sinAng + t * cosAng; + // Handle rotation + F32 temp = s; + s = s * cosAng + t * sinAng; + t = -temp * sinAng + t * cosAng; - // Then scale - s *= magS; - t *= magT; + // Then scale + s *= magS; + t *= magT; - // Then offset - s += offS + 0.5f; - t += offT + 0.5f; + // Then offset + s += offS + 0.5f; + t += offT + 0.5f; - tex_coord.mV[0] = s; - tex_coord.mV[1] = t; + tex_coord.mV[0] = s; + tex_coord.mV[1] = t; } // Transform the texture coordinates for this face. -static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale) +static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale) { - //tex coord is two coords, - LLVector4a st; - - // Texture transforms are done about the center of the face. - st.setAdd(tex_coord, trans); - - // Handle rotation - LLVector4a rot_st; - - // - LLVector4a s0; - s0.splat(st, 0); - LLVector4a s1; - s1.splat(st, 2); - LLVector4a ss; - ss.setSelectWithMask(mask, s1, s0); - - LLVector4a a; - a.setMul(rot0, ss); - - // - LLVector4a t0; - t0.splat(st, 1); - LLVector4a t1; - t1.splat(st, 3); - LLVector4a tt; - tt.setSelectWithMask(mask, t1, t0); - - LLVector4a b; - b.setMul(rot1, tt); - - st.setAdd(a,b); - - // Then scale - st.mul(scale); - - // Then offset - tex_coord.setAdd(st, offset); + //tex coord is two coords, + LLVector4a st; + + // Texture transforms are done about the center of the face. + st.setAdd(tex_coord, trans); + + // Handle rotation + LLVector4a rot_st; + + // + LLVector4a s0; + s0.splat(st, 0); + LLVector4a s1; + s1.splat(st, 2); + LLVector4a ss; + ss.setSelectWithMask(mask, s1, s0); + + LLVector4a a; + a.setMul(rot0, ss); + + // + LLVector4a t0; + t0.splat(st, 1); + LLVector4a t1; + t1.splat(st, 3); + LLVector4a tt; + tt.setSelectWithMask(mask, t1, t0); + + LLVector4a b; + b.setMul(rot1, tt); + + st.setAdd(a,b); + + // Then scale + st.mul(scale); + + // Then offset + tex_coord.setAdd(st, offset); } bool less_than_max_mag(const LLVector4a& vec) { - LLVector4a MAX_MAG; - MAX_MAG.splat(1024.f*1024.f); + LLVector4a MAX_MAG; + MAX_MAG.splat(1024.f*1024.f); - LLVector4a val; - val.setAbs(vec); + LLVector4a val; + val.setAbs(vec); - S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; - - return lt == 0x7; + S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; + + return lt == 0x7; } BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, BOOL global_volume) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - //get bounding box - if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) - { - if (f >= volume.getNumVolumeFaces()) - { - LL_WARNS() << "Generating bounding box for invalid face index!" << LL_ENDL; - f = 0; - } - - const LLVolumeFace &face = volume.getVolumeFace(f); - - LL_DEBUGS("RiggedBox") << "updating extents for face " << f - << " starting extents " << mExtents[0] << ", " << mExtents[1] - << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + + //get bounding box + if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) + { + if (f >= volume.getNumVolumeFaces()) + { + LL_WARNS() << "Generating bounding box for invalid face index!" << LL_ENDL; + f = 0; + } + + const LLVolumeFace &face = volume.getVolumeFace(f); + + LL_DEBUGS("RiggedBox") << "updating extents for face " << f + << " starting extents " << mExtents[0] << ", " << mExtents[1] + << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] << " num verts " << face.mNumVertices << LL_ENDL; // MAINT-8264 - stray vertices, especially in low LODs, cause bounding box errors. - if (face.mNumVertices < 3) + if (face.mNumVertices < 3) { - LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices " + LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices " << face.mNumVertices << " " << face.mNumIndices << " " << face.mWeights << LL_ENDL; return FALSE; } - - //VECTORIZE THIS - LLMatrix4a mat_vert; - mat_vert.loadu(mat_vert_in); + + //VECTORIZE THIS + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); LLVector4a new_extents[2]; - llassert(less_than_max_mag(face.mExtents[0])); - llassert(less_than_max_mag(face.mExtents[1])); + llassert(less_than_max_mag(face.mExtents[0])); + llassert(less_than_max_mag(face.mExtents[1])); - matMulBoundBox(mat_vert, face.mExtents, mExtents); + matMulBoundBox(mat_vert, face.mExtents, mExtents); - LL_DEBUGS("RiggedBox") << "updated extents for face " << f + LL_DEBUGS("RiggedBox") << "updated extents for face " << f << " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; - if (!mDrawablep->isActive()) - { // Shift position for region - LLVector4a offset; - offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); - mExtents[0].add(offset); - mExtents[1].add(offset); - LL_DEBUGS("RiggedBox") << "updating extents for face " << f + if (!mDrawablep->isActive()) + { // Shift position for region + LLVector4a offset; + offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); + mExtents[0].add(offset); + mExtents[1].add(offset); + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " not active, added offset " << offset << LL_ENDL; - } + } - LL_DEBUGS("RiggedBox") << "updated extents for face " << f + LL_DEBUGS("RiggedBox") << "updated extents for face " << f << " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; - LLVector4a t; - t.setAdd(mExtents[0],mExtents[1]); - t.mul(0.5f); + LLVector4a t; + t.setAdd(mExtents[0],mExtents[1]); + t.mul(0.5f); - mCenterLocal.set(t.getF32ptr()); + mCenterLocal.set(t.getF32ptr()); - t.setSub(mExtents[1],mExtents[0]); - mBoundingSphereRadius = t.getLength3().getF32()*0.5f; + t.setSub(mExtents[1],mExtents[0]); + mBoundingSphereRadius = t.getLength3().getF32()*0.5f; - updateCenterAgent(); - } + updateCenterAgent(); + } - return TRUE; + return TRUE; } @@ -885,113 +885,113 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, // with the implications. LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal) { - LLVector2 tc = surface_coord; - - const LLTextureEntry *tep = getTextureEntry(); - - if (tep == NULL) - { - // can't do much without the texture entry - return surface_coord; - } - - //VECTORIZE THIS - // see if we have a non-default mapping + LLVector2 tc = surface_coord; + + const LLTextureEntry *tep = getTextureEntry(); + + if (tep == NULL) + { + // can't do much without the texture entry + return surface_coord; + } + + //VECTORIZE THIS + // see if we have a non-default mapping U8 texgen = getTextureEntry()->getTexGen(); - if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { - LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); - - LLVector4a volume_position; - LLVector3 v_position(position.getF32ptr()); - - volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV); - - if (!mDrawablep->getVOVolume()->isVolumeGlobal()) - { - LLVector4a scale; - scale.load3(mVObjp->getScale().mV); - volume_position.mul(scale); - } - - LLVector4a volume_normal; - LLVector3 v_normal(normal.getF32ptr()); - volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV); - volume_normal.normalize3fast(); - - if (texgen == LLTextureEntry::TEX_GEN_PLANAR) - { - planarProjection(tc, volume_normal, center, volume_position); - } - } - - if (mTextureMatrix) // if we have a texture matrix, use it - { - LLVector3 tc3(tc); - tc3 = tc3 * *mTextureMatrix; - tc = LLVector2(tc3); - } - - else // otherwise use the texture entry parameters - { - xform(tc, cos(tep->getRotation()), sin(tep->getRotation()), - tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT); - } - - - return tc; + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { + LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); + + LLVector4a volume_position; + LLVector3 v_position(position.getF32ptr()); + + volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV); + + if (!mDrawablep->getVOVolume()->isVolumeGlobal()) + { + LLVector4a scale; + scale.load3(mVObjp->getScale().mV); + volume_position.mul(scale); + } + + LLVector4a volume_normal; + LLVector3 v_normal(normal.getF32ptr()); + volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV); + volume_normal.normalize3fast(); + + if (texgen == LLTextureEntry::TEX_GEN_PLANAR) + { + planarProjection(tc, volume_normal, center, volume_position); + } + } + + if (mTextureMatrix) // if we have a texture matrix, use it + { + LLVector3 tc3(tc); + tc3 = tc3 * *mTextureMatrix; + tc = LLVector2(tc3); + } + + else // otherwise use the texture entry parameters + { + xform(tc, cos(tep->getRotation()), sin(tep->getRotation()), + tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT); + } + + + return tc; } // Returns scale compared to default texgen, and face orientation as calculated // by planarProjection(). This is needed to match planar texgen parameters. void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const { - const LLMatrix4& vol_mat = getWorldMatrix(); - const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); - if (! (vf.mNormals && vf.mTangents)) - { - return; - } - const LLVector4a& normal4a = *vf.mNormals; - const LLVector4a& tangent = *vf.mTangents; - - LLVector4a binormal4a; - binormal4a.setCross3(normal4a, tangent); - binormal4a.mul(tangent.getF32ptr()[3]); - - LLVector2 projected_binormal; - planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a); - projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() - *scale = projected_binormal.length(); - // rotate binormal to match what planarProjection() thinks it is, - // then find rotation from that: - projected_binormal.normalize(); - F32 ang = acos(projected_binormal.mV[VY]); - ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang; - - //VECTORIZE THIS - LLVector3 binormal(binormal4a.getF32ptr()); - LLVector3 normal(normal4a.getF32ptr()); - binormal.rotVec(ang, normal); - LLQuaternion local_rot( binormal % normal, binormal, normal ); - *face_rot = local_rot * vol_mat.quaternion(); - *face_pos = vol_mat.getTranslation(); + const LLMatrix4& vol_mat = getWorldMatrix(); + const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); + if (! (vf.mNormals && vf.mTangents)) + { + return; + } + const LLVector4a& normal4a = *vf.mNormals; + const LLVector4a& tangent = *vf.mTangents; + + LLVector4a binormal4a; + binormal4a.setCross3(normal4a, tangent); + binormal4a.mul(tangent.getF32ptr()[3]); + + LLVector2 projected_binormal; + planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a); + projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() + *scale = projected_binormal.length(); + // rotate binormal to match what planarProjection() thinks it is, + // then find rotation from that: + projected_binormal.normalize(); + F32 ang = acos(projected_binormal.mV[VY]); + ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang; + + //VECTORIZE THIS + LLVector3 binormal(binormal4a.getF32ptr()); + LLVector3 normal(normal4a.getF32ptr()); + binormal.rotVec(ang, normal); + LLQuaternion local_rot( binormal % normal, binormal, normal ); + *face_rot = local_rot * vol_mat.quaternion(); + *face_pos = vol_mat.getTranslation(); } // Returns the necessary texture transform to align this face's TE to align_to's TE -bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset, - LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const +bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset, + LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const { - if (!align_to) - { - return false; - } - const LLTextureEntry *orig_tep = align_to->getTextureEntry(); - if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) || - (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) - { - return false; - } + if (!align_to) + { + return false; + } + const LLTextureEntry *orig_tep = align_to->getTextureEntry(); + if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) || + (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) + { + return false; + } F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f; @@ -1037,55 +1037,55 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs break; } - LLVector3 orig_pos, this_pos; - LLQuaternion orig_face_rot, this_face_rot; - F32 orig_proj_scale, this_proj_scale; - align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale); - getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale); - - // The rotation of "this face's" texture: - LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot; - LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot; - F32 x_ang, y_ang, z_ang; - this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang); - *res_st_rot = z_ang; - - // Offset and scale of "this face's" texture: - LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot; - LLVector3 st_scale(map_scaleS, map_scaleT, 1.f); - st_scale *= orig_proj_scale; - centers_dist.scaleVec(st_scale); - LLVector2 orig_st_offset(map_offsS, map_offsT); - - *res_st_offset = orig_st_offset + (LLVector2)centers_dist; - res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX]; - res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY]; - - st_scale /= this_proj_scale; - *res_st_scale = (LLVector2)st_scale; - return true; + LLVector3 orig_pos, this_pos; + LLQuaternion orig_face_rot, this_face_rot; + F32 orig_proj_scale, this_proj_scale; + align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale); + getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale); + + // The rotation of "this face's" texture: + LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot; + LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot; + F32 x_ang, y_ang, z_ang; + this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang); + *res_st_rot = z_ang; + + // Offset and scale of "this face's" texture: + LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot; + LLVector3 st_scale(map_scaleS, map_scaleT, 1.f); + st_scale *= orig_proj_scale; + centers_dist.scaleVec(st_scale); + LLVector2 orig_st_offset(map_offsS, map_offsT); + + *res_st_offset = orig_st_offset + (LLVector2)centers_dist; + res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX]; + res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY]; + + st_scale /= this_proj_scale; + *res_st_scale = (LLVector2)st_scale; + return true; } void LLFace::updateRebuildFlags() { - if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) - { //this rebuild is zero overhead (direct consequence of some change that affects this face) - mLastUpdateTime = gFrameTimeSeconds; - } - else - { //this rebuild is overhead (side effect of some change that does not affect this face) - mLastMoveTime = gFrameTimeSeconds; - } + if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) + { //this rebuild is zero overhead (direct consequence of some change that affects this face) + mLastUpdateTime = gFrameTimeSeconds; + } + else + { //this rebuild is overhead (side effect of some change that does not affect this face) + mLastMoveTime = gFrameTimeSeconds; + } } bool LLFace::canRenderAsMask() { - const LLTextureEntry* te = getTextureEntry(); - if( !te || !getViewerObject() || !getTexture() ) - { - return false; - } + const LLTextureEntry* te = getTextureEntry(); + if( !te || !getViewerObject() || !getTexture() ) + { + return false; + } if (te->getGLTFRenderMaterial()) { @@ -1102,45 +1102,45 @@ bool LLFace::canRenderAsMask() return false; } - - LLMaterial* mat = te->getMaterialParams(); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) - { - return false; - } - - if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha - (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask - getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) - { - if (getViewerObject()->isHUDAttachment() || te->getFullbright()) - { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe - return LLPipeline::sAutoMaskAlphaNonDeferred; - } - else - { - return LLPipeline::sAutoMaskAlphaDeferred; - } - } - - return false; + + LLMaterial* mat = te->getMaterialParams(); + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + { + return false; + } + + if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha + (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask + getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) + { + if (getViewerObject()->isHUDAttachment() || te->getFullbright()) + { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe + return LLPipeline::sAutoMaskAlphaNonDeferred; + } + else + { + return LLPipeline::sAutoMaskAlphaDeferred; + } + } + + return false; } //helper function for pushing primitives for transform shaders and cleaning up //uninitialized data on the tail, plus tracking number of expected primitives void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) { - if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping - { - //push source primitives - buff->drawArrays(LLRender::POINTS, 0, source_count); - U32 tail = dest_count-source_count; - for (U32 i = 0; i < tail; ++i) - { //copy last source primitive into each element in tail - buff->drawArrays(LLRender::POINTS, source_count-1, 1); - } - gPipeline.mTransformFeedbackPrimitives += dest_count; - } + if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping + { + //push source primitives + buff->drawArrays(LLRender::POINTS, 0, source_count); + U32 tail = dest_count-source_count; + for (U32 i = 0; i < tail; ++i) + { //copy last source primitive into each element in tail + buff->drawArrays(LLRender::POINTS, source_count-1, 1); + } + gPipeline.mTransformFeedbackPrimitives += dest_count; + } } BOOL LLFace::getGeometryVolume(const LLVolume& volume, @@ -1152,7 +1152,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, bool no_debug_assert) { LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - llassert(verify()); + llassert(verify()); if (face_index < 0 || face_index >= volume.getNumVolumeFaces()) { @@ -1170,163 +1170,163 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, bool rigged = isState(RIGGED); const LLVolumeFace &vf = volume.getVolumeFace(face_index); - S32 num_vertices = (S32)vf.mNumVertices; - S32 num_indices = (S32) vf.mNumIndices; - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) - { - updateRebuildFlags(); - } - - if (mVertexBuffer.notNull()) - { - if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) - { - if (gDebugGL) - { - LL_WARNS() << "Index buffer overflow!" << LL_ENDL; - LL_WARNS() << "Indices Count: " << mIndicesCount - << " VF Num Indices: " << num_indices - << " Indices Index: " << mIndicesIndex - << " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL; - LL_WARNS() << " Face Index: " << face_index - << " Pool Type: " << mPoolType << LL_ENDL; - llassert(no_debug_assert); - } - return FALSE; - } - - if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts()) - { - if (gDebugGL) - { - LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; - llassert(no_debug_assert); - } - return FALSE; - } - } - - LLStrider vert; - LLStrider tex_coords0; - LLStrider tex_coords1; - LLStrider tex_coords2; - LLStrider norm; - LLStrider colors; - LLStrider tangent; - LLStrider indicesp; - LLStrider wght; - - BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); - - BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal(); - LLVector3 scale; - if (global_volume) - { - scale.setVec(1,1,1); - } - else - { - scale = mVObjp->getScale(); - } - - bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); - bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); - bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE); - bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); - bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); - bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4); - - const LLTextureEntry *tep = mVObjp->getTE(face_index); - const U8 bump_code = tep ? tep->getBumpmap() : 0; - - BOOL is_static = mDrawablep->isStatic(); - BOOL is_global = is_static; - - LLVector3 center_sum(0.f, 0.f, 0.f); - - if (is_global) - { - setState(GLOBAL); - } - else - { - clearState(GLOBAL); - } - - LLColor4U color = tep->getColor(); + S32 num_vertices = (S32)vf.mNumVertices; + S32 num_indices = (S32) vf.mNumIndices; - if (tep->getGLTFRenderMaterial()) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) + { + updateRebuildFlags(); + } + + if (mVertexBuffer.notNull()) + { + if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) + { + if (gDebugGL) + { + LL_WARNS() << "Index buffer overflow!" << LL_ENDL; + LL_WARNS() << "Indices Count: " << mIndicesCount + << " VF Num Indices: " << num_indices + << " Indices Index: " << mIndicesIndex + << " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL; + LL_WARNS() << " Face Index: " << face_index + << " Pool Type: " << mPoolType << LL_ENDL; + llassert(no_debug_assert); + } + return FALSE; + } + + if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts()) + { + if (gDebugGL) + { + LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; + llassert(no_debug_assert); + } + return FALSE; + } + } + + LLStrider vert; + LLStrider tex_coords0; + LLStrider tex_coords1; + LLStrider tex_coords2; + LLStrider norm; + LLStrider colors; + LLStrider tangent; + LLStrider indicesp; + LLStrider wght; + + BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); + + BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal(); + LLVector3 scale; + if (global_volume) + { + scale.setVec(1,1,1); + } + else + { + scale = mVObjp->getScale(); + } + + bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); + bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); + bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE); + bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); + bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); + bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); + bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4); + + const LLTextureEntry *tep = mVObjp->getTE(face_index); + const U8 bump_code = tep ? tep->getBumpmap() : 0; + + BOOL is_static = mDrawablep->isStatic(); + BOOL is_global = is_static; + + LLVector3 center_sum(0.f, 0.f, 0.f); + + if (is_global) + { + setState(GLOBAL); + } + else + { + clearState(GLOBAL); + } + + LLColor4U color = tep->getColor(); + + if (tep->getGLTFRenderMaterial()) { color = tep->getGLTFRenderMaterial()->mBaseColor; } - if (rebuild_color) - { //decide if shiny goes in alpha channel of color - if (tep && - !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny - { - LLMaterial* mat = tep->getMaterialParams().get(); - - bool shiny_in_alpha = false; - - //store shiny in alpha if we don't have a specular map - if (!mat || mat->getSpecularID().isNull()) - { - shiny_in_alpha = true; - } - - if (shiny_in_alpha) - { - static const GLfloat SHININESS_TO_ALPHA[4] = - { - 0.0000f, - 0.25f, - 0.5f, - 0.75f - }; - - llassert(tep->getShiny() <= 3); - color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255); - } - } - } - - // INDICES - if (full_rebuild) - { + if (rebuild_color) + { //decide if shiny goes in alpha channel of color + if (tep && + !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny + { + LLMaterial* mat = tep->getMaterialParams().get(); + + bool shiny_in_alpha = false; + + //store shiny in alpha if we don't have a specular map + if (!mat || mat->getSpecularID().isNull()) + { + shiny_in_alpha = true; + } + + if (shiny_in_alpha) + { + static const GLfloat SHININESS_TO_ALPHA[4] = + { + 0.0000f, + 0.25f, + 0.5f, + 0.75f + }; + + llassert(tep->getShiny() <= 3); + color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255); + } + } + } + + // INDICES + if (full_rebuild) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices"); - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); - volatile __m128i* dst = (__m128i*) indicesp.get(); - __m128i* src = (__m128i*) vf.mIndices; - __m128i offset = _mm_set1_epi16(index_offset); + volatile __m128i* dst = (__m128i*) indicesp.get(); + __m128i* src = (__m128i*) vf.mIndices; + __m128i offset = _mm_set1_epi16(index_offset); - S32 end = num_indices/8; - - for (S32 i = 0; i < end; i++) - { - __m128i res = _mm_add_epi16(src[i], offset); - _mm_storeu_si128((__m128i*) dst++, res); - } + S32 end = num_indices/8; - { + for (S32 i = 0; i < end; i++) + { + __m128i res = _mm_add_epi16(src[i], offset); + _mm_storeu_si128((__m128i*) dst++, res); + } + + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices tail"); - U16* idx = (U16*) dst; + U16* idx = (U16*) dst; + + for (S32 i = end*8; i < num_indices; ++i) + { + *idx++ = vf.mIndices[i]+index_offset; + } + } + } - for (S32 i = end*8; i < num_indices; ++i) - { - *idx++ = vf.mIndices[i]+index_offset; - } - } - } - LLMaterial* mat = tep->getMaterialParams().get(); LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); - F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; + F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; constexpr S32 XFORM_NONE = 0; constexpr S32 XFORM_BLINNPHONG_COLOR = 1; @@ -1391,7 +1391,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } } - + const LLMeshSkinInfo* skin = nullptr; LLMatrix4a mat_vert; LLMatrix4a mat_normal; @@ -1431,334 +1431,334 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - { - //if it's not fullbright and has no normals, bake sunlight based on face normal - //bool bake_sunlight = !getTextureEntry()->getFullbright() && - // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); + { + //if it's not fullbright and has no normals, bake sunlight based on face normal + //bool bake_sunlight = !getTextureEntry()->getFullbright() && + // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - if (rebuild_tcoord) - { + if (rebuild_tcoord) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tcoord"); - - //bump setup - LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); - LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); - LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); - - LLQuaternion bump_quat; - if (mDrawablep->isActive()) - { - bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); - } - - if (bump_code) - { - mVObjp->getVolume()->genTangents(face_index); - F32 offset_multiple; - switch( bump_code ) - { - case BE_NO_BUMP: - offset_multiple = 0.f; - break; - case BE_BRIGHTNESS: - case BE_DARKNESS: - if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture()) - { - // Offset by approximately one texel - S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel(); - S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() ); - max_size <<= cur_discard; - const F32 ARTIFICIAL_OFFSET = 2.f; - offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; - } - else - { - offset_multiple = 1.f/256; - } - break; - - default: // Standard bumpmap textures. Assumed to be 256x256 - offset_multiple = 1.f / 256; - break; - } - - F32 s_scale = 1.f; - F32 t_scale = 1.f; - if( tep ) - { - tep->getScale( &s_scale, &t_scale ); - } - // Use the nudged south when coming from above sun angle, such - // that emboss mapping always shows up on the upward faces of cubes when - // it's noon (since a lot of builders build with the sun forced to noon). - LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; - LLVector3 moon_ray = gSky.mVOSkyp->getMoon().getDirection(); - LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; - - bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); - bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); - } - - U8 texgen = getTextureEntry()->getTexGen(); - if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { //planar texgen needs binormals - mVObjp->getVolume()->genTangents(face_index); - } - - U8 tex_mode = 0; - - bool tex_anim = false; - - LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; - tex_mode = vobj->mTexAnimMode; - - if (vobj->mTextureAnimp) - { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords - tex_anim = true; - } - - if (isState(TEXTURE_ANIM)) - { - if (!tex_mode) - { - clearState(TEXTURE_ANIM); - } - else - { - os = ot = 0.f; - r = 0.f; - cos_ang = 1.f; - sin_ang = 0.f; - ms = mt = 1.f; + + //bump setup + LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); + LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); + LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); + + LLQuaternion bump_quat; + if (mDrawablep->isActive()) + { + bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); + } + + if (bump_code) + { + mVObjp->getVolume()->genTangents(face_index); + F32 offset_multiple; + switch( bump_code ) + { + case BE_NO_BUMP: + offset_multiple = 0.f; + break; + case BE_BRIGHTNESS: + case BE_DARKNESS: + if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture()) + { + // Offset by approximately one texel + S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel(); + S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() ); + max_size <<= cur_discard; + const F32 ARTIFICIAL_OFFSET = 2.f; + offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; + } + else + { + offset_multiple = 1.f/256; + } + break; + + default: // Standard bumpmap textures. Assumed to be 256x256 + offset_multiple = 1.f / 256; + break; + } + + F32 s_scale = 1.f; + F32 t_scale = 1.f; + if( tep ) + { + tep->getScale( &s_scale, &t_scale ); + } + // Use the nudged south when coming from above sun angle, such + // that emboss mapping always shows up on the upward faces of cubes when + // it's noon (since a lot of builders build with the sun forced to noon). + LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; + LLVector3 moon_ray = gSky.mVOSkyp->getMoon().getDirection(); + LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + + bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); + bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); + } + + U8 texgen = getTextureEntry()->getTexGen(); + if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { //planar texgen needs binormals + mVObjp->getVolume()->genTangents(face_index); + } + + U8 tex_mode = 0; + + bool tex_anim = false; + + LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; + tex_mode = vobj->mTexAnimMode; + + if (vobj->mTextureAnimp) + { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords + tex_anim = true; + } + + if (isState(TEXTURE_ANIM)) + { + if (!tex_mode) + { + clearState(TEXTURE_ANIM); + } + else + { + os = ot = 0.f; + r = 0.f; + cos_ang = 1.f; + sin_ang = 0.f; + ms = mt = 1.f; xforms = XFORM_NONE; - } + } + + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED)) + { //don't override texture transform during tc bake + tex_mode = 0; + } + } - if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED)) - { //don't override texture transform during tc bake - tex_mode = 0; - } - } + LLVector4a scalea; + scalea.load3(scale.mV); - LLVector4a scalea; - scalea.load3(scale.mV); + bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); + if ((mat || gltf_mat) && !do_bump) + { + do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1) + || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2); + } - if ((mat || gltf_mat) && !do_bump) - { - do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1) - || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2); - } - // For GLTF materials: Transforms will be applied later - bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat; + bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat; - if (!do_bump) - { //not bump mapped, might be able to do a cheap update - mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount); + if (!do_bump) + { //not bump mapped, might be able to do a cheap update + mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount); - if (texgen != LLTextureEntry::TEX_GEN_PLANAR) - { + if (texgen != LLTextureEntry::TEX_GEN_PLANAR) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen"); - if (!do_tex_mat) - { - if (xforms == XFORM_NONE) - { + if (!do_tex_mat) + { + if (xforms == XFORM_NONE) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1"); - S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size); - } - else - { + S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size); + } + else + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 2"); - F32* dst = (F32*) tex_coords0.get(); - LLVector4a* src = (LLVector4a*) vf.mTexCoords; - - LLVector4a trans; - trans.splat(-0.5f); - - LLVector4a rot0; - rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); - - LLVector4a rot1; - rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); - - LLVector4a scale; - scale.set(ms, mt, ms, mt); - - LLVector4a offset; - offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); - - LLVector4Logical mask; - mask.clear(); - mask.setElement<2>(); - mask.setElement<3>(); - - U32 count = num_vertices/2 + num_vertices%2; - - for (S32 i = 0; i < count; i++) - { - LLVector4a res = *src++; - xform4a(res, trans, mask, rot0, rot1, offset, scale); - res.store4a(dst); - dst += 4; - } - } - } - else - { //do tex mat, no texgen, no bump - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - *tex_coords0++ = tc; - } - } - } - else - { //no bump, tex gen planar + F32* dst = (F32*) tex_coords0.get(); + LLVector4a* src = (LLVector4a*) vf.mTexCoords; + + LLVector4a trans; + trans.splat(-0.5f); + + LLVector4a rot0; + rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); + + LLVector4a rot1; + rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); + + LLVector4a scale; + scale.set(ms, mt, ms, mt); + + LLVector4a offset; + offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<2>(); + mask.setElement<3>(); + + U32 count = num_vertices/2 + num_vertices%2; + + for (S32 i = 0; i < count; i++) + { + LLVector4a res = *src++; + xform4a(res, trans, mask, rot0, rot1, offset, scale); + res.store4a(dst); + dst += 4; + } + } + } + else + { //do tex mat, no texgen, no bump + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; + *tex_coords0++ = tc; + } + } + } + else + { //no bump, tex gen planar LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen planar"); - if (do_tex_mat) - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); - planarProjection(tc, norm, center, vec); - - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - - *tex_coords0++ = tc; - } - } - else if (xforms != XFORM_NONE) - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); - planarProjection(tc, norm, center, vec); - - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - - *tex_coords0++ = tc; - } - } - else - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - LLVector4a vec = vf.mPositions[i]; - vec.mul(scalea); - planarProjection(tc, norm, center, vec); - - *tex_coords0++ = tc; - } - } - } - } - else - { //bump mapped or has material, just do the whole expensive loop + if (do_tex_mat) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + LLVector4a& center = *(vf.mCenter); + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); + planarProjection(tc, norm, center, vec); + + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; + + *tex_coords0++ = tc; + } + } + else if (xforms != XFORM_NONE) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + LLVector4a& center = *(vf.mCenter); + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); + planarProjection(tc, norm, center, vec); + + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + + *tex_coords0++ = tc; + } + } + else + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + LLVector4a& center = *(vf.mCenter); + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); + planarProjection(tc, norm, center, vec); + + *tex_coords0++ = tc; + } + } + } + } + else + { //bump mapped or has material, just do the whole expensive loop LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen default"); - std::vector bump_tc; - - if (mat && !mat->getNormalID().isNull()) - { //writing out normal and specular texture coordinates, not bump offsets - do_bump = false; - } + std::vector bump_tc; - LLStrider dst; + if (mat && !mat->getNormalID().isNull()) + { //writing out normal and specular texture coordinates, not bump offsets + do_bump = false; + } - for (U32 ch = 0; ch < 3; ++ch) - { + LLStrider dst; + + for (U32 ch = 0; ch < 3; ++ch) + { S32 xform_channel = XFORM_NONE; - switch (ch) - { - case 0: + switch (ch) + { + case 0: xform_channel = XFORM_BLINNPHONG_COLOR; - mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount); - break; - case 1: + mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount); + break; + case 1: xform_channel = XFORM_BLINNPHONG_NORMAL; - if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) - { - mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount); - if (mat && !tex_anim) - { - r = mat->getNormalRotation(); - mat->getNormalOffset(os, ot); - mat->getNormalRepeat(ms, mt); - - cos_ang = cos(r); - sin_ang = sin(r); - - } - } - else - { - continue; - } - break; - case 2: + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) + { + mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount); + if (mat && !tex_anim) + { + r = mat->getNormalRotation(); + mat->getNormalOffset(os, ot); + mat->getNormalRepeat(ms, mt); + + cos_ang = cos(r); + sin_ang = sin(r); + + } + } + else + { + continue; + } + break; + case 2: xform_channel = XFORM_BLINNPHONG_SPECULAR; - if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2)) - { - mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount); - if (mat && !tex_anim) - { - r = mat->getSpecularRotation(); - mat->getSpecularOffset(os, ot); - mat->getSpecularRepeat(ms, mt); - - cos_ang = cos(r); - sin_ang = sin(r); - } - } - else - { - continue; - } - break; - } + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2)) + { + mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount); + if (mat && !tex_anim) + { + r = mat->getSpecularRotation(); + mat->getSpecularOffset(os, ot); + mat->getSpecularRepeat(ms, mt); + + cos_ang = cos(r); + sin_ang = sin(r); + } + } + else + { + continue; + } + break; + } const bool do_xform = (xforms & xform_channel) != XFORM_NONE; - + for (S32 i = 0; i < num_vertices; i++) - { + { LLVector2 tc(vf.mTexCoords[i]); - + LLVector4a& norm = vf.mNormals[i]; - + LLVector4a& center = *(vf.mCenter); - + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { LLVector4a vec = vf.mPositions[i]; - + vec.mul(scalea); if (texgen == LLTextureEntry::TEX_GEN_PLANAR) { planarProjection(tc, norm, center, vec); - } + } } if (tex_mode && mTextureMatrix) @@ -1779,239 +1779,239 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, bump_tc.push_back(tc); } } - } + } + + if ((!mat && !gltf_mat) && do_bump) + { + mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount); - if ((!mat && !gltf_mat) && do_bump) - { - mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount); - mVObjp->getVolume()->genTangents(face_index); - for (S32 i = 0; i < num_vertices; i++) - { - LLVector4a tangent = vf.mTangents[i]; - - LLVector4a binorm; - binorm.setCross3(vf.mNormals[i], tangent); - binorm.mul(tangent.getF32ptr()[3]); - - LLMatrix4a tangent_to_object; - tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]); - LLVector4a t; - tangent_to_object.rotate(binormal_dir, t); - LLVector4a binormal; - mat_normal.rotate(t, binormal); - - //VECTORIZE THIS - if (mDrawablep->isActive()) - { - LLVector3 t; - t.set(binormal.getF32ptr()); - t *= bump_quat; - binormal.load3(t.mV); - } - - binormal.normalize3fast(); - - LLVector2 tc = bump_tc[i]; - tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); - - *tex_coords1++ = tc; - } - } - } - } - - if (rebuild_pos) - { - LLVector4a* src = vf.mPositions; - - //_mm_prefetch((char*)src, _MM_HINT_T0); - - LLVector4a* end = src+num_vertices; - //LLVector4a* end_64 = end-4; - - llassert(num_vertices > 0); - - mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount); - - - F32* dst = (F32*) vert.get(); - F32* end_f32 = dst+mGeomCount*4; - - //_mm_prefetch((char*)dst, _MM_HINT_NTA); - //_mm_prefetch((char*)src, _MM_HINT_NTA); - - //_mm_prefetch((char*)dst, _MM_HINT_NTA); - - - LLVector4a res0; //,res1,res2,res3; - - LLVector4a texIdx; - - S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; - - F32 val = 0.f; - S32* vp = (S32*) &val; - *vp = index; - - llassert(index < LLGLSLShader::sIndexedTextureChannels); - - LLVector4Logical mask; - mask.clear(); - mask.setElement<3>(); - - texIdx.set(0,0,0,val); - - LLVector4a tmp; - - - while (src < end) - { - mat_vert.affineTransform(*src++, res0); - tmp.setSelectWithMask(mask, texIdx, res0); - tmp.store4a((F32*) dst); - dst += 4; - } - - while (dst < end_f32) - { - res0.store4a((F32*) dst); - dst += 4; - } - } - - if (rebuild_normal) - { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a tangent = vf.mTangents[i]; + + LLVector4a binorm; + binorm.setCross3(vf.mNormals[i], tangent); + binorm.mul(tangent.getF32ptr()[3]); + + LLMatrix4a tangent_to_object; + tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]); + LLVector4a t; + tangent_to_object.rotate(binormal_dir, t); + LLVector4a binormal; + mat_normal.rotate(t, binormal); + + //VECTORIZE THIS + if (mDrawablep->isActive()) + { + LLVector3 t; + t.set(binormal.getF32ptr()); + t *= bump_quat; + binormal.load3(t.mV); + } + + binormal.normalize3fast(); + + LLVector2 tc = bump_tc[i]; + tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); + + *tex_coords1++ = tc; + } + } + } + } + + if (rebuild_pos) + { + LLVector4a* src = vf.mPositions; + + //_mm_prefetch((char*)src, _MM_HINT_T0); + + LLVector4a* end = src+num_vertices; + //LLVector4a* end_64 = end-4; + + llassert(num_vertices > 0); + + mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount); + + + F32* dst = (F32*) vert.get(); + F32* end_f32 = dst+mGeomCount*4; + + //_mm_prefetch((char*)dst, _MM_HINT_NTA); + //_mm_prefetch((char*)src, _MM_HINT_NTA); + + //_mm_prefetch((char*)dst, _MM_HINT_NTA); + + + LLVector4a res0; //,res1,res2,res3; + + LLVector4a texIdx; + + S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; + + F32 val = 0.f; + S32* vp = (S32*) &val; + *vp = index; + + llassert(index < LLGLSLShader::sIndexedTextureChannels); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + texIdx.set(0,0,0,val); + + LLVector4a tmp; + + + while (src < end) + { + mat_vert.affineTransform(*src++, res0); + tmp.setSelectWithMask(mask, texIdx, res0); + tmp.store4a((F32*) dst); + dst += 4; + } + + while (dst < end_f32) + { + res0.store4a((F32*) dst); + dst += 4; + } + } + + if (rebuild_normal) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - normal"); - mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount); - F32* normals = (F32*) norm.get(); - LLVector4a* src = vf.mNormals; - LLVector4a* end = src+num_vertices; - - while (src < end) - { - LLVector4a normal; - mat_normal.rotate(*src++, normal); - normal.store4a(normals); - normals += 4; - } - } - - if (rebuild_tangent) - { + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount); + F32* normals = (F32*) norm.get(); + LLVector4a* src = vf.mNormals; + LLVector4a* end = src+num_vertices; + + while (src < end) + { + LLVector4a normal; + mat_normal.rotate(*src++, normal); + normal.store4a(normals); + normals += 4; + } + } + + if (rebuild_tangent) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tangent"); - mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount); - F32* tangents = (F32*) tangent.get(); - + mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount); + F32* tangents = (F32*) tangent.get(); + mVObjp->getVolume()->genTangents(face_index); - - LLVector4Logical mask; - mask.clear(); - mask.setElement<3>(); - - LLVector4a* src = vf.mTangents; - LLVector4a* end = vf.mTangents +num_vertices; - - while (src < end) - { - LLVector4a tangent_out; - mat_normal.rotate(*src, tangent_out); - tangent_out.setSelectWithMask(mask, *src, tangent_out); - tangent_out.store4a(tangents); - - src++; - tangents += 4; - } - } - - if (rebuild_weights && vf.mWeights) - { + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + LLVector4a* src = vf.mTangents; + LLVector4a* end = vf.mTangents +num_vertices; + + while (src < end) + { + LLVector4a tangent_out; + mat_normal.rotate(*src, tangent_out); + tangent_out.setSelectWithMask(mask, *src, tangent_out); + tangent_out.store4a(tangents); + + src++; + tangents += 4; + } + } + + if (rebuild_weights && vf.mWeights) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - weight"); - mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount); - F32* weights = (F32*) wght.get(); - LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); - } + mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount); + F32* weights = (F32*) wght.get(); + LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); + } - if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) - { + if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - color"); - mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); - - LLVector4a src; - - U32 vec[4]; - vec[0] = vec[1] = vec[2] = vec[3] = color.asRGBA(); - - src.loadua((F32*) vec); - - F32* dst = (F32*) colors.get(); - S32 num_vecs = num_vertices/4; - if (num_vertices%4 > 0) - { - ++num_vecs; - } - - for (S32 i = 0; i < num_vecs; i++) - { - src.store4a(dst); - dst += 4; - } - } - - if (rebuild_emissive) - { + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); + + LLVector4a src; + + U32 vec[4]; + vec[0] = vec[1] = vec[2] = vec[3] = color.asRGBA(); + + src.loadua((F32*) vec); + + F32* dst = (F32*) colors.get(); + S32 num_vecs = num_vertices/4; + if (num_vertices%4 > 0) + { + ++num_vecs; + } + + for (S32 i = 0; i < num_vecs; i++) + { + src.store4a(dst); + dst += 4; + } + } + + if (rebuild_emissive) + { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - emissive"); - LLStrider emissive; - mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount); - - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); - - LLVector4a src; - - - LLColor4U glow4u = LLColor4U(0,0,0,glow); - - U32 glow32 = glow4u.asRGBA(); - - U32 vec[4]; - vec[0] = vec[1] = vec[2] = vec[3] = glow32; - - src.loadua((F32*) vec); - - F32* dst = (F32*) emissive.get(); - S32 num_vecs = num_vertices/4; - if (num_vertices%4 > 0) - { - ++num_vecs; - } - - for (S32 i = 0; i < num_vecs; i++) - { - src.store4a(dst); - dst += 4; - } - } - } - - if (rebuild_tcoord) - { - mTexExtents[0].setVec(0,0); - mTexExtents[1].setVec(1,1); - xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt); - xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt); - - F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ; - F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ; - mTexExtents[0][0] *= es ; - mTexExtents[1][0] *= es ; - mTexExtents[0][1] *= et ; - mTexExtents[1][1] *= et ; - } - - - return TRUE; + LLStrider emissive; + mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount); + + U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); + + LLVector4a src; + + + LLColor4U glow4u = LLColor4U(0,0,0,glow); + + U32 glow32 = glow4u.asRGBA(); + + U32 vec[4]; + vec[0] = vec[1] = vec[2] = vec[3] = glow32; + + src.loadua((F32*) vec); + + F32* dst = (F32*) emissive.get(); + S32 num_vecs = num_vertices/4; + if (num_vertices%4 > 0) + { + ++num_vecs; + } + + for (S32 i = 0; i < num_vecs; i++) + { + src.store4a(dst); + dst += 4; + } + } + } + + if (rebuild_tcoord) + { + mTexExtents[0].setVec(0,0); + mTexExtents[1].setVec(1,1); + xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt); + xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt); + + F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ; + F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ; + mTexExtents[0][0] *= es ; + mTexExtents[1][0] *= es ; + mTexExtents[0][1] *= et ; + mTexExtents[1][1] *= et ; + } + + + return TRUE; } void LLFace::renderIndexed() @@ -2024,18 +2024,18 @@ void LLFace::renderIndexed() } //check if the face has a media -BOOL LLFace::hasMedia() const +BOOL LLFace::hasMedia() const { - if(mHasMedia) - { - return TRUE ; - } - if(mTexture[LLRender::DIFFUSE_MAP].notNull()) - { - return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media - } - - return FALSE ; //no media. + if(mHasMedia) + { + return TRUE ; + } + if(mTexture[LLRender::DIFFUSE_MAP].notNull()) + { + return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media + } + + return FALSE ; //no media. } const F32 LEAST_IMPORTANCE = 0.05f ; @@ -2043,65 +2043,65 @@ const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; void LLFace::resetVirtualSize() { - setVirtualSize(0.f); - mImportanceToCamera = 0.f; + setVirtualSize(0.f); + mImportanceToCamera = 0.f; } F32 LLFace::getTextureVirtualSize() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - F32 radius; - F32 cos_angle_to_view_dir; - BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius); - - if (mPixelArea < F_ALMOST_ZERO || !in_frustum) - { - setVirtualSize(0.f) ; - return 0.f; - } - - //get area of circle in texture space - LLVector2 tdim = mTexExtents[1] - mTexExtents[0]; - F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; - if (texel_area <= 0) - { - // Probably animated, use default - texel_area = 1.f; - } - - F32 face_area; - if (mVObjp->isSculpted() && texel_area > 1.f) - { - //sculpts can break assumptions about texel area - face_area = mPixelArea; - } - else - { - //apply texel area to face area to get accurate ratio - //face_area /= llclamp(texel_area, 1.f/64.f, 16.f); - face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f); - } - - face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ; - if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. - { - if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage()) - { - face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius ); - } - } - - setVirtualSize(face_area) ; - - return face_area; + F32 radius; + F32 cos_angle_to_view_dir; + BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius); + + if (mPixelArea < F_ALMOST_ZERO || !in_frustum) + { + setVirtualSize(0.f) ; + return 0.f; + } + + //get area of circle in texture space + LLVector2 tdim = mTexExtents[1] - mTexExtents[0]; + F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; + if (texel_area <= 0) + { + // Probably animated, use default + texel_area = 1.f; + } + + F32 face_area; + if (mVObjp->isSculpted() && texel_area > 1.f) + { + //sculpts can break assumptions about texel area + face_area = mPixelArea; + } + else + { + //apply texel area to face area to get accurate ratio + //face_area /= llclamp(texel_area, 1.f/64.f, 16.f); + face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f); + } + + face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ; + if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. + { + if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage()) + { + face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius ); + } + } + + setVirtualSize(face_area) ; + + return face_area; } BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - //VECTORIZE THIS - //get area of circle around face + //VECTORIZE THIS + //get area of circle around face LLVector4a center; LLVector4a size; @@ -2127,237 +2127,237 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) center.load3(getPositionAgent().mV); size.setSub(mExtents[1], mExtents[0]); } - size.mul(0.5f); - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - - F32 size_squared = size.dot3(size).getF32(); - LLVector4a lookAt; - LLVector4a t; - t.load3(camera->getOrigin().mV); - lookAt.setSub(center, t); - - F32 dist = lookAt.getLength3().getF32(); - dist = llmax(dist-size.getLength3().getF32(), 0.001f); - //ramp down distance for nearby objects - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } - - lookAt.normalize3fast() ; - - //get area of circle around node - F32 app_angle = atanf((F32) sqrt(size_squared) / dist); - radius = app_angle*LLDrawable::sCurPixelAngle; - mPixelArea = radius*radius * 3.14159f; - LLVector4a x_axis; - x_axis.load3(camera->getXAxis().mV); - cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32(); - - //if has media, check if the face is out of the view frustum. - if(hasMedia()) - { - if(!camera->AABBInFrustum(center, size)) - { - mImportanceToCamera = 0.f ; - return false ; - } - if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum - { - cos_angle_to_view_dir = 1.0f ; - } - else - { - LLVector4a d; - d.setSub(lookAt, x_axis); - - if(dist * dist * d.dot3(d) < size_squared) - { - cos_angle_to_view_dir = 1.0f ; - } - } - } - - if(dist < mBoundingSphereRadius) //camera is very close - { - cos_angle_to_view_dir = 1.0f ; - mImportanceToCamera = 1.0f ; - } - else - { - mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; - } - - return true ; + size.mul(0.5f); + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + + F32 size_squared = size.dot3(size).getF32(); + LLVector4a lookAt; + LLVector4a t; + t.load3(camera->getOrigin().mV); + lookAt.setSub(center, t); + + F32 dist = lookAt.getLength3().getF32(); + dist = llmax(dist-size.getLength3().getF32(), 0.001f); + //ramp down distance for nearby objects + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + + lookAt.normalize3fast() ; + + //get area of circle around node + F32 app_angle = atanf((F32) sqrt(size_squared) / dist); + radius = app_angle*LLDrawable::sCurPixelAngle; + mPixelArea = radius*radius * 3.14159f; + LLVector4a x_axis; + x_axis.load3(camera->getXAxis().mV); + cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32(); + + //if has media, check if the face is out of the view frustum. + if(hasMedia()) + { + if(!camera->AABBInFrustum(center, size)) + { + mImportanceToCamera = 0.f ; + return false ; + } + if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum + { + cos_angle_to_view_dir = 1.0f ; + } + else + { + LLVector4a d; + d.setSub(lookAt, x_axis); + + if(dist * dist * d.dot3(d) < size_squared) + { + cos_angle_to_view_dir = 1.0f ; + } + } + } + + if(dist < mBoundingSphereRadius) //camera is very close + { + cos_angle_to_view_dir = 1.0f ; + mImportanceToCamera = 1.0f ; + } + else + { + mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; + } + + return true ; } //the projection of the face partially overlaps with the screen F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ) { - F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()) ; - F32 center_angle = acosf(cos_angle_to_view_dir) ; - F32 d = center_angle * LLDrawable::sCurPixelAngle ; - - if(d + radius > screen_radius + 5.f) - { - //---------------------------------------------- - //calculate the intersection area of two circles - //F32 radius_square = radius * radius ; - //F32 d_square = d * d ; - //F32 screen_radius_square = screen_radius * screen_radius ; - //face_area = - // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) + - // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) - - // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ; - //---------------------------------------------- - - //the above calculation is too expensive - //the below is a good estimation: bounding box of the bounding sphere: - F32 alpha = 0.5f * (radius + screen_radius - d) / radius ; - alpha = llclamp(alpha, 0.f, 1.f) ; - return alpha * alpha ; - } - return 1.0f ; + F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()) ; + F32 center_angle = acosf(cos_angle_to_view_dir) ; + F32 d = center_angle * LLDrawable::sCurPixelAngle ; + + if(d + radius > screen_radius + 5.f) + { + //---------------------------------------------- + //calculate the intersection area of two circles + //F32 radius_square = radius * radius ; + //F32 d_square = d * d ; + //F32 screen_radius_square = screen_radius * screen_radius ; + //face_area = + // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) + + // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) - + // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ; + //---------------------------------------------- + + //the above calculation is too expensive + //the below is a good estimation: bounding box of the bounding sphere: + F32 alpha = 0.5f * (radius + screen_radius - d) / radius ; + alpha = llclamp(alpha, 0.f, 1.f) ; + return alpha * alpha ; + } + return 1.0f ; } const S8 FACE_IMPORTANCE_LEVEL = 4 ; const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight} - {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ; + {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ; const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight} - {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ; + {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ; -//static +//static F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) { - F32 importance = 0.f ; - - if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && - dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) - { - LLViewerCamera* camera = LLViewerCamera::getInstance(); - F32 camera_moving_speed = camera->getAverageSpeed() ; - F32 camera_angular_speed = camera->getAverageAngularSpeed(); - - if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) - { - //if camera moves or rotates too fast, ignore the importance factor - return 0.f ; - } - - S32 i = 0 ; - for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ; - - for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ; - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ; - } - - return importance ; + F32 importance = 0.f ; + + if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && + dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) + { + LLViewerCamera* camera = LLViewerCamera::getInstance(); + F32 camera_moving_speed = camera->getAverageSpeed() ; + F32 camera_angular_speed = camera->getAverageAngularSpeed(); + + if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) + { + //if camera moves or rotates too fast, ignore the importance factor + return 0.f ; + } + + S32 i = 0 ; + for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); + i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; + F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ; + + for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ; + i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; + importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ; + } + + return importance ; } -//static +//static F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area) { - if(pixel_area > LLViewerTexture::sMaxSmallImageSize) - { - if(importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res. - { - static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ; - pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ; - } - else if(pixel_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. - { - if(importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res. - { - pixel_area = LLViewerTexture::sMinLargeImageSize ; - } - } - } - - return pixel_area ; + if(pixel_area > LLViewerTexture::sMaxSmallImageSize) + { + if(importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res. + { + static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ; + pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ; + } + else if(pixel_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. + { + if(importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res. + { + pixel_area = LLViewerTexture::sMinLargeImageSize ; + } + } + } + + return pixel_area ; } BOOL LLFace::verify(const U32* indices_array) const { - BOOL ok = TRUE; - - if( mVertexBuffer.isNull() ) - { //no vertex buffer, face is implicitly valid - return TRUE; - } - - // First, check whether the face data fits within the pool's range. - if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts()) - { - ok = FALSE; - LL_INFOS() << "Face references invalid vertices!" << LL_ENDL; - } - - S32 indices_count = (S32)getIndicesCount(); - - if (!indices_count) - { - return TRUE; - } - - if (indices_count > LL_MAX_INDICES_COUNT) - { - ok = FALSE; - LL_INFOS() << "Face has bogus indices count" << LL_ENDL; - } - - if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices()) - { - ok = FALSE; - LL_INFOS() << "Face references invalid indices!" << LL_ENDL; - } + BOOL ok = TRUE; + + if( mVertexBuffer.isNull() ) + { //no vertex buffer, face is implicitly valid + return TRUE; + } + + // First, check whether the face data fits within the pool's range. + if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts()) + { + ok = FALSE; + LL_INFOS() << "Face references invalid vertices!" << LL_ENDL; + } + + S32 indices_count = (S32)getIndicesCount(); + + if (!indices_count) + { + return TRUE; + } + + if (indices_count > LL_MAX_INDICES_COUNT) + { + ok = FALSE; + LL_INFOS() << "Face has bogus indices count" << LL_ENDL; + } + + if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices()) + { + ok = FALSE; + LL_INFOS() << "Face references invalid indices!" << LL_ENDL; + } #if 0 - S32 geom_start = getGeomStart(); - S32 geom_count = mGeomCount; - - const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices(); - - for (S32 i = 0; i < indices_count; i++) - { - S32 delta = indicesp[i] - geom_start; - if (0 > delta) - { - LL_WARNS() << "Face index too low!" << LL_ENDL; - LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << LL_ENDL; - ok = FALSE; - } - else if (delta >= geom_count) - { - LL_WARNS() << "Face index too high!" << LL_ENDL; - LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << LL_ENDL; - ok = FALSE; - } - } + S32 geom_start = getGeomStart(); + S32 geom_count = mGeomCount; + + const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices(); + + for (S32 i = 0; i < indices_count; i++) + { + S32 delta = indicesp[i] - geom_start; + if (0 > delta) + { + LL_WARNS() << "Face index too low!" << LL_ENDL; + LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << LL_ENDL; + ok = FALSE; + } + else if (delta >= geom_count) + { + LL_WARNS() << "Face index too high!" << LL_ENDL; + LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << LL_ENDL; + ok = FALSE; + } + } #endif - if (!ok) - { - printDebugInfo(); - } - return ok; + if (!ok) + { + printDebugInfo(); + } + return ok; } void LLFace::setViewerObject(LLViewerObject* objp) { - mVObjp = objp; + mVObjp = objp; } const LLMatrix4& LLFace::getRenderMatrix() const { - return mDrawablep->getRenderMatrix(); + return mDrawablep->getRenderMatrix(); } //============================================================================ @@ -2365,78 +2365,78 @@ const LLMatrix4& LLFace::getRenderMatrix() const S32 LLFace::getColors(LLStrider &colors) { - if (!mGeomCount) - { - return -1; - } - - // llassert(mGeomIndex >= 0); - mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); - return mGeomIndex; + if (!mGeomCount) + { + return -1; + } + + // llassert(mGeomIndex >= 0); + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); + return mGeomIndex; } -S32 LLFace::getIndices(LLStrider &indicesp) +S32 LLFace::getIndices(LLStrider &indicesp) { - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); - llassert(indicesp[0] != indicesp[1]); - return mIndicesIndex; + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); + llassert(indicesp[0] != indicesp[1]); + return mIndicesIndex; } LLVector3 LLFace::getPositionAgent() const { - if (mDrawablep->isStatic()) - { - return mCenterAgent; - } - else - { - return mCenterLocal * getRenderMatrix(); - } + if (mDrawablep->isStatic()) + { + return mCenterAgent; + } + else + { + return mCenterLocal * getRenderMatrix(); + } } LLViewerTexture* LLFace::getTexture(U32 ch) const { - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - return mTexture[ch] ; + return mTexture[ch] ; } void LLFace::setVertexBuffer(LLVertexBuffer* buffer) { - if (buffer) - { - LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize()); - } - - if (mVertexBuffer) - { - LLSculptIDSize::instance().dec(mDrawablep); - } - - mVertexBuffer = buffer; - llassert(verify()); + if (buffer) + { + LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize()); + } + + if (mVertexBuffer) + { + LLSculptIDSize::instance().dec(mDrawablep); + } + + mVertexBuffer = buffer; + llassert(verify()); } void LLFace::clearVertexBuffer() { - if (mVertexBuffer) - { - LLSculptIDSize::instance().dec(mDrawablep); - } + if (mVertexBuffer) + { + LLSculptIDSize::instance().dec(mDrawablep); + } - mVertexBuffer = NULL; + mVertexBuffer = NULL; } S32 LLFace::getRiggedIndex(U32 type) const { - if (mRiggedIndex.empty()) - { - return -1; - } + if (mRiggedIndex.empty()) + { + return -1; + } - llassert(type < mRiggedIndex.size()); + llassert(type < mRiggedIndex.size()); - return mRiggedIndex[type]; + return mRiggedIndex[type]; } U64 LLFace::getSkinHash() diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 9fff505c2a..9f12648470 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llfeaturemanager.cpp * @brief LLFeatureManager class implementation * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -71,12 +71,12 @@ const char FEATURE_TABLE_FILENAME[] = "featuretable.txt"; #if 0 // consuming code in #if 0 below #endif LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level) - : mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level) + : mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level) { } LLFeatureList::LLFeatureList(const std::string& name) - : mName(name) + : mName(name) { } @@ -86,293 +86,293 @@ LLFeatureList::~LLFeatureList() void LLFeatureList::addFeature(const std::string& name, const BOOL available, const F32 level) { - if (mFeatures.count(name)) - { - LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL; - } + if (mFeatures.count(name)) + { + LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL; + } - LLFeatureInfo fi(name, available, level); + LLFeatureInfo fi(name, available, level); LL_DEBUGS_ONCE("RenderInit") << "Feature '" << name << "' " << (available ? "" : "not " ) << "available" << " at " << level << LL_ENDL; - mFeatures[name] = fi; + mFeatures[name] = fi; } BOOL LLFeatureList::isFeatureAvailable(const std::string& name) { - if (mFeatures.count(name)) - { - return mFeatures[name].mAvailable; - } - - LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL; - - // changing this to TRUE so you have to explicitly disable - // something for it to be disabled - return TRUE; + if (mFeatures.count(name)) + { + return mFeatures[name].mAvailable; + } + + LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL; + + // changing this to TRUE so you have to explicitly disable + // something for it to be disabled + return TRUE; } F32 LLFeatureList::getRecommendedValue(const std::string& name) { - if (mFeatures.count(name) && isFeatureAvailable(name)) - { + if (mFeatures.count(name) && isFeatureAvailable(name)) + { LL_DEBUGS_ONCE("RenderInit") << "Setting '" << name << "' to recommended value " << mFeatures[name].mRecommendedLevel << LL_ENDL; - return mFeatures[name].mRecommendedLevel; - } + return mFeatures[name].mRecommendedLevel; + } - LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL; - return 0; + LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL; + return 0; } BOOL LLFeatureList::maskList(LLFeatureList &mask) { - LL_DEBUGS_ONCE() << "Masking with " << mask.mName << LL_ENDL; - // - // Lookup the specified feature mask, and overlay it on top of the - // current feature mask. - // - - LLFeatureInfo mask_fi; - - feature_map_t::iterator feature_it; - for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it) - { - mask_fi = feature_it->second; - // - // Look for the corresponding feature - // - if (!mFeatures.count(mask_fi.mName)) - { - LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL; - continue; - } - - LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName]; - if (mask_fi.mAvailable && !cur_fi.mAvailable) - { - LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL; - continue; - } - cur_fi.mAvailable = mask_fi.mAvailable; - cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel); - LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName - << " Feature " << mask_fi.mName - << " Mask: " << mask_fi.mRecommendedLevel - << " Now: " << cur_fi.mRecommendedLevel << LL_ENDL; - } - - LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl; - // Will conditionally call dump only if the above message will be logged, thanks - // to it being wrapped by the LL_DEBUGS and LL_ENDL macros. - dump(); - LL_CONT << LL_ENDL; - - return TRUE; + LL_DEBUGS_ONCE() << "Masking with " << mask.mName << LL_ENDL; + // + // Lookup the specified feature mask, and overlay it on top of the + // current feature mask. + // + + LLFeatureInfo mask_fi; + + feature_map_t::iterator feature_it; + for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it) + { + mask_fi = feature_it->second; + // + // Look for the corresponding feature + // + if (!mFeatures.count(mask_fi.mName)) + { + LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL; + continue; + } + + LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName]; + if (mask_fi.mAvailable && !cur_fi.mAvailable) + { + LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL; + continue; + } + cur_fi.mAvailable = mask_fi.mAvailable; + cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel); + LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName + << " Feature " << mask_fi.mName + << " Mask: " << mask_fi.mRecommendedLevel + << " Now: " << cur_fi.mRecommendedLevel << LL_ENDL; + } + + LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl; + // Will conditionally call dump only if the above message will be logged, thanks + // to it being wrapped by the LL_DEBUGS and LL_ENDL macros. + dump(); + LL_CONT << LL_ENDL; + + return TRUE; } void LLFeatureList::dump() { - LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL; - - LLFeatureInfo fi; - feature_map_t::iterator feature_it; - for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it) - { - fi = feature_it->second; - LL_DEBUGS("RenderInit") << "With " << mName << " feature " << fi.mName << " " << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL; - } + LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL; + + LLFeatureInfo fi; + feature_map_t::iterator feature_it; + for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it) + { + fi = feature_it->second; + LL_DEBUGS("RenderInit") << "With " << mName << " feature " << fi.mName << " " << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL; + } } static const std::vector sGraphicsLevelNames = boost::assign::list_of - ("Low") - ("LowMid") - ("Mid") - ("MidHigh") - ("High") - ("HighUltra") - ("Ultra") + ("Low") + ("LowMid") + ("Mid") + ("MidHigh") + ("High") + ("HighUltra") + ("Ultra") ; U32 LLFeatureManager::getMaxGraphicsLevel() const { - return sGraphicsLevelNames.size() - 1; + return sGraphicsLevelNames.size() - 1; } bool LLFeatureManager::isValidGraphicsLevel(U32 level) const { - return (level <= getMaxGraphicsLevel()); + return (level <= getMaxGraphicsLevel()); } std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const { - if (isValidGraphicsLevel(level)) - { - return sGraphicsLevelNames[level]; - } - return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. " - << getMaxGraphicsLevel()); + if (isValidGraphicsLevel(level)) + { + return sGraphicsLevelNames[level]; + } + return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. " + << getMaxGraphicsLevel()); } S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const { - const std::string FixedFunction("FixedFunction"); - std::string rname(name); - if (LLStringUtil::endsWith(rname, FixedFunction)) - { - // chop off any "FixedFunction" suffix - rname = rname.substr(0, rname.length() - FixedFunction.length()); - } - for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i) - { - if (sGraphicsLevelNames[i] == rname) - { - return i; - } - } - return -1; + const std::string FixedFunction("FixedFunction"); + std::string rname(name); + if (LLStringUtil::endsWith(rname, FixedFunction)) + { + // chop off any "FixedFunction" suffix + rname = rname.substr(0, rname.length() - FixedFunction.length()); + } + for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i) + { + if (sGraphicsLevelNames[i] == rname) + { + return i; + } + } + return -1; } LLFeatureList *LLFeatureManager::findMask(const std::string& name) { - if (mMaskList.count(name)) - { - return mMaskList[name]; - } + if (mMaskList.count(name)) + { + return mMaskList[name]; + } - return NULL; + return NULL; } BOOL LLFeatureManager::maskFeatures(const std::string& name) { - LLFeatureList *maskp = findMask(name); - if (!maskp) - { - LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL; - return FALSE; - } - LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL; - return maskList(*maskp); + LLFeatureList *maskp = findMask(name); + if (!maskp) + { + LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL; + return FALSE; + } + LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL; + return maskList(*maskp); } bool LLFeatureManager::loadFeatureTables() { - // *TODO - if I or anyone else adds something else to the skipped list - // make this data driven. Put it in the feature table and parse it - // correctly - mSkippedFeatures.insert("RenderAnisotropic"); - mSkippedFeatures.insert("RenderGamma"); - mSkippedFeatures.insert("RenderVBOEnable"); - mSkippedFeatures.insert("RenderFogRatio"); + // *TODO - if I or anyone else adds something else to the skipped list + // make this data driven. Put it in the feature table and parse it + // correctly + mSkippedFeatures.insert("RenderAnisotropic"); + mSkippedFeatures.insert("RenderGamma"); + mSkippedFeatures.insert("RenderVBOEnable"); + mSkippedFeatures.insert("RenderFogRatio"); - // first table is install with app - std::string app_path = gDirUtilp->getAppRODataDir(); - app_path += gDirUtilp->getDirDelimiter(); + // first table is install with app + std::string app_path = gDirUtilp->getAppRODataDir(); + app_path += gDirUtilp->getDirDelimiter(); - std::string filename; - filename = FEATURE_TABLE_FILENAME; + std::string filename; + filename = FEATURE_TABLE_FILENAME; - app_path += filename; + app_path += filename; - bool parse_ok = parseFeatureTable(app_path); + bool parse_ok = parseFeatureTable(app_path); - return parse_ok; + return parse_ok; } bool LLFeatureManager::parseFeatureTable(std::string filename) { - LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL; - - llifstream file; - std::string name; - U32 version; - - cleanupFeatureTables(); // in case an earlier attempt left partial results - file.open(filename.c_str()); /*Flawfinder: ignore*/ - - if (!file) - { - LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL; - return FALSE; - } - - // Check file version - file >> name; - if (name != "version") - { - LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL; - return false; - } - file >> version; - - mTableVersion = version; - LL_INFOS("RenderInit") << "Found feature table version " << version << LL_ENDL; - - LLFeatureList *flp = NULL; - bool parse_ok = true; - while (parse_ok && file >> name ) - { - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - - if (name.substr(0,2) == "//") - { - // This is a comment. - file.getline(buffer, MAX_STRING); - continue; - } - - if (name == "list") - { - LL_DEBUGS("RenderInit") << "Before new list" << std::endl; - if (flp) - { - flp->dump(); - } - else - { - LL_CONT << "No current list"; - } - LL_CONT << LL_ENDL; - - // It's a new mask, create it. - file >> name; - if (!mMaskList.count(name)) - { + LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL; + + llifstream file; + std::string name; + U32 version; + + cleanupFeatureTables(); // in case an earlier attempt left partial results + file.open(filename.c_str()); /*Flawfinder: ignore*/ + + if (!file) + { + LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL; + return FALSE; + } + + // Check file version + file >> name; + if (name != "version") + { + LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL; + return false; + } + file >> version; + + mTableVersion = version; + LL_INFOS("RenderInit") << "Found feature table version " << version << LL_ENDL; + + LLFeatureList *flp = NULL; + bool parse_ok = true; + while (parse_ok && file >> name ) + { + char buffer[MAX_STRING]; /*Flawfinder: ignore*/ + + if (name.substr(0,2) == "//") + { + // This is a comment. + file.getline(buffer, MAX_STRING); + continue; + } + + if (name == "list") + { + LL_DEBUGS("RenderInit") << "Before new list" << std::endl; + if (flp) + { + flp->dump(); + } + else + { + LL_CONT << "No current list"; + } + LL_CONT << LL_ENDL; + + // It's a new mask, create it. + file >> name; + if (!mMaskList.count(name)) + { flp = new LLFeatureList(name); mMaskList[name] = flp; } else { - LL_WARNS("RenderInit") << "Overriding mask '" << name << "'; this is invalid!" << LL_ENDL; - parse_ok = false; - } - } - else - { - if (flp) - { + LL_WARNS("RenderInit") << "Overriding mask '" << name << "'; this is invalid!" << LL_ENDL; + parse_ok = false; + } + } + else + { + if (flp) + { S32 available; F32 recommended; file >> available >> recommended; flp->addFeature(name, available, recommended); } - else - { - LL_WARNS("RenderInit") << "Specified parameter before keyword!" << LL_ENDL; - parse_ok = false; - } - } - } - file.close(); - - if (!parse_ok) - { - LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL; - cleanupFeatureTables(); - } - - return parse_ok; + else + { + LL_WARNS("RenderInit") << "Specified parameter before keyword!" << LL_ENDL; + parse_ok = false; + } + } + } + file.close(); + + if (!parse_ok) + { + LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL; + cleanupFeatureTables(); + } + + return parse_ok; } F32 gpu_benchmark(); @@ -382,9 +382,9 @@ F32 gpu_benchmark(); F32 logExceptionBenchmark() { // FIXME: gpu_benchmark uses many C++ classes on the stack to control state. - // SEH exceptions with our current exception handling options do not call + // SEH exceptions with our current exception handling options do not call // destructors for these classes, resulting in an undefined state should - // this handler be invoked. + // this handler be invoked. F32 gbps = -1; __try { @@ -406,25 +406,25 @@ F32 logExceptionBenchmark() bool LLFeatureManager::loadGPUClass() { - if (!gSavedSettings.getBOOL("SkipBenchmark")) - { - F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth"); - //get memory bandwidth from benchmark - F32 gbps; - try - { + if (!gSavedSettings.getBOOL("SkipBenchmark")) + { + F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth"); + //get memory bandwidth from benchmark + F32 gbps; + try + { #if LL_WINDOWS - gbps = logExceptionBenchmark(); + gbps = logExceptionBenchmark(); #else - gbps = gpu_benchmark(); + gbps = gpu_benchmark(); #endif - } - catch (const std::exception& e) - { - gbps = -1.f; - LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL; - } - + } + catch (const std::exception& e) + { + gbps = -1.f; + LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL; + } + mGPUMemoryBandwidth = gbps; // bias by CPU speed @@ -433,36 +433,36 @@ bool LLFeatureManager::loadGPUClass() F32 cpu_bias = llclamp(cpu_mhz / cpu_basis_mhz, 0.5f, 1.f); gbps *= cpu_bias; - if (gbps < 0.f) - { //couldn't bench, default to Low - #if LL_DARWIN - //GLVersion is misleading on OSX, just default to class 3 if we can't bench - LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; - mGPUClass = GPU_CLASS_3; - #else - mGPUClass = GPU_CLASS_0; - #endif - } - else if (gbps <= class1_gbps) - { - mGPUClass = GPU_CLASS_1; - } - else if (gbps <= class1_gbps *2.f) - { - mGPUClass = GPU_CLASS_2; - } - else if (gbps <= class1_gbps*4.f) - { - mGPUClass = GPU_CLASS_3; - } - else if (gbps <= class1_gbps*8.f) - { - mGPUClass = GPU_CLASS_4; - } - else - { - mGPUClass = GPU_CLASS_5; - } + if (gbps < 0.f) + { //couldn't bench, default to Low + #if LL_DARWIN + //GLVersion is misleading on OSX, just default to class 3 if we can't bench + LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; + mGPUClass = GPU_CLASS_3; + #else + mGPUClass = GPU_CLASS_0; + #endif + } + else if (gbps <= class1_gbps) + { + mGPUClass = GPU_CLASS_1; + } + else if (gbps <= class1_gbps *2.f) + { + mGPUClass = GPU_CLASS_2; + } + else if (gbps <= class1_gbps*4.f) + { + mGPUClass = GPU_CLASS_3; + } + else if (gbps <= class1_gbps*8.f) + { + mGPUClass = GPU_CLASS_4; + } + else + { + mGPUClass = GPU_CLASS_5; + } #if LL_WINDOWS const F32Gigabytes MIN_PHYSICAL_MEMORY(2); @@ -475,118 +475,118 @@ bool LLFeatureManager::loadGPUClass() mGPUClass = (EGPUClass)(mGPUClass - 1); } #endif //LL_WINDOWS - } //end if benchmark - else - { - //setting says don't benchmark MAINT-7558 + } //end if benchmark + else + { + //setting says don't benchmark MAINT-7558 LL_WARNS("RenderInit") << "Setting 'SkipBenchmark' is true; defaulting to class 1 (may be required for some GPUs)" << LL_ENDL; - - mGPUClass = GPU_CLASS_1; - } - // defaults - mGPUString = gGLManager.getRawGLString(); - mGPUSupported = TRUE; + mGPUClass = GPU_CLASS_1; + } + + // defaults + mGPUString = gGLManager.getRawGLString(); + mGPUSupported = TRUE; - return true; // indicates that a gpu value was established + return true; // indicates that a gpu value was established } void LLFeatureManager::cleanupFeatureTables() { - std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer()); - mMaskList.clear(); + std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer()); + mMaskList.clear(); } void LLFeatureManager::initSingleton() { - // load the tables - loadFeatureTables(); + // load the tables + loadFeatureTables(); - // get the gpu class - loadGPUClass(); + // get the gpu class + loadGPUClass(); - // apply the base masks, so we know if anything is disabled - applyBaseMasks(); + // apply the base masks, so we know if anything is disabled + applyBaseMasks(); } void LLFeatureManager::applyRecommendedSettings() { - // apply saved settings - // cap the level at 2 (high) - U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); - - LL_INFOS("RenderInit") << "Applying Recommended Features for level " << level << LL_ENDL; - - setGraphicsLevel(level, false); - gSavedSettings.setU32("RenderQualityPerformance", level); - - // now apply the tweaks to draw distance - // these are double negatives, because feature masks only work by - // downgrading values, so i needed to make a true value go to false - // for certain cards, thus the awkward name, "Disregard..." - if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance")) - { - gSavedSettings.setF32("RenderFarClip", 96.0f); - } - else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance")) - { - gSavedSettings.setF32("RenderFarClip", 128.0f); - } + // apply saved settings + // cap the level at 2 (high) + U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); + + LL_INFOS("RenderInit") << "Applying Recommended Features for level " << level << LL_ENDL; + + setGraphicsLevel(level, false); + gSavedSettings.setU32("RenderQualityPerformance", level); + + // now apply the tweaks to draw distance + // these are double negatives, because feature masks only work by + // downgrading values, so i needed to make a true value go to false + // for certain cards, thus the awkward name, "Disregard..." + if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance")) + { + gSavedSettings.setF32("RenderFarClip", 96.0f); + } + else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance")) + { + gSavedSettings.setF32("RenderFarClip", 128.0f); + } } void LLFeatureManager::applyFeatures(bool skipFeatures) { - // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt + // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt #ifndef LL_RELEASE_FOR_DOWNLOAD - dump(); + dump(); #endif - // scroll through all of these and set their corresponding control value - for(feature_map_t::iterator mIt = mFeatures.begin(); - mIt != mFeatures.end(); - ++mIt) - { - // skip features you want to skip - // do this for when you don't want to change certain settings - if(skipFeatures) - { - if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end()) - { - continue; - } - } - - // get the control setting - LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first); - if(ctrl == NULL) - { - LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL; - continue; - } - - // handle all the different types - if(ctrl->isType(TYPE_BOOLEAN)) - { - gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first)); - } - else if (ctrl->isType(TYPE_S32)) - { - gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first)); - } - else if (ctrl->isType(TYPE_U32)) - { - gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first)); - } - else if (ctrl->isType(TYPE_F32)) - { - gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first)); - } - else - { - LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL; - } - } + // scroll through all of these and set their corresponding control value + for(feature_map_t::iterator mIt = mFeatures.begin(); + mIt != mFeatures.end(); + ++mIt) + { + // skip features you want to skip + // do this for when you don't want to change certain settings + if(skipFeatures) + { + if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end()) + { + continue; + } + } + + // get the control setting + LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first); + if(ctrl == NULL) + { + LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL; + continue; + } + + // handle all the different types + if(ctrl->isType(TYPE_BOOLEAN)) + { + gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first)); + } + else if (ctrl->isType(TYPE_S32)) + { + gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first)); + } + else if (ctrl->isType(TYPE_U32)) + { + gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first)); + } + else if (ctrl->isType(TYPE_F32)) + { + gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first)); + } + else + { + LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL; + } + } } void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures) @@ -609,69 +609,69 @@ void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures) void LLFeatureManager::applyBaseMasks() { - // reapply masks - mFeatures.clear(); - - LLFeatureList* maskp = findMask("all"); - if(maskp == NULL) - { - LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL; - return; - } - - mFeatures = maskp->getFeatures(); - - // mask class - if (mGPUClass >= 0 && mGPUClass < 6) - { - const char* class_table[] = - { - "Class0", - "Class1", - "Class2", - "Class3", - "Class4", - "Class5", - }; - - LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL; - maskFeatures(class_table[mGPUClass]); - } - else - { - LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL; - maskFeatures("Unknown"); - } - - // now all those wacky ones - if (gGLManager.mIsNVIDIA) - { - maskFeatures("NVIDIA"); - } - if (gGLManager.mIsAMD) - { - maskFeatures("AMD"); - } - if (gGLManager.mIsIntel) - { - maskFeatures("Intel"); - } - if (gGLManager.mGLVersion < 3.f) - { - maskFeatures("OpenGLPre30"); - } - if (gGLManager.mNumTextureImageUnits <= 8) - { - maskFeatures("TexUnit8orLess"); - } - if (gGLManager.mNumTextureImageUnits <= 16) - { - maskFeatures("TexUnit16orLess"); - } - if (gGLManager.mVRAM > 512) - { - maskFeatures("VRAMGT512"); - } + // reapply masks + mFeatures.clear(); + + LLFeatureList* maskp = findMask("all"); + if(maskp == NULL) + { + LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL; + return; + } + + mFeatures = maskp->getFeatures(); + + // mask class + if (mGPUClass >= 0 && mGPUClass < 6) + { + const char* class_table[] = + { + "Class0", + "Class1", + "Class2", + "Class3", + "Class4", + "Class5", + }; + + LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL; + maskFeatures(class_table[mGPUClass]); + } + else + { + LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL; + maskFeatures("Unknown"); + } + + // now all those wacky ones + if (gGLManager.mIsNVIDIA) + { + maskFeatures("NVIDIA"); + } + if (gGLManager.mIsAMD) + { + maskFeatures("AMD"); + } + if (gGLManager.mIsIntel) + { + maskFeatures("Intel"); + } + if (gGLManager.mGLVersion < 3.f) + { + maskFeatures("OpenGLPre30"); + } + if (gGLManager.mNumTextureImageUnits <= 8) + { + maskFeatures("TexUnit8orLess"); + } + if (gGLManager.mNumTextureImageUnits <= 16) + { + maskFeatures("TexUnit16orLess"); + } + if (gGLManager.mVRAM > 512) + { + maskFeatures("VRAMGT512"); + } if (gGLManager.mVRAM < 2048) { maskFeatures("VRAMLT2GB"); @@ -681,79 +681,79 @@ void LLFeatureManager::applyBaseMasks() maskFeatures("GL3"); } - // now mask by gpu string - // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces - std::string gpustr = mGPUString; - for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter) - { - if (*iter == ' ') - { - *iter = '_'; - } - } - - //LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL; - maskFeatures(gpustr); - - if (isSafe()) - { - maskFeatures("safe"); - } + // now mask by gpu string + // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces + std::string gpustr = mGPUString; + for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter) + { + if (*iter == ' ') + { + *iter = '_'; + } + } + + //LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL; + maskFeatures(gpustr); + + if (isSafe()) + { + maskFeatures("safe"); + } } LLSD LLFeatureManager::getRecommendedSettingsMap() { - // Create the map and fill it with the hardware recommended settings. - // It's needed to create an initial Default graphics preset (MAINT-6435). - // The process is similar to the one LLFeatureManager::applyRecommendedSettings() does. - - LLSD map(LLSD::emptyMap()); - - U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); - LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL; - - std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low"); - - maskFeatures(features); - - LLControlVariable* ctrl = gSavedSettings.getControl("RenderQualityPerformance"); // include the quality value for correct preset loading - map["RenderQualityPerformance"]["Value"] = (LLSD::Integer)level; - map["RenderQualityPerformance"]["Comment"] = ctrl->getComment();; - map["RenderQualityPerformance"]["Persist"] = 1; - map["RenderQualityPerformance"]["Type"] = LLControlGroup::typeEnumToString(ctrl->type()); - - - - for (feature_map_t::iterator mIt = mFeatures.begin(); mIt != mFeatures.end(); ++mIt) - { - LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first); - if (ctrl == NULL) - { - LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL; - continue; - } - - if (ctrl->isType(TYPE_BOOLEAN)) - { - map[mIt->first]["Value"] = (LLSD::Boolean)getRecommendedValue(mIt->first); - } - else if (ctrl->isType(TYPE_S32) || ctrl->isType(TYPE_U32)) - { - map[mIt->first]["Value"] = (LLSD::Integer)getRecommendedValue(mIt->first); - } - else if (ctrl->isType(TYPE_F32)) - { - map[mIt->first]["Value"] = (LLSD::Real)getRecommendedValue(mIt->first); - } - else - { - LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL; - continue; - } - map[mIt->first]["Comment"] = ctrl->getComment();; - map[mIt->first]["Persist"] = 1; - map[mIt->first]["Type"] = LLControlGroup::typeEnumToString(ctrl->type()); - } - - return map; + // Create the map and fill it with the hardware recommended settings. + // It's needed to create an initial Default graphics preset (MAINT-6435). + // The process is similar to the one LLFeatureManager::applyRecommendedSettings() does. + + LLSD map(LLSD::emptyMap()); + + U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); + LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL; + + std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low"); + + maskFeatures(features); + + LLControlVariable* ctrl = gSavedSettings.getControl("RenderQualityPerformance"); // include the quality value for correct preset loading + map["RenderQualityPerformance"]["Value"] = (LLSD::Integer)level; + map["RenderQualityPerformance"]["Comment"] = ctrl->getComment();; + map["RenderQualityPerformance"]["Persist"] = 1; + map["RenderQualityPerformance"]["Type"] = LLControlGroup::typeEnumToString(ctrl->type()); + + + + for (feature_map_t::iterator mIt = mFeatures.begin(); mIt != mFeatures.end(); ++mIt) + { + LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first); + if (ctrl == NULL) + { + LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL; + continue; + } + + if (ctrl->isType(TYPE_BOOLEAN)) + { + map[mIt->first]["Value"] = (LLSD::Boolean)getRecommendedValue(mIt->first); + } + else if (ctrl->isType(TYPE_S32) || ctrl->isType(TYPE_U32)) + { + map[mIt->first]["Value"] = (LLSD::Integer)getRecommendedValue(mIt->first); + } + else if (ctrl->isType(TYPE_F32)) + { + map[mIt->first]["Value"] = (LLSD::Real)getRecommendedValue(mIt->first); + } + else + { + LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL; + continue; + } + map[mIt->first]["Comment"] = ctrl->getComment();; + map[mIt->first]["Persist"] = 1; + map[mIt->first]["Type"] = LLControlGroup::typeEnumToString(ctrl->type()); + } + + return map; } diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index b82172c506..96ab5da318 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llfilepicker.cpp * @brief OS-specific file picker * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,7 +34,7 @@ #include "llframetimer.h" #include "lltrans.h" #include "llviewercontrol.h" -#include "llwindow.h" // beforeDialog() +#include "llwindow.h" // beforeDialog() #if LL_SDL #include "llwindowsdl.h" // for some X/GTK utils to help with filepickers @@ -76,149 +76,149 @@ LLFilePicker LLFilePicker::sInstance; // Implementation // LLFilePicker::LLFilePicker() - : mCurrentFile(0), - mLocked(false) + : mCurrentFile(0), + mLocked(false) { - reset(); + reset(); #if LL_WINDOWS - mOFN.lStructSize = sizeof(OPENFILENAMEW); - mOFN.hwndOwner = NULL; // Set later - mOFN.hInstance = NULL; - mOFN.lpstrCustomFilter = NULL; - mOFN.nMaxCustFilter = 0; - mOFN.lpstrFile = NULL; // set in open and close - mOFN.nMaxFile = LL_MAX_PATH; - mOFN.lpstrFileTitle = NULL; - mOFN.nMaxFileTitle = 0; - mOFN.lpstrInitialDir = NULL; - mOFN.lpstrTitle = NULL; - mOFN.Flags = 0; // set in open and close - mOFN.nFileOffset = 0; - mOFN.nFileExtension = 0; - mOFN.lpstrDefExt = NULL; - mOFN.lCustData = 0L; - mOFN.lpfnHook = NULL; - mOFN.lpTemplateName = NULL; - mFilesW[0] = '\0'; + mOFN.lStructSize = sizeof(OPENFILENAMEW); + mOFN.hwndOwner = NULL; // Set later + mOFN.hInstance = NULL; + mOFN.lpstrCustomFilter = NULL; + mOFN.nMaxCustFilter = 0; + mOFN.lpstrFile = NULL; // set in open and close + mOFN.nMaxFile = LL_MAX_PATH; + mOFN.lpstrFileTitle = NULL; + mOFN.nMaxFileTitle = 0; + mOFN.lpstrInitialDir = NULL; + mOFN.lpstrTitle = NULL; + mOFN.Flags = 0; // set in open and close + mOFN.nFileOffset = 0; + mOFN.nFileExtension = 0; + mOFN.lpstrDefExt = NULL; + mOFN.lCustData = 0L; + mOFN.lpfnHook = NULL; + mOFN.lpTemplateName = NULL; + mFilesW[0] = '\0'; #elif LL_DARWIN - mPickOptions = 0; + mPickOptions = 0; #endif } LLFilePicker::~LLFilePicker() { - // nothing + // nothing } -// utility function to check if access to local file system via file browser +// utility function to check if access to local file system via file browser // is enabled and if not, tidy up and indicate we're not allowed to do this. bool LLFilePicker::check_local_file_access_enabled() { - // if local file browsing is turned off, return without opening dialog - bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled"); - if ( ! local_file_system_browsing_enabled ) - { - mFiles.clear(); - return false; - } - - return true; + // if local file browsing is turned off, return without opening dialog + bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled"); + if ( ! local_file_system_browsing_enabled ) + { + mFiles.clear(); + return false; + } + + return true; } const std::string LLFilePicker::getFirstFile() { - mCurrentFile = 0; - return getNextFile(); + mCurrentFile = 0; + return getNextFile(); } const std::string LLFilePicker::getNextFile() { - if (mCurrentFile >= getFileCount()) - { - mLocked = false; - return std::string(); - } - else - { - return mFiles[mCurrentFile++]; - } + if (mCurrentFile >= getFileCount()) + { + mLocked = false; + return std::string(); + } + else + { + return mFiles[mCurrentFile++]; + } } const std::string LLFilePicker::getCurFile() { - if (mCurrentFile >= getFileCount()) - { - mLocked = false; - return std::string(); - } - else - { - return mFiles[mCurrentFile]; - } + if (mCurrentFile >= getFileCount()) + { + mLocked = false; + return std::string(); + } + else + { + return mFiles[mCurrentFile]; + } } void LLFilePicker::reset() { - mLocked = false; - mFiles.clear(); - mCurrentFile = 0; + mLocked = false; + mFiles.clear(); + mCurrentFile = 0; } #if LL_WINDOWS BOOL LLFilePicker::setupFilter(ELoadFilter filter) { - BOOL res = TRUE; - switch (filter) - { + BOOL res = TRUE; + switch (filter) + { case FFLOAD_ALL: case FFLOAD_EXE: - mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ - SOUND_FILTER \ - IMAGE_FILTER \ - ANIM_FILTER \ - MATERIAL_FILTER \ - L"\0"; - break; - case FFLOAD_WAV: - mOFN.lpstrFilter = SOUND_FILTER \ - L"\0"; - break; - case FFLOAD_IMAGE: - mOFN.lpstrFilter = IMAGE_FILTER \ - L"\0"; - break; - case FFLOAD_ANIM: - mOFN.lpstrFilter = ANIM_FILTER \ - L"\0"; - break; - case FFLOAD_GLTF: - mOFN.lpstrFilter = GLTF_FILTER \ - L"\0"; - break; - case FFLOAD_COLLADA: - mOFN.lpstrFilter = COLLADA_FILTER \ - L"\0"; - break; - case FFLOAD_XML: - mOFN.lpstrFilter = XML_FILTER \ - L"\0"; - break; - case FFLOAD_SLOBJECT: - mOFN.lpstrFilter = SLOBJECT_FILTER \ - L"\0"; - break; - case FFLOAD_RAW: - mOFN.lpstrFilter = RAW_FILTER \ - L"\0"; - break; - case FFLOAD_MODEL: - mOFN.lpstrFilter = MODEL_FILTER \ - L"\0"; - break; + mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ + SOUND_FILTER \ + IMAGE_FILTER \ + ANIM_FILTER \ + MATERIAL_FILTER \ + L"\0"; + break; + case FFLOAD_WAV: + mOFN.lpstrFilter = SOUND_FILTER \ + L"\0"; + break; + case FFLOAD_IMAGE: + mOFN.lpstrFilter = IMAGE_FILTER \ + L"\0"; + break; + case FFLOAD_ANIM: + mOFN.lpstrFilter = ANIM_FILTER \ + L"\0"; + break; + case FFLOAD_GLTF: + mOFN.lpstrFilter = GLTF_FILTER \ + L"\0"; + break; + case FFLOAD_COLLADA: + mOFN.lpstrFilter = COLLADA_FILTER \ + L"\0"; + break; + case FFLOAD_XML: + mOFN.lpstrFilter = XML_FILTER \ + L"\0"; + break; + case FFLOAD_SLOBJECT: + mOFN.lpstrFilter = SLOBJECT_FILTER \ + L"\0"; + break; + case FFLOAD_RAW: + mOFN.lpstrFilter = RAW_FILTER \ + L"\0"; + break; + case FFLOAD_MODEL: + mOFN.lpstrFilter = MODEL_FILTER \ + L"\0"; + break; case FFLOAD_MATERIAL: mOFN.lpstrFilter = MATERIAL_FILTER \ L"\0"; @@ -233,70 +233,70 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = HDRI_FILTER \ L"\0"; break; - case FFLOAD_SCRIPT: - mOFN.lpstrFilter = SCRIPT_FILTER \ - L"\0"; - break; - case FFLOAD_DICTIONARY: - mOFN.lpstrFilter = DICTIONARY_FILTER \ - L"\0"; - break; - default: - res = FALSE; - break; - } - return res; + case FFLOAD_SCRIPT: + mOFN.lpstrFilter = SCRIPT_FILTER \ + L"\0"; + break; + case FFLOAD_DICTIONARY: + mOFN.lpstrFilter = DICTIONARY_FILTER \ + L"\0"; + break; + default: + res = FALSE; + break; + } + return res; } BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - // don't provide default file selection - mFilesW[0] = '\0'; - - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - mOFN.lpstrFile = mFilesW; - mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ; - mOFN.nFilterIndex = 1; - - setupFilter(filter); - - if (blocking) - { - // Modal, so pause agent - send_agent_pause(); - } - - reset(); - - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - success = GetOpenFileName(&mOFN); - if (success) - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - - if (blocking) - { - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - } - - return success; + if( mLocked ) + { + return FALSE; + } + BOOL success = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + // don't provide default file selection + mFilesW[0] = '\0'; + + mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); + mOFN.lpstrFile = mFilesW; + mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; + mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ; + mOFN.nFilterIndex = 1; + + setupFilter(filter); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + reset(); + + // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! + success = GetOpenFileName(&mOFN); + if (success) + { + std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + mFiles.push_back(filename); + } + + if (blocking) + { + send_agent_resume(); + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; } BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, @@ -310,79 +310,79 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) { - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - // don't provide default file selection - mFilesW[0] = '\0'; - - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - mOFN.lpstrFile = mFilesW; - mOFN.nFilterIndex = 1; - mOFN.nMaxFile = FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | - OFN_EXPLORER | OFN_ALLOWMULTISELECT; - - setupFilter(filter); - - reset(); - - if (blocking) - { - // Modal, so pause agent - send_agent_pause(); - } - - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - success = GetOpenFileName(&mOFN); // pauses until ok or cancel. - if( success ) - { - // The getopenfilename api doesn't tell us if we got more than - // one file, so we have to test manually by checking string - // lengths. - if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - else - { - mLocked = true; - WCHAR* tptrw = mFilesW; - std::string dirname; - while(1) - { - if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0' - break; - if (*tptrw == 0) - tptrw++; // shouldn't happen? - std::string filename = utf16str_to_utf8str(llutf16string(tptrw)); - if (dirname.empty()) - dirname = filename + "\\"; - else - mFiles.push_back(dirname + filename); - tptrw += wcslen(tptrw); - } - } - } - - if (blocking) - { - send_agent_resume(); - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + if( mLocked ) + { + return FALSE; + } + BOOL success = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + // don't provide default file selection + mFilesW[0] = '\0'; + + mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); + mOFN.lpstrFile = mFilesW; + mOFN.nFilterIndex = 1; + mOFN.nMaxFile = FILENAME_BUFFER_SIZE; + mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | + OFN_EXPLORER | OFN_ALLOWMULTISELECT; + + setupFilter(filter); + + reset(); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! + success = GetOpenFileName(&mOFN); // pauses until ok or cancel. + if( success ) + { + // The getopenfilename api doesn't tell us if we got more than + // one file, so we have to test manually by checking string + // lengths. + if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ + { + std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + mFiles.push_back(filename); + } + else + { + mLocked = true; + WCHAR* tptrw = mFilesW; + std::string dirname; + while(1) + { + if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0' + break; + if (*tptrw == 0) + tptrw++; // shouldn't happen? + std::string filename = utf16str_to_utf8str(llutf16string(tptrw)); + if (dirname.empty()) + dirname = filename + "\\"; + else + mFiles.push_back(dirname + filename); + tptrw += wcslen(tptrw); + } + } + } + + if (blocking) + { + send_agent_resume(); + } + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + return success; } BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, @@ -396,222 +396,222 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) { - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - mOFN.lpstrFile = mFilesW; - if (!filename.empty()) - { - llutf16string tstring = utf8str_to_utf16str(filename); - wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ - else - { - mFilesW[0] = '\0'; - } - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - - switch( filter ) - { - case FFSAVE_ALL: - mOFN.lpstrDefExt = NULL; - mOFN.lpstrFilter = - L"All Files (*.*)\0*.*\0" \ - L"WAV Sounds (*.wav)\0*.wav\0" \ - L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ - L"\0"; - break; - case FFSAVE_WAV: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"wav"; - mOFN.lpstrFilter = - L"WAV Sounds (*.wav)\0*.wav\0" \ - L"\0"; - break; - case FFSAVE_TGA: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"tga"; - mOFN.lpstrFilter = - L"Targa Images (*.tga)\0*.tga\0" \ - L"\0"; - break; - case FFSAVE_BMP: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"bmp"; - mOFN.lpstrFilter = - L"Bitmap Images (*.bmp)\0*.bmp\0" \ - L"\0"; - break; - case FFSAVE_PNG: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"png"; - mOFN.lpstrFilter = - L"PNG Images (*.png)\0*.png\0" \ - L"\0"; - break; - case FFSAVE_TGAPNG: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - //PNG by default - } - mOFN.lpstrDefExt = L"png"; - mOFN.lpstrFilter = - L"PNG Images (*.png)\0*.png\0" \ - L"Targa Images (*.tga)\0*.tga\0" \ - L"\0"; - break; - - case FFSAVE_JPEG: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"jpg"; - mOFN.lpstrFilter = - L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \ - L"\0"; - break; - case FFSAVE_AVI: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"avi"; - mOFN.lpstrFilter = - L"AVI Movie File (*.avi)\0*.avi\0" \ - L"\0"; - break; - case FFSAVE_ANIM: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"xaf"; - mOFN.lpstrFilter = - L"XAF Anim File (*.xaf)\0*.xaf\0" \ - L"\0"; - break; - case FFSAVE_GLTF: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"glb"; - mOFN.lpstrFilter = - L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \ - L"\0"; - break; - case FFSAVE_XML: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - - mOFN.lpstrDefExt = L"xml"; - mOFN.lpstrFilter = - L"XML File (*.xml)\0*.xml\0" \ - L"\0"; - break; - case FFSAVE_COLLADA: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"collada"; - mOFN.lpstrFilter = - L"COLLADA File (*.collada)\0*.collada\0" \ - L"\0"; - break; - case FFSAVE_RAW: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"raw"; - mOFN.lpstrFilter = RAW_FILTER \ - L"\0"; - break; - case FFSAVE_J2C: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"j2c"; - mOFN.lpstrFilter = - L"Compressed Images (*.j2c)\0*.j2c\0" \ - L"\0"; - break; - case FFSAVE_SCRIPT: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"txt"; - mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0"; - break; - default: - return FALSE; - } - - - mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; - - reset(); - - if (blocking) - { - // Modal, so pause agent - send_agent_pause(); - } - - { - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - try - { - success = GetSaveFileName(&mOFN); - if (success) - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - } - catch (...) - { - LOG_UNHANDLED_EXCEPTION(""); - } - gKeyboard->resetKeys(); - } - - if (blocking) - { - send_agent_resume(); - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + if( mLocked ) + { + return FALSE; + } + BOOL success = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + mOFN.lpstrFile = mFilesW; + if (!filename.empty()) + { + llutf16string tstring = utf8str_to_utf16str(filename); + wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ + else + { + mFilesW[0] = '\0'; + } + mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); + + switch( filter ) + { + case FFSAVE_ALL: + mOFN.lpstrDefExt = NULL; + mOFN.lpstrFilter = + L"All Files (*.*)\0*.*\0" \ + L"WAV Sounds (*.wav)\0*.wav\0" \ + L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ + L"\0"; + break; + case FFSAVE_WAV: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"wav"; + mOFN.lpstrFilter = + L"WAV Sounds (*.wav)\0*.wav\0" \ + L"\0"; + break; + case FFSAVE_TGA: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"tga"; + mOFN.lpstrFilter = + L"Targa Images (*.tga)\0*.tga\0" \ + L"\0"; + break; + case FFSAVE_BMP: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"bmp"; + mOFN.lpstrFilter = + L"Bitmap Images (*.bmp)\0*.bmp\0" \ + L"\0"; + break; + case FFSAVE_PNG: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"png"; + mOFN.lpstrFilter = + L"PNG Images (*.png)\0*.png\0" \ + L"\0"; + break; + case FFSAVE_TGAPNG: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + //PNG by default + } + mOFN.lpstrDefExt = L"png"; + mOFN.lpstrFilter = + L"PNG Images (*.png)\0*.png\0" \ + L"Targa Images (*.tga)\0*.tga\0" \ + L"\0"; + break; + + case FFSAVE_JPEG: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"jpg"; + mOFN.lpstrFilter = + L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \ + L"\0"; + break; + case FFSAVE_AVI: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"avi"; + mOFN.lpstrFilter = + L"AVI Movie File (*.avi)\0*.avi\0" \ + L"\0"; + break; + case FFSAVE_ANIM: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"xaf"; + mOFN.lpstrFilter = + L"XAF Anim File (*.xaf)\0*.xaf\0" \ + L"\0"; + break; + case FFSAVE_GLTF: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"glb"; + mOFN.lpstrFilter = + L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \ + L"\0"; + break; + case FFSAVE_XML: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + + mOFN.lpstrDefExt = L"xml"; + mOFN.lpstrFilter = + L"XML File (*.xml)\0*.xml\0" \ + L"\0"; + break; + case FFSAVE_COLLADA: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"collada"; + mOFN.lpstrFilter = + L"COLLADA File (*.collada)\0*.collada\0" \ + L"\0"; + break; + case FFSAVE_RAW: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"raw"; + mOFN.lpstrFilter = RAW_FILTER \ + L"\0"; + break; + case FFSAVE_J2C: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); + } + mOFN.lpstrDefExt = L"j2c"; + mOFN.lpstrFilter = + L"Compressed Images (*.j2c)\0*.j2c\0" \ + L"\0"; + break; + case FFSAVE_SCRIPT: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); + } + mOFN.lpstrDefExt = L"txt"; + mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0"; + break; + default: + return FALSE; + } + + + mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; + mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; + + reset(); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + { + // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! + try + { + success = GetSaveFileName(&mOFN); + if (success) + { + std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + mFiles.push_back(filename); + } + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION(""); + } + gKeyboard->resetKeys(); + } + + if (blocking) + { + send_agent_resume(); + } + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + return success; } BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, @@ -692,25 +692,25 @@ std::unique_ptr> LLFilePicker::navOpenFilterProc(ELoadF LL_WARNS() << "Unsupported format." << LL_ENDL; } - return allowedv; + return allowedv; } -bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) +bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) { - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return false; - } - - gViewerWindow->getWindow()->beforeDialog(); - + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + gViewerWindow->getWindow()->beforeDialog(); + std::unique_ptr> allowed_types = navOpenFilterProc(filter); - + std::unique_ptr> filev = doLoadDialog(allowed_types.get(), mPickOptions); - gViewerWindow->getWindow()->afterDialog(); + gViewerWindow->getWindow()->afterDialog(); if (filev && filev->size() > 0) @@ -718,8 +718,8 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) mFiles.insert(mFiles.end(), filev->begin(), filev->end()); return true; } - - return false; + + return false; } bool LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter, @@ -731,14 +731,14 @@ bool LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter, { return false; } - + std::unique_ptr> allowed_types=navOpenFilterProc(filter); - + doLoadDialogModeless(allowed_types.get(), mPickOptions, callback, userdata); - + return true; } @@ -792,13 +792,13 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension, creator = "\?\?\?\?"; extension = "glb"; break; - + case LLFilePicker::FFSAVE_XML: type = "\?\?\?\?"; creator = "\?\?\?\?"; extension = "xml"; break; - + case LLFilePicker::FFSAVE_RAW: type = "\?\?\?\?"; creator = "\?\?\?\?"; @@ -810,13 +810,13 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension, creator = "prvw"; extension = "j2c"; break; - + case LLFilePicker::FFSAVE_SCRIPT: type = "LSL "; creator = "\?\?\?\?"; extension = "lsl"; break; - + case LLFilePicker::FFSAVE_ALL: default: type = "\?\?\?\?"; @@ -826,34 +826,34 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension, } } -bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) +bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) { - // Setup the type, creator, and extension - std::string extension, type, creator; - + // Setup the type, creator, and extension + std::string extension, type, creator; + set_nav_save_data(filter, extension, type, creator); - + std::string namestring = filename; if (namestring.empty()) namestring="Untitled"; - - gViewerWindow->getWindow()->beforeDialog(); - // Run the dialog - std::unique_ptr filev = doSaveDialog(&namestring, + gViewerWindow->getWindow()->beforeDialog(); + + // Run the dialog + std::unique_ptr filev = doSaveDialog(&namestring, &type, &creator, &extension, mPickOptions); - gViewerWindow->getWindow()->afterDialog(); + gViewerWindow->getWindow()->afterDialog(); - if ( filev && !filev->empty() ) - { + if ( filev && !filev->empty() ) + { mFiles.push_back(*filev); - return true; + return true; } - - return false; + + return false; } bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter, @@ -863,9 +863,9 @@ bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter, { // Setup the type, creator, and extension std::string extension, type, creator; - + set_nav_save_data(filter, extension, type, creator); - + std::string namestring = filename; if (namestring.empty()) namestring="Untitled"; @@ -882,57 +882,57 @@ bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter, BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { - if( mLocked ) - return FALSE; + if( mLocked ) + return FALSE; - BOOL success = FALSE; + BOOL success = FALSE; - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + reset(); - reset(); - mPickOptions &= ~F_MULTIPLE; mPickOptions |= F_FILE; - - if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. + + if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. { mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY ); mPickOptions &= ~F_FILE; } - if (filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful - { + if (filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful + { mPickOptions |= F_NAV_SUPPORT; - } - - if (blocking) // always true for linux/mac - { - // Modal, so pause agent - send_agent_pause(); - } - - - success = doNavChooseDialog(filter); - - if (success) - { - if (!getFileCount()) - success = false; - } - - if (blocking) - { - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - } - - return success; + } + + if (blocking) // always true for linux/mac + { + // Modal, so pause agent + send_agent_pause(); + } + + + success = doNavChooseDialog(filter); + + if (success) + { + if (!getFileCount()) + success = false; + } + + if (blocking) + { + send_agent_resume(); + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; } @@ -950,10 +950,10 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, } reset(); - + mPickOptions &= ~F_MULTIPLE; mPickOptions |= F_FILE; - + if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. { @@ -971,47 +971,47 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) { - if( mLocked ) - return FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - + if( mLocked ) + return FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + BOOL success = FALSE; - reset(); - + reset(); + mPickOptions |= F_FILE; mPickOptions |= F_MULTIPLE; - if (blocking) // always true for linux/mac - { - // Modal, so pause agent - send_agent_pause(); - } - - success = doNavChooseDialog(filter); - - if (blocking) - { - send_agent_resume(); - } - - if (success) - { - if (!getFileCount()) - success = false; - if (getFileCount() > 1) - mLocked = true; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + if (blocking) // always true for linux/mac + { + // Modal, so pause agent + send_agent_pause(); + } + + success = doNavChooseDialog(filter); + + if (blocking) + { + send_agent_resume(); + } + + if (success) + { + if (!getFileCount()) + success = false; + if (getFileCount() > 1) + mLocked = true; + } + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + return success; } @@ -1029,7 +1029,7 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, } reset(); - + mPickOptions |= F_FILE; mPickOptions |= F_MULTIPLE; @@ -1040,42 +1040,42 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) { - if( mLocked ) - return false; - BOOL success = false; + if( mLocked ) + return false; + BOOL success = false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return false; - } + reset(); - reset(); - mPickOptions &= ~F_MULTIPLE; - if (blocking) - { - // Modal, so pause agent - send_agent_pause(); - } + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } success = doNavSaveDialog(filter, filename); if (success) - { - if (!getFileCount()) - success = false; - } - - if (blocking) - { - send_agent_resume(); - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + { + if (!getFileCount()) + success = false; + } + + if (blocking) + { + send_agent_resume(); + } + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + return success; } BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, @@ -1085,7 +1085,7 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, { if( mLocked ) return false; - + // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { @@ -1093,7 +1093,7 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, } reset(); - + mPickOptions &= ~F_MULTIPLE; return doNavSaveDialogModeless(filter, filename, callback, userdata); @@ -1107,414 +1107,414 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, // static void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) { - // We need to run g_filename_to_utf8 in the user's locale - std::string saved_locale(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - - LLFilePicker* picker = (LLFilePicker*) user_data; - GError *error = NULL; - gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, - -1, NULL, NULL, &error); - if (error) - { - // *FIXME. - // This condition should really be notified to the user, e.g. - // through a message box. Just logging it is inappropriate. - - // g_filename_display_name is ideal, but >= glib 2.6, so: - // a hand-rolled hacky makeASCII which disallows control chars - std::string display_name; - for (const gchar *str = (const gchar *)data; *str; str++) - { - display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); - } - LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; - } - - if (filename_utf8) - { - picker->mFiles.push_back(std::string(filename_utf8)); - LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; - g_free(filename_utf8); - } - - setlocale(LC_ALL, saved_locale.c_str()); + // We need to run g_filename_to_utf8 in the user's locale + std::string saved_locale(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + + LLFilePicker* picker = (LLFilePicker*) user_data; + GError *error = NULL; + gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, + -1, NULL, NULL, &error); + if (error) + { + // *FIXME. + // This condition should really be notified to the user, e.g. + // through a message box. Just logging it is inappropriate. + + // g_filename_display_name is ideal, but >= glib 2.6, so: + // a hand-rolled hacky makeASCII which disallows control chars + std::string display_name; + for (const gchar *str = (const gchar *)data; *str; str++) + { + display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); + } + LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; + } + + if (filename_utf8) + { + picker->mFiles.push_back(std::string(filename_utf8)); + LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; + g_free(filename_utf8); + } + + setlocale(LC_ALL, saved_locale.c_str()); } // static void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) { - LLFilePicker* picker = (LLFilePicker*)user_data; - - LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; - - if (response == GTK_RESPONSE_ACCEPT) - { - GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); - g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); - g_slist_foreach(file_list, (GFunc)g_free, NULL); - g_slist_free (file_list); - } - - // let's save the extension of the last added file(considering current filter) - GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); - if(gfilter) - { - std::string filter = gtk_file_filter_get_name(gfilter); - - if(filter == LLTrans::getString("png_image_files")) - { - picker->mCurrentExtension = ".png"; - } - else if(filter == LLTrans::getString("targa_image_files")) - { - picker->mCurrentExtension = ".tga"; - } - } - - // set the default path for this usage context. - const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); - if (cur_folder != NULL) - { - picker->mContextToPathMap[picker->mCurContextName] = cur_folder; - } - - gtk_widget_destroy(widget); - gtk_main_quit(); + LLFilePicker* picker = (LLFilePicker*)user_data; + + LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; + + if (response == GTK_RESPONSE_ACCEPT) + { + GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); + g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); + g_slist_foreach(file_list, (GFunc)g_free, NULL); + g_slist_free (file_list); + } + + // let's save the extension of the last added file(considering current filter) + GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); + if(gfilter) + { + std::string filter = gtk_file_filter_get_name(gfilter); + + if(filter == LLTrans::getString("png_image_files")) + { + picker->mCurrentExtension = ".png"; + } + else if(filter == LLTrans::getString("targa_image_files")) + { + picker->mCurrentExtension = ".tga"; + } + } + + // set the default path for this usage context. + const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); + if (cur_folder != NULL) + { + picker->mContextToPathMap[picker->mCurContextName] = cur_folder; + } + + gtk_widget_destroy(widget); + gtk_main_quit(); } GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context) { #ifndef LL_MESA_HEADLESS - if (LLWindowSDL::ll_try_gtk_init()) - { - GtkWidget *win = NULL; - GtkFileChooserAction pickertype = - is_save? - (is_folder? - GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : - GTK_FILE_CHOOSER_ACTION_SAVE) : - (is_folder? - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : - GTK_FILE_CHOOSER_ACTION_OPEN); - - win = gtk_file_chooser_dialog_new(NULL, NULL, - pickertype, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - is_folder ? - GTK_STOCK_APPLY : - (is_save ? - GTK_STOCK_SAVE : - GTK_STOCK_OPEN), - GTK_RESPONSE_ACCEPT, - (gchar *)NULL); - mCurContextName = context; - - // get the default path for this usage context if it's been - // seen before. - std::map::iterator - this_path = mContextToPathMap.find(context); - if (this_path != mContextToPathMap.end()) - { - gtk_file_chooser_set_current_folder - (GTK_FILE_CHOOSER(win), - this_path->second.c_str()); - } + if (LLWindowSDL::ll_try_gtk_init()) + { + GtkWidget *win = NULL; + GtkFileChooserAction pickertype = + is_save? + (is_folder? + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : + GTK_FILE_CHOOSER_ACTION_SAVE) : + (is_folder? + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : + GTK_FILE_CHOOSER_ACTION_OPEN); + + win = gtk_file_chooser_dialog_new(NULL, NULL, + pickertype, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + is_folder ? + GTK_STOCK_APPLY : + (is_save ? + GTK_STOCK_SAVE : + GTK_STOCK_OPEN), + GTK_RESPONSE_ACCEPT, + (gchar *)NULL); + mCurContextName = context; + + // get the default path for this usage context if it's been + // seen before. + std::map::iterator + this_path = mContextToPathMap.find(context); + if (this_path != mContextToPathMap.end()) + { + gtk_file_chooser_set_current_folder + (GTK_FILE_CHOOSER(win), + this_path->second.c_str()); + } # if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK raw X11 window, which should try - // to keep it on top etc. - Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); - if (None != XWindowID) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } - else - { - LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; - } + // Make GTK tell the window manager to associate this + // dialog with our non-GTK raw X11 window, which should try + // to keep it on top etc. + Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); + if (None != XWindowID) + { + gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin + GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); + gdk_window_set_transient_for(GTK_WIDGET(win)->window, + gdkwin); + } + else + { + LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; + } # endif //LL_X11 - g_signal_connect (GTK_FILE_CHOOSER(win), - "response", - G_CALLBACK(LLFilePicker::chooser_responder), - this); + g_signal_connect (GTK_FILE_CHOOSER(win), + "response", + G_CALLBACK(LLFilePicker::chooser_responder), + this); - gtk_window_set_modal(GTK_WINDOW(win), TRUE); + gtk_window_set_modal(GTK_WINDOW(win), TRUE); - /* GTK 2.6: if (is_folder) - gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), - TRUE); */ + /* GTK 2.6: if (is_folder) + gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), + TRUE); */ - return GTK_WINDOW(win); - } - else - { - return NULL; - } + return GTK_WINDOW(win); + } + else + { + return NULL; + } #else - return NULL; + return NULL; #endif //LL_MESA_HEADLESS } static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, - GtkWindow *picker, - std::string filtername) -{ - gtk_file_filter_set_name(gfilter, filtername.c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter); - GtkFileFilter *allfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(allfilter, "*"); - gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); + GtkWindow *picker, + std::string filtername) +{ + gtk_file_filter_set_name(gfilter, filtername.c_str()); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter); + GtkFileFilter *allfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(allfilter, "*"); + gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); } static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, - std::string pattern, - std::string filtername) + std::string pattern, + std::string filtername) { - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, pattern.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, pattern.c_str()); + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, - std::string mime, - std::string filtername) + std::string mime, + std::string filtername) { - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_mime_type(gfilter, mime.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_mime_type(gfilter, mime.c_str()); + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", - LLTrans::getString("sound_files") + " (*.wav)"); + return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", + LLTrans::getString("sound_files") + " (*.wav)"); } static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) { - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.bvh"); - gtk_file_filter_add_pattern(gfilter, "*.anim"); - std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, "*.bvh"); + gtk_file_filter_add_pattern(gfilter, "*.anim"); + std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", - LLTrans::getString("xml_files") + " (*.xml)"); + return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", + LLTrans::getString("xml_files") + " (*.xml)"); } static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", - LLTrans::getString("scene_files") + " (*.dae)"); + return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", + LLTrans::getString("scene_files") + " (*.dae)"); } static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) { - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.tga"); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); - std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, "*.tga"); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); + std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } - + static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("script_files") + " (*.lsl)"); + return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, + LLTrans::getString("script_files") + " (*.lsl)"); } static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) { - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); + return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, + LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); } static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) { - GtkFileFilter *gfilter_tga = gtk_file_filter_new(); - GtkFileFilter *gfilter_png = gtk_file_filter_new(); - - gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); - gtk_file_filter_add_mime_type(gfilter_png, "image/png"); - std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; - gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); - gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); - - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_png); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_tga); - return caption; + GtkFileFilter *gfilter_tga = gtk_file_filter_new(); + GtkFileFilter *gfilter_png = gtk_file_filter_new(); + + gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); + gtk_file_filter_add_mime_type(gfilter_png, "image/png"); + std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; + gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); + gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); + + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter_png); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter_tga); + return caption; } BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { - BOOL rtn = FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(true, false, "savefile"); - - if (picker) - { - std::string suggest_name = "untitled"; - std::string suggest_ext = ""; - std::string caption = LLTrans::getString("save_file_verb") + " "; - switch (filter) - { - case FFSAVE_WAV: - caption += add_wav_filter_to_gtkchooser(picker); - suggest_ext = ".wav"; - break; - case FFSAVE_TGA: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); - suggest_ext = ".tga"; - break; - case FFSAVE_BMP: - caption += add_simple_mime_filter_to_gtkchooser - (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); - suggest_ext = ".bmp"; - break; - case FFSAVE_PNG: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); - suggest_ext = ".png"; - break; - case FFSAVE_TGAPNG: - caption += add_save_texture_filter_to_gtkchooser(picker); - suggest_ext = ".png"; - break; - case FFSAVE_AVI: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "video/x-msvideo", - LLTrans::getString("avi_movie_file") + " (*.avi)"); - suggest_ext = ".avi"; - break; - case FFSAVE_ANIM: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); - suggest_ext = ".xaf"; - break; - case FFSAVE_XML: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); - suggest_ext = ".xml"; - break; - case FFSAVE_RAW: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); - suggest_ext = ".raw"; - break; - case FFSAVE_J2C: - // *TODO: Should this be 'image/j2c' ? - caption += add_simple_mime_filter_to_gtkchooser - (picker, "images/jp2", - LLTrans::getString("compressed_image_files") + " (*.j2c)"); - suggest_ext = ".j2c"; - break; - case FFSAVE_SCRIPT: - caption += add_script_filter_to_gtkchooser(picker); - suggest_ext = ".lsl"; - break; - default:; - break; - } - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - if (filename.empty()) - { - suggest_name += suggest_ext; - - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), - suggest_name.c_str()); - } - else - { - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), filename.c_str()); - } - - gtk_widget_show_all(GTK_WIDGET(picker)); - - gtk_main(); - - rtn = (getFileCount() == 1); - - if(rtn && filter == FFSAVE_TGAPNG) - { - std::string selected_file = mFiles.back(); - mFiles.pop_back(); - mFiles.push_back(selected_file + mCurrentExtension); - } - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; + BOOL rtn = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + gViewerWindow->getWindow()->beforeDialog(); + + reset(); + + GtkWindow* picker = buildFilePicker(true, false, "savefile"); + + if (picker) + { + std::string suggest_name = "untitled"; + std::string suggest_ext = ""; + std::string caption = LLTrans::getString("save_file_verb") + " "; + switch (filter) + { + case FFSAVE_WAV: + caption += add_wav_filter_to_gtkchooser(picker); + suggest_ext = ".wav"; + break; + case FFSAVE_TGA: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); + suggest_ext = ".tga"; + break; + case FFSAVE_BMP: + caption += add_simple_mime_filter_to_gtkchooser + (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); + suggest_ext = ".bmp"; + break; + case FFSAVE_PNG: + caption += add_simple_mime_filter_to_gtkchooser + (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); + suggest_ext = ".png"; + break; + case FFSAVE_TGAPNG: + caption += add_save_texture_filter_to_gtkchooser(picker); + suggest_ext = ".png"; + break; + case FFSAVE_AVI: + caption += add_simple_mime_filter_to_gtkchooser + (picker, "video/x-msvideo", + LLTrans::getString("avi_movie_file") + " (*.avi)"); + suggest_ext = ".avi"; + break; + case FFSAVE_ANIM: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); + suggest_ext = ".xaf"; + break; + case FFSAVE_XML: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); + suggest_ext = ".xml"; + break; + case FFSAVE_RAW: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); + suggest_ext = ".raw"; + break; + case FFSAVE_J2C: + // *TODO: Should this be 'image/j2c' ? + caption += add_simple_mime_filter_to_gtkchooser + (picker, "images/jp2", + LLTrans::getString("compressed_image_files") + " (*.j2c)"); + suggest_ext = ".j2c"; + break; + case FFSAVE_SCRIPT: + caption += add_script_filter_to_gtkchooser(picker); + suggest_ext = ".lsl"; + break; + default:; + break; + } + + gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); + + if (filename.empty()) + { + suggest_name += suggest_ext; + + gtk_file_chooser_set_current_name + (GTK_FILE_CHOOSER(picker), + suggest_name.c_str()); + } + else + { + gtk_file_chooser_set_current_name + (GTK_FILE_CHOOSER(picker), filename.c_str()); + } + + gtk_widget_show_all(GTK_WIDGET(picker)); + + gtk_main(); + + rtn = (getFileCount() == 1); + + if(rtn && filter == FFSAVE_TGAPNG) + { + std::string selected_file = mFiles.back(); + mFiles.pop_back(); + mFiles.push_back(selected_file + mCurrentExtension); + } + } + + gViewerWindow->getWindow()->afterDialog(); + + return rtn; } BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) { - BOOL rtn = FALSE; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) - { - std::string caption = LLTrans::getString("load_file_verb") + " "; - std::string filtername = ""; - switch (filter) - { - case FFLOAD_WAV: - filtername = add_wav_filter_to_gtkchooser(picker); - break; - case FFLOAD_ANIM: - filtername = add_anim_filter_to_gtkchooser(picker); - break; - case FFLOAD_XML: - filtername = add_xml_filter_to_gtkchooser(picker); - break; + BOOL rtn = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + gViewerWindow->getWindow()->beforeDialog(); + + reset(); + + GtkWindow* picker = buildFilePicker(false, false, "openfile"); + + if (picker) + { + std::string caption = LLTrans::getString("load_file_verb") + " "; + std::string filtername = ""; + switch (filter) + { + case FFLOAD_WAV: + filtername = add_wav_filter_to_gtkchooser(picker); + break; + case FFLOAD_ANIM: + filtername = add_anim_filter_to_gtkchooser(picker); + break; + case FFLOAD_XML: + filtername = add_xml_filter_to_gtkchooser(picker); + break; case FFLOAD_GLTF: filtername = dead_code_should_blow_up_here(picker); break; @@ -1522,64 +1522,64 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) filtername = add_collada_filter_to_gtkchooser(picker); break; case FFLOAD_IMAGE: - filtername = add_imageload_filter_to_gtkchooser(picker); - break; - case FFLOAD_SCRIPT: - filtername = add_script_filter_to_gtkchooser(picker); - break; - case FFLOAD_DICTIONARY: - filtername = add_dictionary_filter_to_gtkchooser(picker); - break; - default:; - break; - } - - caption += filtername; - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - - rtn = (getFileCount() == 1); - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; + filtername = add_imageload_filter_to_gtkchooser(picker); + break; + case FFLOAD_SCRIPT: + filtername = add_script_filter_to_gtkchooser(picker); + break; + case FFLOAD_DICTIONARY: + filtername = add_dictionary_filter_to_gtkchooser(picker); + break; + default:; + break; + } + + caption += filtername; + + gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); + + gtk_widget_show_all(GTK_WIDGET(picker)); + gtk_main(); + + rtn = (getFileCount() == 1); + } + + gViewerWindow->getWindow()->afterDialog(); + + return rtn; } BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { - BOOL rtn = FALSE; + BOOL rtn = FALSE; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } + gViewerWindow->getWindow()->beforeDialog(); - gViewerWindow->getWindow()->beforeDialog(); + reset(); - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); + GtkWindow* picker = buildFilePicker(false, false, "openfile"); - if (picker) - { - gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), - TRUE); + if (picker) + { + gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), + TRUE); - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); + gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - rtn = !mFiles.empty(); - } + gtk_widget_show_all(GTK_WIDGET(picker)); + gtk_main(); + rtn = !mFiles.empty(); + } - gViewerWindow->getWindow()->afterDialog(); + gViewerWindow->getWindow()->afterDialog(); - return rtn; + return rtn; } # else // LL_GTK @@ -1589,23 +1589,23 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { - // if local file browsing is turned off, return without opening dialog - // (Even though this is a stub, I think we still should not return anything at all) - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - reset(); - - LL_INFOS() << "getSaveFile suggested filename is [" << filename - << "]" << LL_ENDL; - if (!filename.empty()) - { - mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename); - return TRUE; - } - return FALSE; + // if local file browsing is turned off, return without opening dialog + // (Even though this is a stub, I think we still should not return anything at all) + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + reset(); + + LL_INFOS() << "getSaveFile suggested filename is [" << filename + << "]" << LL_ENDL; + if (!filename.empty()) + { + mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename); + return TRUE; + } + return FALSE; } BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, @@ -1619,27 +1619,27 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) { - // if local file browsing is turned off, return without opening dialog - // (Even though this is a stub, I think we still should not return anything at all) - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - reset(); - - // HACK: Static filenames for 'open' until we implement filepicker - std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload"; - switch (filter) - { - case FFLOAD_WAV: filename += ".wav"; break; - case FFLOAD_IMAGE: filename += ".tga"; break; - case FFLOAD_ANIM: filename += ".bvh"; break; - default: break; - } - mFiles.push_back(filename); - LL_INFOS() << "getOpenFile: Will try to open file: " << filename << LL_ENDL; - return TRUE; + // if local file browsing is turned off, return without opening dialog + // (Even though this is a stub, I think we still should not return anything at all) + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + reset(); + + // HACK: Static filenames for 'open' until we implement filepicker + std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload"; + switch (filter) + { + case FFLOAD_WAV: filename += ".wav"; break; + case FFLOAD_IMAGE: filename += ".tga"; break; + case FFLOAD_ANIM: filename += ".bvh"; break; + default: break; + } + mFiles.push_back(filename); + LL_INFOS() << "getOpenFile: Will try to open file: " << filename << LL_ENDL; + return TRUE; } BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, @@ -1652,15 +1652,15 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { - // if local file browsing is turned off, return without opening dialog - // (Even though this is a stub, I think we still should not return anything at all) - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - reset(); - return FALSE; + // if local file browsing is turned off, return without opening dialog + // (Even though this is a stub, I think we still should not return anything at all) + if ( check_local_file_access_enabled() == false ) + { + return FALSE; + } + + reset(); + return FALSE; } BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, @@ -1677,20 +1677,20 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) { - reset(); - return FALSE; + reset(); + return FALSE; } BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) { - reset(); - return FALSE; + reset(); + return FALSE; } BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { - reset(); - return FALSE; + reset(); + return FALSE; } #endif // LL_LINUX diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 891c0c0482..994e7458d3 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -1,25 +1,25 @@ -/** +/** * @file llfilepicker.h * @brief OS-specific file picker * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -64,119 +64,119 @@ extern "C" { class LLFilePicker { #ifdef LL_GTK - friend class LLDirPicker; - friend void chooser_responder(GtkWidget *, gint, gpointer); + friend class LLDirPicker; + friend void chooser_responder(GtkWidget *, gint, gpointer); #endif // LL_GTK public: - // calling this before main() is undefined - static LLFilePicker& instance( void ) { return sInstance; } - - enum ELoadFilter - { - FFLOAD_ALL = 1, - FFLOAD_WAV = 2, - FFLOAD_IMAGE = 3, - FFLOAD_ANIM = 4, - FFLOAD_GLTF = 5, - FFLOAD_XML = 6, - FFLOAD_SLOBJECT = 7, - FFLOAD_RAW = 8, - FFLOAD_MODEL = 9, - FFLOAD_COLLADA = 10, - FFLOAD_SCRIPT = 11, - FFLOAD_DICTIONARY = 12, + // calling this before main() is undefined + static LLFilePicker& instance( void ) { return sInstance; } + + enum ELoadFilter + { + FFLOAD_ALL = 1, + FFLOAD_WAV = 2, + FFLOAD_IMAGE = 3, + FFLOAD_ANIM = 4, + FFLOAD_GLTF = 5, + FFLOAD_XML = 6, + FFLOAD_SLOBJECT = 7, + FFLOAD_RAW = 8, + FFLOAD_MODEL = 9, + FFLOAD_COLLADA = 10, + FFLOAD_SCRIPT = 11, + FFLOAD_DICTIONARY = 12, FFLOAD_DIRECTORY = 13, // To call from lldirpicker. FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin FFLOAD_MATERIAL = 15, FFLOAD_MATERIAL_TEXTURE = 16, FFLOAD_HDRI = 17, - }; - - enum ESaveFilter - { - FFSAVE_ALL = 1, - FFSAVE_WAV = 3, - FFSAVE_TGA = 4, - FFSAVE_BMP = 5, - FFSAVE_AVI = 6, - FFSAVE_ANIM = 7, - FFSAVE_GLTF = 8, - FFSAVE_XML = 9, - FFSAVE_COLLADA = 10, - FFSAVE_RAW = 11, - FFSAVE_J2C = 12, - FFSAVE_PNG = 13, - FFSAVE_JPEG = 14, - FFSAVE_SCRIPT = 15, - FFSAVE_TGAPNG = 16 - }; - - // open the dialog. This is a modal operation - BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true); + }; + + enum ESaveFilter + { + FFSAVE_ALL = 1, + FFSAVE_WAV = 3, + FFSAVE_TGA = 4, + FFSAVE_BMP = 5, + FFSAVE_AVI = 6, + FFSAVE_ANIM = 7, + FFSAVE_GLTF = 8, + FFSAVE_XML = 9, + FFSAVE_COLLADA = 10, + FFSAVE_RAW = 11, + FFSAVE_J2C = 12, + FFSAVE_PNG = 13, + FFSAVE_JPEG = 14, + FFSAVE_SCRIPT = 15, + FFSAVE_TGAPNG = 16 + }; + + // open the dialog. This is a modal operation + BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true); BOOL getSaveFileModeless(ESaveFilter filter, const std::string& filename, void (*callback)(bool, std::string&, void*), void *userdata); - BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); + BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); // Todo: implement getOpenFileModeless and getMultipleOpenFilesModeless // for windows and use directly instead of ugly LLFilePickerThread BOOL getOpenFileModeless( ELoadFilter filter, void (*callback)(bool, std::vector &, void*), void *userdata); // MAC only. - BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); + BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); BOOL getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector &, void*), void *userdata ); // MAC only - // Get the filename(s) found. getFirstFile() sets the pointer to - // the start of the structure and allows the start of iteration. - const std::string getFirstFile(); + // Get the filename(s) found. getFirstFile() sets the pointer to + // the start of the structure and allows the start of iteration. + const std::string getFirstFile(); + + // getNextFile() increments the internal representation and + // returns the next file specified by the user. Returns NULL when + // no more files are left. Further calls to getNextFile() are + // undefined. + const std::string getNextFile(); - // getNextFile() increments the internal representation and - // returns the next file specified by the user. Returns NULL when - // no more files are left. Further calls to getNextFile() are - // undefined. - const std::string getNextFile(); + // This utility function extracts the current file name without + // doing any incrementing. + const std::string getCurFile(); - // This utility function extracts the current file name without - // doing any incrementing. - const std::string getCurFile(); + // Returns the index of the current file. + S32 getCurFileNum() const { return mCurrentFile; } - // Returns the index of the current file. - S32 getCurFileNum() const { return mCurrentFile; } + S32 getFileCount() const { return (S32)mFiles.size(); } - S32 getFileCount() const { return (S32)mFiles.size(); } + // see lldir.h : getBaseFileName and getDirName to extract base or directory names - // see lldir.h : getBaseFileName and getDirName to extract base or directory names - - // clear any lists of buffers or whatever, and make sure the file - // picker isn't locked. - void reset(); + // clear any lists of buffers or whatever, and make sure the file + // picker isn't locked. + void reset(); private: - enum - { - SINGLE_FILENAME_BUFFER_SIZE = 1024, - //FILENAME_BUFFER_SIZE = 65536 - FILENAME_BUFFER_SIZE = 65000 - }; - - // utility function to check if access to local file system via file browser - // is enabled and if not, tidy up and indicate we're not allowed to do this. - bool check_local_file_access_enabled(); - + enum + { + SINGLE_FILENAME_BUFFER_SIZE = 1024, + //FILENAME_BUFFER_SIZE = 65536 + FILENAME_BUFFER_SIZE = 65000 + }; + + // utility function to check if access to local file system via file browser + // is enabled and if not, tidy up and indicate we're not allowed to do this. + bool check_local_file_access_enabled(); + #if LL_WINDOWS - OPENFILENAMEW mOFN; // for open and save dialogs - WCHAR mFilesW[FILENAME_BUFFER_SIZE]; + OPENFILENAMEW mOFN; // for open and save dialogs + WCHAR mFilesW[FILENAME_BUFFER_SIZE]; - BOOL setupFilter(ELoadFilter filter); + BOOL setupFilter(ELoadFilter filter); #endif #if LL_DARWIN S32 mPickOptions; - std::vector mFileVector; - - bool doNavChooseDialog(ELoadFilter filter); - bool doNavChooseDialogModeless(ELoadFilter filter, + std::vector mFileVector; + + bool doNavChooseDialog(ELoadFilter filter); + bool doNavChooseDialogModeless(ELoadFilter filter, void (*callback)(bool, std::vector&, void*), void *userdata); - bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); + bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); std::unique_ptr> navOpenFilterProc(ELoadFilter filter); bool doNavSaveDialogModeless(ESaveFilter filter, const std::string& filename, @@ -185,31 +185,31 @@ private: #endif #if LL_GTK - static void add_to_selectedfiles(gpointer data, gpointer user_data); - static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data); - // we remember the last path that was accessed for a particular usage - std::map mContextToPathMap; - std::string mCurContextName; - // we also remember the extension of the last added file. - std::string mCurrentExtension; + static void add_to_selectedfiles(gpointer data, gpointer user_data); + static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data); + // we remember the last path that was accessed for a particular usage + std::map mContextToPathMap; + std::string mCurContextName; + // we also remember the extension of the last added file. + std::string mCurrentExtension; #endif - std::vector mFiles; - S32 mCurrentFile; - bool mLocked; + std::vector mFiles; + S32 mCurrentFile; + bool mLocked; + + static LLFilePicker sInstance; - static LLFilePicker sInstance; - protected: #if LL_GTK GtkWindow* buildFilePicker(bool is_save, bool is_folder, - std::string context = "generic"); + std::string context = "generic"); #endif public: - // don't call these directly please. - LLFilePicker(); - ~LLFilePicker(); + // don't call these directly please. + LLFilePicker(); + ~LLFilePicker(); }; #endif diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 2a5106f79e..98842eed77 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llfloaterimagepreview.cpp * @brief LLFloaterImagePreview class implementation * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -65,23 +65,23 @@ const S32 PREVIEW_BORDER_WIDTH = 2; const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; -const S32 PREVIEW_VPAD = -24 + 35; // yuk, hard coded +const S32 PREVIEW_VPAD = -24 + 35; // yuk, hard coded const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16 + 35; const S32 PREVIEW_TEXTURE_HEIGHT = 320; //----------------------------------------------------------------------------- // LLFloaterImagePreview() //----------------------------------------------------------------------------- -LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : - LLFloaterNameDesc(filename), +LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : + LLFloaterNameDesc(filename), - mAvatarPreview(NULL), - mSculptedPreview(NULL), - mLastMouseX(0), - mLastMouseY(0), - mImagep(NULL) + mAvatarPreview(NULL), + mSculptedPreview(NULL), + mLastMouseX(0), + mLastMouseY(0), + mImagep(NULL) { - loadImage(mFilenameAndPath); + loadImage(mFilenameAndPath); } //----------------------------------------------------------------------------- @@ -89,33 +89,33 @@ LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : //----------------------------------------------------------------------------- BOOL LLFloaterImagePreview::postBuild() { - if (!LLFloaterNameDesc::postBuild()) - { - return FALSE; - } - - LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - if (iface) - { - iface->selectFirstItem(); - } - childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this); - - mPreviewRect.set(PREVIEW_HPAD, - PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD, - getRect().getWidth() - PREVIEW_HPAD, - PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f); - - getChildView("bad_image_text")->setVisible(FALSE); - - if (mRawImagep.notNull() && gAgent.getRegion() != NULL) - { - mAvatarPreview = new LLImagePreviewAvatar(256, 256); - mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE); - - mSculptedPreview = new LLImagePreviewSculpted(256, 256); - mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f); + if (!LLFloaterNameDesc::postBuild()) + { + return FALSE; + } + + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); + if (iface) + { + iface->selectFirstItem(); + } + childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this); + + mPreviewRect.set(PREVIEW_HPAD, + PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD, + getRect().getWidth() - PREVIEW_HPAD, + PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f); + + getChildView("bad_image_text")->setVisible(FALSE); + + if (mRawImagep.notNull() && gAgent.getRegion() != NULL) + { + mAvatarPreview = new LLImagePreviewAvatar(256, 256); + mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE); + + mSculptedPreview = new LLImagePreviewSculpted(256, 256); + mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f); if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF) { @@ -125,24 +125,24 @@ BOOL LLFloaterImagePreview::postBuild() check_box->setEnabled(TRUE); check_box->setControlVariable(gSavedSettings.getControl("LosslessJ2CUpload")); } - } - else - { - mAvatarPreview = NULL; - mSculptedPreview = NULL; - getChildView("bad_image_text")->setVisible(TRUE); - getChildView("clothing_type_combo")->setEnabled(FALSE); - getChildView("ok_btn")->setEnabled(FALSE); + } + else + { + mAvatarPreview = NULL; + mSculptedPreview = NULL; + getChildView("bad_image_text")->setVisible(TRUE); + getChildView("clothing_type_combo")->setEnabled(FALSE); + getChildView("ok_btn")->setEnabled(FALSE); + + if(!mImageLoadError.empty()) + { + getChild("bad_image_text")->setValue(mImageLoadError.c_str()); + } + } - if(!mImageLoadError.empty()) - { - getChild("bad_image_text")->setValue(mImageLoadError.c_str()); - } - } - - getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); - - return TRUE; + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + + return TRUE; } @@ -159,70 +159,70 @@ S32 LLFloaterImagePreview::getExpectedUploadCost() const //----------------------------------------------------------------------------- LLFloaterImagePreview::~LLFloaterImagePreview() { - clearAllPreviewTextures(); + clearAllPreviewTextures(); - mRawImagep = NULL; - mImagep = NULL ; + mRawImagep = NULL; + mImagep = NULL ; } -//static +//static //----------------------------------------------------------------------------- // onPreviewTypeCommit() //----------------------------------------------------------------------------- -void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata) -{ - LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata; - - if (!fp->mAvatarPreview || !fp->mSculptedPreview) - { - return; - } - - S32 which_mode = 0; - - LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo"); - if (iface) - { - which_mode = iface->getFirstSelectedIndex(); - } - - switch(which_mode) - { - case 0: - break; - case 1: - fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE); - break; - case 2: - fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE); - break; - case 3: - fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE); - break; - case 4: - fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE); - break; - case 5: - fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE); - break; - case 6: - fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE); - break; - case 7: - fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE); - break; - case 8: - fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE); - break; - case 9: - fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f); - break; - default: - break; - } - - fp->mAvatarPreview->refresh(); - fp->mSculptedPreview->refresh(); +void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata; + + if (!fp->mAvatarPreview || !fp->mSculptedPreview) + { + return; + } + + S32 which_mode = 0; + + LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo"); + if (iface) + { + which_mode = iface->getFirstSelectedIndex(); + } + + switch(which_mode) + { + case 0: + break; + case 1: + fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE); + break; + case 2: + fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE); + break; + case 3: + fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE); + break; + case 4: + fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE); + break; + case 5: + fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE); + break; + case 6: + fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE); + break; + case 7: + fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE); + break; + case 8: + fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE); + break; + case 9: + fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f); + break; + default: + break; + } + + fp->mAvatarPreview->refresh(); + fp->mSculptedPreview->refresh(); } @@ -231,16 +231,16 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata) //----------------------------------------------------------------------------- void LLFloaterImagePreview::clearAllPreviewTextures() { - if (mAvatarPreview) - { - mAvatarPreview->clearPreviewTexture("mHairMesh0"); - mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0"); - mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0"); - mAvatarPreview->clearPreviewTexture("mHeadMesh0"); - mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0"); - mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0"); - mAvatarPreview->clearPreviewTexture("mSkirtMesh0"); - } + if (mAvatarPreview) + { + mAvatarPreview->clearPreviewTexture("mHairMesh0"); + mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0"); + mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0"); + mAvatarPreview->clearPreviewTexture("mHeadMesh0"); + mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0"); + mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0"); + mAvatarPreview->clearPreviewTexture("mSkirtMesh0"); + } } //----------------------------------------------------------------------------- @@ -248,92 +248,92 @@ void LLFloaterImagePreview::clearAllPreviewTextures() //----------------------------------------------------------------------------- void LLFloaterImagePreview::draw() { - LLFloater::draw(); - LLRect r = getRect(); - - if (mRawImagep.notNull()) - { - LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - U32 selected = 0; - if (iface) - selected = iface->getFirstSelectedIndex(); - - if (selected <= 0) - { - gl_rect_2d_checkerboard(mPreviewRect); - - if(mImagep.notNull()) - { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); - } - else - { - mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ; - - gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ; - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); - stop_glerror(); - - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - if (mAvatarPreview) - { - mAvatarPreview->setTexture(mImagep->getTexName()); - mSculptedPreview->setTexture(mImagep->getTexName()); - } - } - - gGL.color3f(1.f, 1.f, 1.f); - gGL.begin( LLRender::QUADS ); - { - gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - } - gGL.end(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - stop_glerror(); - } - else - { - if ((mAvatarPreview) && (mSculptedPreview)) - { - gGL.color3f(1.f, 1.f, 1.f); - - if (selected == 9) - { - gGL.getTexUnit(0)->bind(mSculptedPreview); - } - else - { - gGL.getTexUnit(0)->bind(mAvatarPreview); - } - - gGL.begin( LLRender::QUADS ); - { - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - } - gGL.end(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - } - } + LLFloater::draw(); + LLRect r = getRect(); + + if (mRawImagep.notNull()) + { + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); + U32 selected = 0; + if (iface) + selected = iface->getFirstSelectedIndex(); + + if (selected <= 0) + { + gl_rect_2d_checkerboard(mPreviewRect); + + if(mImagep.notNull()) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); + } + else + { + mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ; + + gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ; + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); + stop_glerror(); + + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + if (mAvatarPreview) + { + mAvatarPreview->setTexture(mImagep->getTexName()); + mSculptedPreview->setTexture(mImagep->getTexName()); + } + } + + gGL.color3f(1.f, 1.f, 1.f); + gGL.begin( LLRender::QUADS ); + { + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + } + gGL.end(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + stop_glerror(); + } + else + { + if ((mAvatarPreview) && (mSculptedPreview)) + { + gGL.color3f(1.f, 1.f, 1.f); + + if (selected == 9) + { + gGL.getTexUnit(0)->bind(mSculptedPreview); + } + else + { + gGL.getTexUnit(0)->bind(mAvatarPreview); + } + + gGL.begin( LLRender::QUADS ); + { + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + } + gGL.end(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + } + } } @@ -342,56 +342,56 @@ void LLFloaterImagePreview::draw() //----------------------------------------------------------------------------- bool LLFloaterImagePreview::loadImage(const std::string& src_filename) { - std::string exten = gDirUtilp->getExtension(src_filename); - U32 codec = LLImageBase::getCodecFromExtension(exten); - - LLImageDimensionsInfo image_info; - if (!image_info.load(src_filename,codec)) - { - mImageLoadError = image_info.getLastError(); - return false; - } - - S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); - S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); - - if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) - { - LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); - - mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); - return false; - } - - // Load the image - LLPointer image = LLImageFormatted::createFromType(codec); - if (image.isNull()) - { - return false; - } - if (!image->load(src_filename)) - { - return false; - } - // Decompress or expand it in a raw image structure - LLPointer raw_image = new LLImageRaw; - if (!image->decode(raw_image, 0.0f)) - { - return false; - } - // Check the image constraints - if ((image->getComponents() != 3) && (image->getComponents() != 4)) - { - image->setLastError("Image files with less than 3 or more than 4 components are not supported."); - return false; - } - - raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - mRawImagep = raw_image; - - return true; + std::string exten = gDirUtilp->getExtension(src_filename); + U32 codec = LLImageBase::getCodecFromExtension(exten); + + LLImageDimensionsInfo image_info; + if (!image_info.load(src_filename,codec)) + { + mImageLoadError = image_info.getLastError(); + return false; + } + + S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); + S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + + if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) + { + LLStringUtil::format_map_t args; + args["WIDTH"] = llformat("%d", max_width); + args["HEIGHT"] = llformat("%d", max_height); + + mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + return false; + } + + // Load the image + LLPointer image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + return false; + } + if (!image->load(src_filename)) + { + return false; + } + // Decompress or expand it in a raw image structure + LLPointer raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + return false; + } + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + image->setLastError("Image files with less than 3 or more than 4 components are not supported."); + return false; + } + + raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + mRawImagep = raw_image; + + return true; } //----------------------------------------------------------------------------- @@ -399,17 +399,17 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) //----------------------------------------------------------------------------- BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask) { - if (mPreviewRect.pointInRect(x, y)) - { - bringToFront( x, y ); - gFocusMgr.setMouseCapture(this); - gViewerWindow->hideCursor(); - mLastMouseX = x; - mLastMouseY = y; - return TRUE; - } + if (mPreviewRect.pointInRect(x, y)) + { + bringToFront( x, y ); + gFocusMgr.setMouseCapture(this); + gViewerWindow->hideCursor(); + mLastMouseX = x; + mLastMouseY = y; + return TRUE; + } - return LLFloater::handleMouseDown(x, y, mask); + return LLFloater::handleMouseDown(x, y, mask); } //----------------------------------------------------------------------------- @@ -417,9 +417,9 @@ BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask) { - gFocusMgr.setMouseCapture(FALSE); - gViewerWindow->showCursor(); - return LLFloater::handleMouseUp(x, y, mask); + gFocusMgr.setMouseCapture(FALSE); + gViewerWindow->showCursor(); + return LLFloater::handleMouseUp(x, y, mask); } //----------------------------------------------------------------------------- @@ -427,119 +427,119 @@ BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) { - MASK local_mask = mask & ~MASK_ALT; - - if (mAvatarPreview && hasMouseCapture()) - { - if (local_mask == MASK_PAN) - { - // pan here - LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - if (iface && iface->getFirstSelectedIndex() <= 0) - { - mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(), - (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight()); - } - else - { - mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); - mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); - } - } - else if (local_mask == MASK_ORBIT) - { - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; - - mAvatarPreview->rotate(yaw_radians, pitch_radians); - mSculptedPreview->rotate(yaw_radians, pitch_radians); - } - else - { - LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - if (iface && iface->getFirstSelectedIndex() <= 0) - { - F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f; - mPreviewImageRect.stretch(zoom_amt); - } - else - { - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; - - mAvatarPreview->rotate(yaw_radians, 0.f); - mAvatarPreview->zoom(zoom_amt); - mSculptedPreview->rotate(yaw_radians, 0.f); - mSculptedPreview->zoom(zoom_amt); - } - } - - LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - if (iface && iface->getFirstSelectedIndex() <= 0) - { - if (mPreviewImageRect.getWidth() > 1.f) - { - mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f); - } - else if (mPreviewImageRect.getWidth() < 0.1f) - { - mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f); - } - - if (mPreviewImageRect.getHeight() > 1.f) - { - mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f); - } - else if (mPreviewImageRect.getHeight() < 0.1f) - { - mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f); - } - - if (mPreviewImageRect.mLeft < 0.f) - { - mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f); - } - else if (mPreviewImageRect.mRight > 1.f) - { - mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f); - } - - if (mPreviewImageRect.mBottom < 0.f) - { - mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom); - } - else if (mPreviewImageRect.mTop > 1.f) - { - mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop); - } - } - else - { - mAvatarPreview->refresh(); - mSculptedPreview->refresh(); - } - - LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY); - } - - if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview) - { - return LLFloater::handleHover(x, y, mask); - } - else if (local_mask == MASK_ORBIT) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); - } - else if (local_mask == MASK_PAN) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); - } - - return TRUE; + MASK local_mask = mask & ~MASK_ALT; + + if (mAvatarPreview && hasMouseCapture()) + { + if (local_mask == MASK_PAN) + { + // pan here + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); + if (iface && iface->getFirstSelectedIndex() <= 0) + { + mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(), + (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight()); + } + else + { + mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); + mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); + } + } + else if (local_mask == MASK_ORBIT) + { + F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; + F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; + + mAvatarPreview->rotate(yaw_radians, pitch_radians); + mSculptedPreview->rotate(yaw_radians, pitch_radians); + } + else + { + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); + if (iface && iface->getFirstSelectedIndex() <= 0) + { + F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f; + mPreviewImageRect.stretch(zoom_amt); + } + else + { + F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; + F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; + + mAvatarPreview->rotate(yaw_radians, 0.f); + mAvatarPreview->zoom(zoom_amt); + mSculptedPreview->rotate(yaw_radians, 0.f); + mSculptedPreview->zoom(zoom_amt); + } + } + + LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); + if (iface && iface->getFirstSelectedIndex() <= 0) + { + if (mPreviewImageRect.getWidth() > 1.f) + { + mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f); + } + else if (mPreviewImageRect.getWidth() < 0.1f) + { + mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f); + } + + if (mPreviewImageRect.getHeight() > 1.f) + { + mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f); + } + else if (mPreviewImageRect.getHeight() < 0.1f) + { + mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f); + } + + if (mPreviewImageRect.mLeft < 0.f) + { + mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f); + } + else if (mPreviewImageRect.mRight > 1.f) + { + mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f); + } + + if (mPreviewImageRect.mBottom < 0.f) + { + mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom); + } + else if (mPreviewImageRect.mTop > 1.f) + { + mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop); + } + } + else + { + mAvatarPreview->refresh(); + mSculptedPreview->refresh(); + } + + LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY); + } + + if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview) + { + return LLFloater::handleHover(x, y, mask); + } + else if (local_mask == MASK_ORBIT) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); + } + else if (local_mask == MASK_PAN) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); + } + else + { + gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); + } + + return TRUE; } //----------------------------------------------------------------------------- @@ -547,16 +547,16 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) //----------------------------------------------------------------------------- BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if (mPreviewRect.pointInRect(x, y) && mAvatarPreview) - { - mAvatarPreview->zoom((F32)clicks * -0.2f); - mAvatarPreview->refresh(); + if (mPreviewRect.pointInRect(x, y) && mAvatarPreview) + { + mAvatarPreview->zoom((F32)clicks * -0.2f); + mAvatarPreview->refresh(); - mSculptedPreview->zoom((F32)clicks * -0.2f); - mSculptedPreview->refresh(); - } + mSculptedPreview->zoom((F32)clicks * -0.2f); + mSculptedPreview->refresh(); + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -565,7 +565,7 @@ BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks) // static void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handler) { - gViewerWindow->showCursor(); + gViewerWindow->showCursor(); } @@ -574,63 +574,63 @@ void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handl //----------------------------------------------------------------------------- LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { - mNeedsUpdate = TRUE; - mTargetJoint = NULL; - mTargetMesh = NULL; - mCameraDistance = 0.f; - mCameraYaw = 0.f; - mCameraPitch = 0.f; - mCameraZoom = 1.f; + mNeedsUpdate = TRUE; + mTargetJoint = NULL; + mTargetMesh = NULL; + mCameraDistance = 0.f; + mCameraYaw = 0.f; + mCameraPitch = 0.f; + mCameraZoom = 1.f; - mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR); - mDummyAvatar->mSpecialRenderMode = 2; + mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR); + mDummyAvatar->mSpecialRenderMode = 2; - mTextureName = 0; + mTextureName = 0; } LLImagePreviewAvatar::~LLImagePreviewAvatar() { - mDummyAvatar->markDead(); + mDummyAvatar->markDead(); } //virtual S8 LLImagePreviewAvatar::getType() const { - return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_AVATAR ; -} - -void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male) -{ - mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name); - // clear out existing test mesh - if (mTargetMesh) - { - mTargetMesh->setTestTexture(0); - } - - if (male) - { - mDummyAvatar->setVisualParamWeight( "male", 1.f ); - mDummyAvatar->updateVisualParams(); - mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); - } - else - { - mDummyAvatar->setVisualParamWeight( "male", 0.f ); - mDummyAvatar->updateVisualParams(); - mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); - } - mDummyAvatar->mRoot->setVisible(FALSE, TRUE); - - mTargetMesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); - mTargetMesh->setTestTexture(mTextureName); - mTargetMesh->setVisible(TRUE, FALSE); - mCameraDistance = distance; - mCameraZoom = 1.f; - mCameraPitch = 0.f; - mCameraYaw = 0.f; - mCameraOffset.clearVec(); + return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_AVATAR ; +} + +void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male) +{ + mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name); + // clear out existing test mesh + if (mTargetMesh) + { + mTargetMesh->setTestTexture(0); + } + + if (male) + { + mDummyAvatar->setVisualParamWeight( "male", 1.f ); + mDummyAvatar->updateVisualParams(); + mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); + } + else + { + mDummyAvatar->setVisualParamWeight( "male", 0.f ); + mDummyAvatar->updateVisualParams(); + mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); + } + mDummyAvatar->mRoot->setVisible(FALSE, TRUE); + + mTargetMesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); + mTargetMesh->setTestTexture(mTextureName); + mTargetMesh->setVisible(TRUE, FALSE); + mCameraDistance = distance; + mCameraZoom = 1.f; + mCameraPitch = 0.f; + mCameraYaw = 0.f; + mCameraOffset.clearVec(); } //----------------------------------------------------------------------------- @@ -638,15 +638,15 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const //----------------------------------------------------------------------------- void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name) { - if (mDummyAvatar) - { - LLViewerJointMesh *mesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); - // clear out existing test mesh - if (mesh) - { - mesh->setTestTexture(0); - } - } + if (mDummyAvatar) + { + LLViewerJointMesh *mesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); + // clear out existing test mesh + if (mesh) + { + mesh->setTestTexture(0); + } + } } //----------------------------------------------------------------------------- @@ -654,82 +654,82 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name) //----------------------------------------------------------------------------- BOOL LLImagePreviewAvatar::render() { - mNeedsUpdate = FALSE; - LLVOAvatar* avatarp = mDummyAvatar; + mNeedsUpdate = FALSE; + LLVOAvatar* avatarp = mDummyAvatar; + + gGL.pushUIMatrix(); + gGL.loadUIIdentity(); - gGL.pushUIMatrix(); - gGL.loadUIIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - - LLGLSUIDefault def; - gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); + LLGLSUIDefault def; + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gUIProgram.bind(); + gUIProgram.bind(); - gl_rect_2d_simple( mFullWidth, mFullHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); - gGL.flush(); - LLVector3 target_pos = mTargetJoint->getWorldPosition(); + gGL.flush(); + LLVector3 target_pos = mTargetJoint->getWorldPosition(); - LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * - LLQuaternion(mCameraYaw, LLVector3::z_axis); + LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * + LLQuaternion(mCameraYaw, LLVector3::z_axis); - LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot; - LLViewerCamera::getInstance()->setOriginAndLookAt( - target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera - LLVector3::z_axis, // up - target_pos + (mCameraOffset * av_rot) ); // point of interest + LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot; + LLViewerCamera::getInstance()->setOriginAndLookAt( + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos + (mCameraOffset * av_rot) ); // point of interest - stop_glerror(); + stop_glerror(); - LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight); - LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); - LLVertexBuffer::unbind(); - avatarp->updateLOD(); - - if (avatarp->mDrawable.notNull()) - { - LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); - // make sure alpha=0 shows avatar material color - LLGLDisable no_blend(GL_BLEND); + LLVertexBuffer::unbind(); + avatarp->updateLOD(); - LLFace* face = avatarp->mDrawable->getFace(0); - if (face) - { - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); - gPipeline.enableLightsPreview(); - avatarPoolp->renderAvatars(avatarp); // renders only one avatar - } - } + if (avatarp->mDrawable.notNull()) + { + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); + // make sure alpha=0 shows avatar material color + LLGLDisable no_blend(GL_BLEND); - gGL.popUIMatrix(); - gGL.color4f(1,1,1,1); - return TRUE; + LLFace* face = avatarp->mDrawable->getFace(0); + if (face) + { + LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); + gPipeline.enableLightsPreview(); + avatarPoolp->renderAvatars(avatarp); // renders only one avatar + } + } + + gGL.popUIMatrix(); + gGL.color4f(1,1,1,1); + return TRUE; } //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- void LLImagePreviewAvatar::refresh() -{ - mNeedsUpdate = TRUE; +{ + mNeedsUpdate = TRUE; } //----------------------------------------------------------------------------- @@ -737,9 +737,9 @@ void LLImagePreviewAvatar::refresh() //----------------------------------------------------------------------------- void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians) { - mCameraYaw = mCameraYaw + yaw_radians; + mCameraYaw = mCameraYaw + yaw_radians; - mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); + mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); } //----------------------------------------------------------------------------- @@ -747,13 +747,13 @@ void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians) //----------------------------------------------------------------------------- void LLImagePreviewAvatar::zoom(F32 zoom_amt) { - mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); + mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); } void LLImagePreviewAvatar::pan(F32 right, F32 up) { - mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); - mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); + mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); + mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); } @@ -763,19 +763,19 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up) LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { - mNeedsUpdate = TRUE; - mCameraDistance = 0.f; - mCameraYaw = 0.f; - mCameraPitch = 0.f; - mCameraZoom = 1.f; - mTextureName = 0; + mNeedsUpdate = TRUE; + mCameraDistance = 0.f; + mCameraYaw = 0.f; + mCameraPitch = 0.f; + mCameraZoom = 1.f; + mTextureName = 0; + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE); + volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_SPHERE); - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE); - volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_SPHERE); - - F32 const HIGHEST_LOD = 4.0f; - mVolume = new LLVolume(volume_params, HIGHEST_LOD); + F32 const HIGHEST_LOD = 4.0f; + mVolume = new LLVolume(volume_params, HIGHEST_LOD); } @@ -786,67 +786,67 @@ LLImagePreviewSculpted::~LLImagePreviewSculpted() //virtual S8 LLImagePreviewSculpted::getType() const { - return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_SCULPTED ; + return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_SCULPTED ; } void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) -{ - mCameraDistance = distance; - mCameraZoom = 1.f; - mCameraPitch = 0.f; - mCameraYaw = 0.f; - mCameraOffset.clearVec(); - - if (imagep) - { - mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false); - } - - const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mNumIndices; - U32 num_vertices = vf.mNumVertices; - - mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); - if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to" - << num_vertices << " vertices and " - << num_indices << " indices" << LL_ENDL; - // We are likely to crash on getTexCoord0Strider() - } - - LLStrider vertex_strider; - LLStrider normal_strider; - LLStrider tc_strider; - LLStrider index_strider; - - mVertexBuffer->getVertexStrider(vertex_strider); - mVertexBuffer->getNormalStrider(normal_strider); - mVertexBuffer->getTexCoord0Strider(tc_strider); - mVertexBuffer->getIndexStrider(index_strider); - - // build vertices and normals - LLStrider pos; - pos = (LLVector3*) vf.mPositions; pos.setStride(16); - LLStrider norm; - norm = (LLVector3*) vf.mNormals; norm.setStride(16); - LLStrider tc; - tc = (LLVector2*) vf.mTexCoords; tc.setStride(8); - - for (U32 i = 0; i < num_vertices; i++) - { - *(vertex_strider++) = *pos++; - LLVector3 normal = *norm++; - normal.normalize(); - *(normal_strider++) = normal; - *(tc_strider++) = *tc++; - } - - // build indices - for (U16 i = 0; i < num_indices; i++) - { - *(index_strider++) = vf.mIndices[i]; - } +{ + mCameraDistance = distance; + mCameraZoom = 1.f; + mCameraPitch = 0.f; + mCameraYaw = 0.f; + mCameraOffset.clearVec(); + + if (imagep) + { + mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false); + } + + const LLVolumeFace &vf = mVolume->getVolumeFace(0); + U32 num_indices = vf.mNumIndices; + U32 num_vertices = vf.mNumVertices; + + mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to" + << num_vertices << " vertices and " + << num_indices << " indices" << LL_ENDL; + // We are likely to crash on getTexCoord0Strider() + } + + LLStrider vertex_strider; + LLStrider normal_strider; + LLStrider tc_strider; + LLStrider index_strider; + + mVertexBuffer->getVertexStrider(vertex_strider); + mVertexBuffer->getNormalStrider(normal_strider); + mVertexBuffer->getTexCoord0Strider(tc_strider); + mVertexBuffer->getIndexStrider(index_strider); + + // build vertices and normals + LLStrider pos; + pos = (LLVector3*) vf.mPositions; pos.setStride(16); + LLStrider norm; + norm = (LLVector3*) vf.mNormals; norm.setStride(16); + LLStrider tc; + tc = (LLVector2*) vf.mTexCoords; tc.setStride(8); + + for (U32 i = 0; i < num_vertices; i++) + { + *(vertex_strider++) = *pos++; + LLVector3 normal = *norm++; + normal.normalize(); + *(normal_strider++) = normal; + *(tc_strider++) = *tc++; + } + + // build indices + for (U16 i = 0; i < num_indices; i++) + { + *(index_strider++) = vf.mIndices[i]; + } mVertexBuffer->unmapBuffer(); } @@ -857,82 +857,82 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) //----------------------------------------------------------------------------- BOOL LLImagePreviewSculpted::render() { - mNeedsUpdate = FALSE; - LLGLSUIDefault def; - LLGLDisable no_blend(GL_BLEND); - LLGLEnable cull(GL_CULL_FACE); - LLGLDepthTest depth(GL_TRUE); + mNeedsUpdate = FALSE; + LLGLSUIDefault def; + LLGLDisable no_blend(GL_BLEND); + LLGLEnable cull(GL_CULL_FACE); + LLGLDepthTest depth(GL_TRUE); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - - gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); - gUIProgram.bind(); + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mFullWidth, mFullHeight ); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); + gUIProgram.bind(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gl_rect_2d_simple( mFullWidth, mFullHeight ); - glClear(GL_DEPTH_BUFFER_BIT); - - LLVector3 target_pos(0, 0, 0); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); - LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * - LLQuaternion(mCameraYaw, LLVector3::z_axis); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); - LLQuaternion av_rot = camera_rot; - LLViewerCamera::getInstance()->setOriginAndLookAt( - target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera - LLVector3::z_axis, // up - target_pos + (mCameraOffset * av_rot) ); // point of interest + glClear(GL_DEPTH_BUFFER_BIT); - stop_glerror(); + LLVector3 target_pos(0, 0, 0); - LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight); - LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * + LLQuaternion(mCameraYaw, LLVector3::z_axis); - const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mNumIndices; - - gPipeline.enableLightsAvatar(); + LLQuaternion av_rot = camera_rot; + LLViewerCamera::getInstance()->setOriginAndLookAt( + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos + (mCameraOffset * av_rot) ); // point of interest - gObjectPreviewProgram.bind(); - gPipeline.enableLightsPreview(); + stop_glerror(); - gGL.pushMatrix(); - const F32 SCALE = 1.25f; - gGL.scalef(SCALE, SCALE, SCALE); - const F32 BRIGHTNESS = 0.9f; - gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); - mVertexBuffer->setBuffer(); - mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); + const LLVolumeFace &vf = mVolume->getVolumeFace(0); + U32 num_indices = vf.mNumIndices; - gGL.popMatrix(); + gPipeline.enableLightsAvatar(); - gObjectPreviewProgram.unbind(); + gObjectPreviewProgram.bind(); + gPipeline.enableLightsPreview(); - return TRUE; + gGL.pushMatrix(); + const F32 SCALE = 1.25f; + gGL.scalef(SCALE, SCALE, SCALE); + const F32 BRIGHTNESS = 0.9f; + gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + + mVertexBuffer->setBuffer(); + mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); + + gGL.popMatrix(); + + gObjectPreviewProgram.unbind(); + + return TRUE; } //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- void LLImagePreviewSculpted::refresh() -{ - mNeedsUpdate = TRUE; +{ + mNeedsUpdate = TRUE; } //----------------------------------------------------------------------------- @@ -940,9 +940,9 @@ void LLImagePreviewSculpted::refresh() //----------------------------------------------------------------------------- void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians) { - mCameraYaw = mCameraYaw + yaw_radians; + mCameraYaw = mCameraYaw + yaw_radians; - mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); + mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); } //----------------------------------------------------------------------------- @@ -950,11 +950,11 @@ void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians) //----------------------------------------------------------------------------- void LLImagePreviewSculpted::zoom(F32 zoom_amt) { - mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); + mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); } void LLImagePreviewSculpted::pan(F32 right, F32 up) { - mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); - mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); + mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); + mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); } diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index 426dd926ae..6cd5bb4ca7 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -1,25 +1,25 @@ -/** +/** * @file llfloaterimagepreview.h * @brief LLFloaterImagePreview class definition * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,104 +43,104 @@ class LLVolume; class LLImagePreviewSculpted : public LLViewerDynamicTexture { protected: - virtual ~LLImagePreviewSculpted(); + virtual ~LLImagePreviewSculpted(); public: - LLImagePreviewSculpted(S32 width, S32 height); + LLImagePreviewSculpted(S32 width, S32 height); - S8 getType() const override; + S8 getType() const override; - void setPreviewTarget(LLImageRaw *imagep, F32 distance); - void setTexture(U32 name) { mTextureName = name; } + void setPreviewTarget(LLImageRaw *imagep, F32 distance); + void setTexture(U32 name) { mTextureName = name; } - BOOL render() override; - void refresh(); - void rotate(F32 yaw_radians, F32 pitch_radians); - void zoom(F32 zoom_amt); - void pan(F32 right, F32 up); - virtual BOOL needsRender() override { return mNeedsUpdate; } + BOOL render() override; + void refresh(); + void rotate(F32 yaw_radians, F32 pitch_radians); + void zoom(F32 zoom_amt); + void pan(F32 right, F32 up); + virtual BOOL needsRender() override { return mNeedsUpdate; } protected: - BOOL mNeedsUpdate; - U32 mTextureName; - F32 mCameraDistance; - F32 mCameraYaw; - F32 mCameraPitch; - F32 mCameraZoom; - LLVector3 mCameraOffset; - LLPointer mVolume; - LLPointer mVertexBuffer; + BOOL mNeedsUpdate; + U32 mTextureName; + F32 mCameraDistance; + F32 mCameraYaw; + F32 mCameraPitch; + F32 mCameraZoom; + LLVector3 mCameraOffset; + LLPointer mVolume; + LLPointer mVertexBuffer; }; class LLImagePreviewAvatar : public LLViewerDynamicTexture { protected: - virtual ~LLImagePreviewAvatar(); + virtual ~LLImagePreviewAvatar(); public: - LLImagePreviewAvatar(S32 width, S32 height); + LLImagePreviewAvatar(S32 width, S32 height); - S8 getType() const override; + S8 getType() const override; - void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male); - void setTexture(U32 name) { mTextureName = name; } - void clearPreviewTexture(const std::string& mesh_name); + void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male); + void setTexture(U32 name) { mTextureName = name; } + void clearPreviewTexture(const std::string& mesh_name); - BOOL render() override; - void refresh(); - void rotate(F32 yaw_radians, F32 pitch_radians); - void zoom(F32 zoom_amt); - void pan(F32 right, F32 up); - virtual BOOL needsRender() override { return mNeedsUpdate; } + BOOL render() override; + void refresh(); + void rotate(F32 yaw_radians, F32 pitch_radians); + void zoom(F32 zoom_amt); + void pan(F32 right, F32 up); + virtual BOOL needsRender() override { return mNeedsUpdate; } protected: - BOOL mNeedsUpdate; - LLJoint* mTargetJoint; - LLViewerJointMesh* mTargetMesh; - F32 mCameraDistance; - F32 mCameraYaw; - F32 mCameraPitch; - F32 mCameraZoom; - LLVector3 mCameraOffset; - LLPointer mDummyAvatar; - U32 mTextureName; + BOOL mNeedsUpdate; + LLJoint* mTargetJoint; + LLViewerJointMesh* mTargetMesh; + F32 mCameraDistance; + F32 mCameraYaw; + F32 mCameraPitch; + F32 mCameraZoom; + LLVector3 mCameraOffset; + LLPointer mDummyAvatar; + U32 mTextureName; }; class LLFloaterImagePreview : public LLFloaterNameDesc { public: - LLFloaterImagePreview(const std::string& filename); - virtual ~LLFloaterImagePreview(); + LLFloaterImagePreview(const std::string& filename); + virtual ~LLFloaterImagePreview(); - BOOL postBuild() override; + BOOL postBuild() override; S32 getExpectedUploadCost() const override; - - BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; - BOOL handleMouseUp(S32 x, S32 y, MASK mask) override; - BOOL handleHover(S32 x, S32 y, MASK mask) override; - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override; - static void onMouseCaptureLostImagePreview(LLMouseHandler*); + BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; + BOOL handleMouseUp(S32 x, S32 y, MASK mask) override; + BOOL handleHover(S32 x, S32 y, MASK mask) override; + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override; + + static void onMouseCaptureLostImagePreview(LLMouseHandler*); - void clearAllPreviewTextures(); + void clearAllPreviewTextures(); protected: - static void onPreviewTypeCommit(LLUICtrl*,void*); - void draw() override; - bool loadImage(const std::string& filename); - - LLPointer mRawImagep; - LLPointer mAvatarPreview; - LLPointer mSculptedPreview; - S32 mLastMouseX; - S32 mLastMouseY; - LLRect mPreviewRect; - LLRectf mPreviewImageRect; - LLPointer mImagep ; - - std::string mImageLoadError; + static void onPreviewTypeCommit(LLUICtrl*,void*); + void draw() override; + bool loadImage(const std::string& filename); + + LLPointer mRawImagep; + LLPointer mAvatarPreview; + LLPointer mSculptedPreview; + S32 mLastMouseX; + S32 mLastMouseY; + LLRect mPreviewRect; + LLRectf mPreviewImageRect; + LLPointer mImagep ; + + std::string mImageLoadError; }; #endif // LL_LLFLOATERIMAGEPREVIEW_H diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h index cf3b512fab..4b3a9b536d 100644 --- a/indra/newview/llfloaternamedesc.h +++ b/indra/newview/llfloaternamedesc.h @@ -1,25 +1,25 @@ -/** +/** * @file llfloaternamedesc.h * @brief LLFloaterNameDesc class definition * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,46 +39,46 @@ class LLRadioGroup; class LLFloaterNameDesc : public LLFloater { public: - LLFloaterNameDesc(const LLSD& filename); - virtual ~LLFloaterNameDesc(); - virtual BOOL postBuild(); - - void onBtnOK(); - void onBtnCancel(); - void doCommit(); + LLFloaterNameDesc(const LLSD& filename); + virtual ~LLFloaterNameDesc(); + virtual BOOL postBuild(); + + void onBtnOK(); + void onBtnCancel(); + void doCommit(); + + virtual S32 getExpectedUploadCost() const; - virtual S32 getExpectedUploadCost() const; - protected: - virtual void onCommit(); + virtual void onCommit(); protected: - BOOL mIsAudio; - bool mIsText; + BOOL mIsAudio; + bool mIsText; - std::string mFilenameAndPath; - std::string mFilename; + std::string mFilenameAndPath; + std::string mFilename; }; class LLFloaterSoundPreview : public LLFloaterNameDesc { public: - LLFloaterSoundPreview(const LLSD& filename ); - virtual BOOL postBuild(); + LLFloaterSoundPreview(const LLSD& filename ); + virtual BOOL postBuild(); }; class LLFloaterAnimPreview : public LLFloaterNameDesc { public: - LLFloaterAnimPreview(const LLSD& filename ); - virtual BOOL postBuild(); + LLFloaterAnimPreview(const LLSD& filename ); + virtual BOOL postBuild(); }; class LLFloaterScriptPreview : public LLFloaterNameDesc { public: - LLFloaterScriptPreview(const LLSD& filename ); - virtual BOOL postBuild(); + LLFloaterScriptPreview(const LLSD& filename ); + virtual BOOL postBuild(); }; #endif // LL_LLFLOATERNAMEDESC_H diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 9ce7a07ee4..8d2efc79db 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llfloaterregioninfo.cpp * @author Aaron Brashears * @brief Implementation of the region info and controls floater and panels. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -50,13 +50,13 @@ #include "llavataractions.h" #include "llavatarname.h" #include "llfloateravatarpicker.h" -#include "llbutton.h" +#include "llbutton.h" #include "llcheckboxctrl.h" #include "llclipboard.h" #include "llcombobox.h" #include "llestateinfomodel.h" #include "llfilepicker.h" -#include "llfloatergodtools.h" // for send_sim_wide_deletes() +#include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" #include "llfloaterreg.h" @@ -113,70 +113,70 @@ const U32 MAX_LISTED_NAMES = 100; class LLDispatchEstateUpdateInfo : public LLDispatchHandler { public: - LLDispatchEstateUpdateInfo() {} - virtual ~LLDispatchEstateUpdateInfo() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); + LLDispatchEstateUpdateInfo() {} + virtual ~LLDispatchEstateUpdateInfo() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); }; class LLDispatchSetEstateAccess : public LLDispatchHandler { public: - LLDispatchSetEstateAccess() {} - virtual ~LLDispatchSetEstateAccess() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); + LLDispatchSetEstateAccess() {} + virtual ~LLDispatchSetEstateAccess() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); }; class LLDispatchSetEstateExperience : public LLDispatchHandler { public: - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); - static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count ); + static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count ); }; /* void unpack_request_params( - LLMessageSystem* msg, - LLDispatcher::sparam_t& strings, - LLDispatcher::iparam_t& integers) -{ - char str_buf[MAX_STRING]; - S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); - S32 i; - for (i = 0; i < str_count; ++i) - { - // we treat the SParam as binary data (since it might be an - // LLUUID in compressed form which may have embedded \0's,) - str_buf[0] = '\0'; - S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); - if (data_size >= 0) - { - msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, - str_buf, data_size, i, MAX_STRING - 1); - strings.push_back(std::string(str_buf, data_size)); - } - } - - U32 int_buf; - S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); - for (i = 0; i < int_count; ++i) - { - msg->getU32("IntegerData", "IParam", int_buf, i); - integers.push_back(int_buf); - } + LLMessageSystem* msg, + LLDispatcher::sparam_t& strings, + LLDispatcher::iparam_t& integers) +{ + char str_buf[MAX_STRING]; + S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); + S32 i; + for (i = 0; i < str_count; ++i) + { + // we treat the SParam as binary data (since it might be an + // LLUUID in compressed form which may have embedded \0's,) + str_buf[0] = '\0'; + S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); + if (data_size >= 0) + { + msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, + str_buf, data_size, i, MAX_STRING - 1); + strings.push_back(std::string(str_buf, data_size)); + } + } + + U32 int_buf; + S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); + for (i = 0; i < int_count; ++i) + { + msg->getU32("IntegerData", "IParam", int_buf, i); + integers.push_back(int_buf); + } } */ @@ -228,75 +228,75 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice; LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) - : LLFloater(seed), + : LLFloater(seed), mEnvironmentPanel(NULL), mRegionChangedCallback() {} BOOL LLFloaterRegionInfo::postBuild() { - mTab = getChild("region_panels"); - mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2)); - - // contruct the panels - LLPanelRegionInfo* panel; - panel = new LLPanelEstateInfo; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_estate.xml"); - mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); - - panel = new LLPanelEstateAccess; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_access.xml"); - mTab->addTabPanel(panel); - - panel = new LLPanelEstateCovenant; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_covenant.xml"); - mTab->addTabPanel(panel); - - panel = new LLPanelRegionGeneralInfo; - mInfoPanels.push_back(panel); - panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub", boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel)); - panel->buildFromFile("panel_region_general.xml"); - mTab->addTabPanel(panel); - - panel = new LLPanelRegionTerrainInfo; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_terrain.xml"); - mTab->addTabPanel(panel); + mTab = getChild("region_panels"); + mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2)); + + // contruct the panels + LLPanelRegionInfo* panel; + panel = new LLPanelEstateInfo; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_estate.xml"); + mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); + + panel = new LLPanelEstateAccess; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_access.xml"); + mTab->addTabPanel(panel); + + panel = new LLPanelEstateCovenant; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_covenant.xml"); + mTab->addTabPanel(panel); + + panel = new LLPanelRegionGeneralInfo; + mInfoPanels.push_back(panel); + panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub", boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel)); + panel->buildFromFile("panel_region_general.xml"); + mTab->addTabPanel(panel); + + panel = new LLPanelRegionTerrainInfo; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_terrain.xml"); + mTab->addTabPanel(panel); mEnvironmentPanel = new LLPanelRegionEnvironment; mEnvironmentPanel->buildFromFile("panel_region_environment.xml"); // mEnvironmentPanel->configureForRegion(); mTab->addTabPanel(mEnvironmentPanel); - panel = new LLPanelRegionDebugInfo; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_debug.xml"); - mTab->addTabPanel(panel); + panel = new LLPanelRegionDebugInfo; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_debug.xml"); + mTab->addTabPanel(panel); + + if(gDisconnected) + { + return TRUE; + } - if(gDisconnected) - { - return TRUE; - } + if(!gAgent.getRegionCapability("RegionExperiences").empty()) + { + panel = new LLPanelRegionExperiences; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_experiences.xml"); + mTab->addTabPanel(panel); + } - if(!gAgent.getRegionCapability("RegionExperiences").empty()) - { - panel = new LLPanelRegionExperiences; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_experiences.xml"); - mTab->addTabPanel(panel); - } - - gMessageSystem->setHandlerFunc( - "EstateOwnerMessage", - &processEstateOwnerRequest); + gMessageSystem->setHandlerFunc( + "EstateOwnerMessage", + &processEstateOwnerRequest); - // Request region info when agent region changes. - mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this)); + // Request region info when agent region changes. + mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this)); - return TRUE; + return TRUE; } LLFloaterRegionInfo::~LLFloaterRegionInfo() @@ -309,26 +309,26 @@ LLFloaterRegionInfo::~LLFloaterRegionInfo() void LLFloaterRegionInfo::onOpen(const LLSD& key) { - if(gDisconnected) - { - disableTabCtrls(); - return; - } - refreshFromRegion(gAgent.getRegion()); - requestRegionInfo(); + if(gDisconnected) + { + disableTabCtrls(); + return; + } + refreshFromRegion(gAgent.getRegion()); + requestRegionInfo(); - if (!mGodLevelChangeSlot.connected()) - { - mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1)); - } + if (!mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1)); + } } void LLFloaterRegionInfo::onClose(bool app_quitting) { - if (mGodLevelChangeSlot.connected()) - { - mGodLevelChangeSlot.disconnect(); - } + if (mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot.disconnect(); + } } void LLFloaterRegionInfo::onRegionChanged() @@ -341,266 +341,266 @@ void LLFloaterRegionInfo::onRegionChanged() void LLFloaterRegionInfo::requestRegionInfo() { - LLTabContainer* tab = findChild("region_panels"); - if (tab) - { - tab->getChild("General")->setCtrlsEnabled(FALSE); - tab->getChild("Debug")->setCtrlsEnabled(FALSE); - tab->getChild("Terrain")->setCtrlsEnabled(FALSE); - tab->getChild("Estate")->setCtrlsEnabled(FALSE); + LLTabContainer* tab = findChild("region_panels"); + if (tab) + { + tab->getChild("General")->setCtrlsEnabled(FALSE); + tab->getChild("Debug")->setCtrlsEnabled(FALSE); + tab->getChild("Terrain")->setCtrlsEnabled(FALSE); + tab->getChild("Estate")->setCtrlsEnabled(FALSE); tab->getChild("Access")->setCtrlsEnabled(FALSE); - } + } - // Must allow anyone to request the RegionInfo data - // so non-owners/non-gods can see the values. - // Therefore can't use an EstateOwnerMessage JC - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("RequestRegionInfo"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - gAgent.sendReliableMessage(); + // Must allow anyone to request the RegionInfo data + // so non-owners/non-gods can see the values. + // Therefore can't use an EstateOwnerMessage JC + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("RequestRegionInfo"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + gAgent.sendReliableMessage(); } // static void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) { - static LLDispatcher dispatch; - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if(!floater) - { - return; - } - - if (!estate_dispatch_initialized) - { - LLPanelEstateInfo::initDispatch(dispatch); - } - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - - // unpack the message - std::string request; - LLUUID invoice; - LLDispatcher::sparam_t strings; - LLDispatcher::unpackMessage(msg, request, invoice, strings); - if(invoice != getLastInvoice()) - { - LL_WARNS() << "Mismatched Estate message: " << request << LL_ENDL; - return; - } - - //dispatch the message - dispatch.dispatch(request, invoice, strings); - - if (panel) - { - panel->updateControls(gAgent.getRegion()); - } + static LLDispatcher dispatch; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if(!floater) + { + return; + } + + if (!estate_dispatch_initialized) + { + LLPanelEstateInfo::initDispatch(dispatch); + } + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + + // unpack the message + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + if(invoice != getLastInvoice()) + { + LL_WARNS() << "Mismatched Estate message: " << request << LL_ENDL; + return; + } + + //dispatch the message + dispatch.dispatch(request, invoice, strings); + + if (panel) + { + panel->updateControls(gAgent.getRegion()); + } } // static void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { - LLPanel* panel; - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if(!floater) - { - return; - } + LLPanel* panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if(!floater) + { + return; + } #if 0 - // We need to re-request environment setting here, - // otherwise after we apply (send) updated region settings we won't get them back, - // so our environment won't be updated. - // This is also the way to know about externally changed region environment. - LLEnvManagerNew::instance().requestRegionSettings(); -#endif - LLTabContainer* tab = floater->getChild("region_panels"); - - LLViewerRegion* region = gAgent.getRegion(); - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - - // *TODO: Replace parsing msg with accessing the region info model. - LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); - - // extract message - std::string sim_name; - std::string sim_type = LLTrans::getString("land_type_unknown"); - U64 region_flags; - U8 agent_limit; - S32 hard_agent_limit; - F32 object_bonus_factor; - U8 sim_access; - F32 water_height; - F32 terrain_raise_limit; - F32 terrain_lower_limit; - BOOL use_estate_sun; - F32 sun_hour; - msg->getString("RegionInfo", "SimName", sim_name); - msg->getU8("RegionInfo", "MaxAgents", agent_limit); - msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit); - msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); - msg->getU8("RegionInfo", "SimAccess", sim_access); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); - msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); - // actually the "last set" sun hour, not the current sun hour. JC - msg->getF32("RegionInfo", "SunHour", sun_hour); - // the only reasonable way to decide if we actually have any data is to - // check to see if any of these fields have nonzero sizes - if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || - msg->getSize("RegionInfo2", "ProductName") > 0) - { - msg->getString("RegionInfo2", "ProductName", sim_type); - LLTrans::findString(sim_type, sim_type); // try localizing sim product name - } - - if (msg->has(_PREHASH_RegionInfo3)) - { - msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags); - } - else - { - U32 flags = 0; - msg->getU32("RegionInfo", "RegionFlags", flags); - region_flags = flags; - } - - if (msg->has(_PREHASH_RegionInfo5)) - { - F32 chat_whisper_range; - F32 chat_normal_range; - F32 chat_shout_range; - F32 chat_whisper_offset; - F32 chat_normal_offset; - F32 chat_shout_offset; - U32 chat_flags; - - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range); - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range); - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range); - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset); - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset); - msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset); - msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags); - - LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range - << " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset - << " chat flags: " << chat_flags << LL_ENDL; - } - - // GENERAL PANEL - panel = tab->getChild("General"); - panel->getChild("region_text")->setValue(LLSD(sim_name)); - panel->getChild("region_type")->setValue(LLSD(sim_type)); - panel->getChild("version_channel_text")->setValue(gLastVersionChannel); - - panel->getChild("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); - panel->getChild("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); - panel->getChild("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE ); - panel->getChild("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); - panel->getChild("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); - panel->getChild("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); - panel->getChild("allow_parcel_changes_check")->setValue((region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); - panel->getChild("block_parcel_search_check")->setValue((region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); - panel->getChild("agent_limit_spin")->setValue(LLSD((F32)agent_limit) ); - panel->getChild("object_bonus_spin")->setValue(LLSD(object_bonus_factor) ); - panel->getChild("access_combo")->setValue(LLSD(sim_access) ); - - panel->getChild("agent_limit_spin")->setMaxValue(hard_agent_limit); - - LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral(); - if (panel) - { - panel_general->setObjBonusFactor(object_bonus_factor); - } - - // detect teen grid for maturity - - U32 parent_estate_id; - msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); - BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that - panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); - panel->setCtrlsEnabled(allow_modify); - - - // DEBUG PANEL - panel = tab->getChild("Debug"); - - panel->getChild("region_text")->setValue(LLSD(sim_name) ); - panel->getChild("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) ); - panel->getChild("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) ); - panel->getChild("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) ); - panel->setCtrlsEnabled(allow_modify); - - // TERRAIN PANEL - panel = tab->getChild("Terrain"); - - panel->getChild("region_text")->setValue(LLSD(sim_name)); - panel->getChild("water_height_spin")->setValue(region_info.mWaterHeight); - panel->getChild("terrain_raise_spin")->setValue(region_info.mTerrainRaiseLimit); - panel->getChild("terrain_lower_spin")->setValue(region_info.mTerrainLowerLimit); - - panel->setCtrlsEnabled(allow_modify); - - if (floater->getVisible()) - { - // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message - // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed' - floater->refreshFromRegion(gAgent.getRegion()); - } // else will rerequest on onOpen either way + // We need to re-request environment setting here, + // otherwise after we apply (send) updated region settings we won't get them back, + // so our environment won't be updated. + // This is also the way to know about externally changed region environment. + LLEnvManagerNew::instance().requestRegionSettings(); +#endif + LLTabContainer* tab = floater->getChild("region_panels"); + + LLViewerRegion* region = gAgent.getRegion(); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + // *TODO: Replace parsing msg with accessing the region info model. + LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); + + // extract message + std::string sim_name; + std::string sim_type = LLTrans::getString("land_type_unknown"); + U64 region_flags; + U8 agent_limit; + S32 hard_agent_limit; + F32 object_bonus_factor; + U8 sim_access; + F32 water_height; + F32 terrain_raise_limit; + F32 terrain_lower_limit; + BOOL use_estate_sun; + F32 sun_hour; + msg->getString("RegionInfo", "SimName", sim_name); + msg->getU8("RegionInfo", "MaxAgents", agent_limit); + msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit); + msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); + msg->getU8("RegionInfo", "SimAccess", sim_access); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); + msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); + // actually the "last set" sun hour, not the current sun hour. JC + msg->getF32("RegionInfo", "SunHour", sun_hour); + // the only reasonable way to decide if we actually have any data is to + // check to see if any of these fields have nonzero sizes + if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || + msg->getSize("RegionInfo2", "ProductName") > 0) + { + msg->getString("RegionInfo2", "ProductName", sim_type); + LLTrans::findString(sim_type, sim_type); // try localizing sim product name + } + + if (msg->has(_PREHASH_RegionInfo3)) + { + msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags); + } + else + { + U32 flags = 0; + msg->getU32("RegionInfo", "RegionFlags", flags); + region_flags = flags; + } + + if (msg->has(_PREHASH_RegionInfo5)) + { + F32 chat_whisper_range; + F32 chat_normal_range; + F32 chat_shout_range; + F32 chat_whisper_offset; + F32 chat_normal_offset; + F32 chat_shout_offset; + U32 chat_flags; + + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range); + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range); + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range); + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset); + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset); + msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset); + msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags); + + LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range + << " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset + << " chat flags: " << chat_flags << LL_ENDL; + } + + // GENERAL PANEL + panel = tab->getChild("General"); + panel->getChild("region_text")->setValue(LLSD(sim_name)); + panel->getChild("region_type")->setValue(LLSD(sim_type)); + panel->getChild("version_channel_text")->setValue(gLastVersionChannel); + + panel->getChild("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); + panel->getChild("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); + panel->getChild("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE ); + panel->getChild("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); + panel->getChild("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); + panel->getChild("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); + panel->getChild("allow_parcel_changes_check")->setValue((region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); + panel->getChild("block_parcel_search_check")->setValue((region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); + panel->getChild("agent_limit_spin")->setValue(LLSD((F32)agent_limit) ); + panel->getChild("object_bonus_spin")->setValue(LLSD(object_bonus_factor) ); + panel->getChild("access_combo")->setValue(LLSD(sim_access) ); + + panel->getChild("agent_limit_spin")->setMaxValue(hard_agent_limit); + + LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral(); + if (panel) + { + panel_general->setObjBonusFactor(object_bonus_factor); + } + + // detect teen grid for maturity + + U32 parent_estate_id; + msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); + BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that + panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); + panel->setCtrlsEnabled(allow_modify); + + + // DEBUG PANEL + panel = tab->getChild("Debug"); + + panel->getChild("region_text")->setValue(LLSD(sim_name) ); + panel->getChild("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) ); + panel->getChild("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) ); + panel->getChild("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) ); + panel->setCtrlsEnabled(allow_modify); + + // TERRAIN PANEL + panel = tab->getChild("Terrain"); + + panel->getChild("region_text")->setValue(LLSD(sim_name)); + panel->getChild("water_height_spin")->setValue(region_info.mWaterHeight); + panel->getChild("terrain_raise_spin")->setValue(region_info.mTerrainRaiseLimit); + panel->getChild("terrain_lower_spin")->setValue(region_info.mTerrainLowerLimit); + + panel->setCtrlsEnabled(allow_modify); + + if (floater->getVisible()) + { + // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message + // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed' + floater->refreshFromRegion(gAgent.getRegion()); + } // else will rerequest on onOpen either way } // static LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); - return panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); + return panel; } // static LLPanelEstateAccess* LLFloaterRegionInfo::getPanelAccess() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild("Access"); - return panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild("Access"); + return panel; } // static LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild("Covenant"); - return panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild("Covenant"); + return panel; } // static LLPanelRegionGeneralInfo* LLFloaterRegionInfo::getPanelGeneral() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelRegionGeneralInfo* panel = (LLPanelRegionGeneralInfo*)tab->getChild("General"); - return panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelRegionGeneralInfo* panel = (LLPanelRegionGeneralInfo*)tab->getChild("General"); + return panel; } // static LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelRegionEnvironment* panel = (LLPanelRegionEnvironment*)tab->getChild("panel_env_info"); - return panel; + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelRegionEnvironment* panel = (LLPanelRegionEnvironment*)tab->getChild("panel_env_info"); + return panel; } LLTerrainMaterials::Type material_type_from_ctrl(LLCheckBoxCtrl* ctrl) @@ -616,91 +616,91 @@ void material_type_to_ctrl(LLCheckBoxCtrl* ctrl, LLTerrainMaterials::Type new_ty // static LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) - { - llassert(floater); - return NULL; - } + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) + { + llassert(floater); + return NULL; + } - LLTabContainer* tab_container = floater->getChild("region_panels"); - LLPanelRegionTerrainInfo* panel = - dynamic_cast(tab_container->getChild("Terrain")); - llassert(panel); - return panel; + LLTabContainer* tab_container = floater->getChild("region_panels"); + LLPanelRegionTerrainInfo* panel = + dynamic_cast(tab_container->getChild("Terrain")); + llassert(panel); + return panel; } LLPanelRegionExperiences* LLFloaterRegionInfo::getPanelExperiences() { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild("region_panels"); - return (LLPanelRegionExperiences*)tab->getChild("Experiences"); + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + return (LLPanelRegionExperiences*)tab->getChild("Experiences"); } void LLFloaterRegionInfo::disableTabCtrls() { - LLTabContainer* tab = getChild("region_panels"); + LLTabContainer* tab = getChild("region_panels"); - tab->getChild("General")->setCtrlsEnabled(FALSE); - tab->getChild("Debug")->setCtrlsEnabled(FALSE); - tab->getChild("Terrain")->setCtrlsEnabled(FALSE); - tab->getChild("panel_env_info")->setCtrlsEnabled(FALSE); - tab->getChild("Estate")->setCtrlsEnabled(FALSE); - tab->getChild("Access")->setCtrlsEnabled(FALSE); + tab->getChild("General")->setCtrlsEnabled(FALSE); + tab->getChild("Debug")->setCtrlsEnabled(FALSE); + tab->getChild("Terrain")->setCtrlsEnabled(FALSE); + tab->getChild("panel_env_info")->setCtrlsEnabled(FALSE); + tab->getChild("Estate")->setCtrlsEnabled(FALSE); + tab->getChild("Access")->setCtrlsEnabled(FALSE); } void LLFloaterRegionInfo::onTabSelected(const LLSD& param) { - LLPanel* active_panel = getChild(param.asString()); - active_panel->onOpen(LLSD()); + LLPanel* active_panel = getChild(param.asString()); + active_panel->onOpen(LLSD()); } void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) { - if (!region) - { - return; - } + if (!region) + { + return; + } - // call refresh from region on all panels - for (const auto& infoPanel : mInfoPanels) - { - infoPanel->refreshFromRegion(region); - } - mEnvironmentPanel->refreshFromRegion(region); + // call refresh from region on all panels + for (const auto& infoPanel : mInfoPanels) + { + infoPanel->refreshFromRegion(region); + } + mEnvironmentPanel->refreshFromRegion(region); } // public void LLFloaterRegionInfo::refresh() { - for(info_panels_t::iterator iter = mInfoPanels.begin(); - iter != mInfoPanels.end(); ++iter) - { - (*iter)->refresh(); - } + for(info_panels_t::iterator iter = mInfoPanels.begin(); + iter != mInfoPanels.end(); ++iter) + { + (*iter)->refresh(); + } mEnvironmentPanel->refresh(); } void LLFloaterRegionInfo::enableTopButtons() { - getChildView("top_colliders_btn")->setEnabled(true); - getChildView("top_scripts_btn")->setEnabled(true); + getChildView("top_colliders_btn")->setEnabled(true); + getChildView("top_scripts_btn")->setEnabled(true); } void LLFloaterRegionInfo::disableTopButtons() { - getChildView("top_colliders_btn")->setEnabled(false); - getChildView("top_scripts_btn")->setEnabled(false); + getChildView("top_colliders_btn")->setEnabled(false); + getChildView("top_scripts_btn")->setEnabled(false); } void LLFloaterRegionInfo::onGodLevelChange(U8 god_level) { - LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); - if (floater && floater->getVisible()) - { - refreshFromRegion(gAgent.getRegion()); - } + LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance("region_info"); + if (floater && floater->getVisible()) + { + refreshFromRegion(gAgent.getRegion()); + } } ///---------------------------------------------------------------------------- @@ -712,58 +712,58 @@ void LLFloaterRegionInfo::onGodLevelChange(U8 god_level) // LLPanelRegionInfo::LLPanelRegionInfo() - : LLPanel() + : LLPanel() { } void LLPanelRegionInfo::onBtnSet() { - if (sendUpdate()) - { - disableButton("apply_btn"); - } + if (sendUpdate()) + { + disableButton("apply_btn"); + } } void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl) { - updateChild(ctrl); // virtual function + updateChild(ctrl); // virtual function } // Enables the "set" button if it is not already enabled void LLPanelRegionInfo::onChangeAnything() { - enableButton("apply_btn"); - refresh(); + enableButton("apply_btn"); + refresh(); } // static // Enables set button on change to line editor void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) { - LLPanelRegionInfo* panel = dynamic_cast(caller->getParent()); - if(panel) - { - panel->enableButton("apply_btn"); - panel->refresh(); - } + LLPanelRegionInfo* panel = dynamic_cast(caller->getParent()); + if(panel) + { + panel->enableButton("apply_btn"); + panel->refresh(); + } } // virtual BOOL LLPanelRegionInfo::postBuild() { - // If the panel has an Apply button, set a callback for it. - LLUICtrl* apply_btn = findChild("apply_btn"); - if (apply_btn) - { - apply_btn->setCommitCallback(boost::bind(&LLPanelRegionInfo::onBtnSet, this)); - } + // If the panel has an Apply button, set a callback for it. + LLUICtrl* apply_btn = findChild("apply_btn"); + if (apply_btn) + { + apply_btn->setCommitCallback(boost::bind(&LLPanelRegionInfo::onBtnSet, this)); + } - refresh(); - return TRUE; + refresh(); + return TRUE; } -// virtual +// virtual void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) { } @@ -771,64 +771,64 @@ void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) // virtual bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) { - if (region) mHost = region->getHost(); - return true; + if (region) mHost = region->getHost(); + return true; } void LLPanelRegionInfo::sendEstateOwnerMessage( - LLMessageSystem* msg, - const std::string& request, - const LLUUID& invoice, - const strings_t& strings) -{ - LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", request); - msg->addUUID("Invoice", invoice); - if(strings.empty()) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", NULL); - } - else - { - strings_t::const_iterator it = strings.begin(); - strings_t::const_iterator end = strings.end(); - for(; it != end; ++it) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", *it); - } - } - msg->sendReliable(mHost); + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings) +{ + LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", request); + msg->addUUID("Invoice", invoice); + if(strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + strings_t::const_iterator it = strings.begin(); + strings_t::const_iterator end = strings.end(); + for(; it != end; ++it) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", *it); + } + } + msg->sendReliable(mHost); } void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable) { - LLView* button = findChildView(btn_name); - if (button) button->setEnabled(enable); + LLView* button = findChildView(btn_name); + if (button) button->setEnabled(enable); } void LLPanelRegionInfo::disableButton(const std::string& btn_name) { - LLView* button = findChildView(btn_name); - if (button) button->setEnabled(FALSE); + LLView* button = findChildView(btn_name); + if (button) button->setEnabled(FALSE); } void LLPanelRegionInfo::initCtrl(const std::string& name) { - getChild(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this)); + getChild(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this)); } void LLPanelRegionInfo::onClickManageTelehub() { - LLFloaterReg::hideInstance("region_info"); - LLFloaterReg::showInstance("telehubs"); + LLFloaterReg::hideInstance("region_info"); + LLFloaterReg::showInstance("telehubs"); } ///////////////////////////////////////////////////////////////////////////// @@ -836,181 +836,181 @@ void LLPanelRegionInfo::onClickManageTelehub() // bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) { - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - getChildView("apply_btn")->setEnabled(FALSE); - getChildView("access_text")->setEnabled(allow_modify); - // getChildView("access_combo")->setEnabled(allow_modify); - // now set in processRegionInfo for teen grid detection - getChildView("kick_btn")->setEnabled(allow_modify); - getChildView("kick_all_btn")->setEnabled(allow_modify); - getChildView("im_btn")->setEnabled(allow_modify); - getChildView("manage_telehub_btn")->setEnabled(allow_modify); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + getChildView("apply_btn")->setEnabled(FALSE); + getChildView("access_text")->setEnabled(allow_modify); + // getChildView("access_combo")->setEnabled(allow_modify); + // now set in processRegionInfo for teen grid detection + getChildView("kick_btn")->setEnabled(allow_modify); + getChildView("kick_all_btn")->setEnabled(allow_modify); + getChildView("im_btn")->setEnabled(allow_modify); + getChildView("manage_telehub_btn")->setEnabled(allow_modify); - // Data gets filled in by processRegionInfo + // Data gets filled in by processRegionInfo - return LLPanelRegionInfo::refreshFromRegion(region); + return LLPanelRegionInfo::refreshFromRegion(region); } BOOL LLPanelRegionGeneralInfo::postBuild() { - // Enable the "Apply" button if something is changed. JC - initCtrl("block_terraform_check"); - initCtrl("block_fly_check"); - initCtrl("block_fly_over_check"); - initCtrl("allow_damage_check"); - initCtrl("allow_land_resell_check"); - initCtrl("allow_parcel_changes_check"); - initCtrl("agent_limit_spin"); - initCtrl("object_bonus_spin"); - initCtrl("access_combo"); - initCtrl("restrict_pushobject"); - initCtrl("block_parcel_search_check"); - - childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this)); - childSetAction("kick_all_btn", onClickKickAll, this); - childSetAction("im_btn", onClickMessage, this); -// childSetAction("manage_telehub_btn", onClickManageTelehub, this); - - LLUICtrl* apply_btn = findChild("apply_btn"); - if (apply_btn) - { - apply_btn->setCommitCallback(boost::bind(&LLPanelRegionGeneralInfo::onBtnSet, this)); - } - - refresh(); - return TRUE; + // Enable the "Apply" button if something is changed. JC + initCtrl("block_terraform_check"); + initCtrl("block_fly_check"); + initCtrl("block_fly_over_check"); + initCtrl("allow_damage_check"); + initCtrl("allow_land_resell_check"); + initCtrl("allow_parcel_changes_check"); + initCtrl("agent_limit_spin"); + initCtrl("object_bonus_spin"); + initCtrl("access_combo"); + initCtrl("restrict_pushobject"); + initCtrl("block_parcel_search_check"); + + childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this)); + childSetAction("kick_all_btn", onClickKickAll, this); + childSetAction("im_btn", onClickMessage, this); +// childSetAction("manage_telehub_btn", onClickManageTelehub, this); + + LLUICtrl* apply_btn = findChild("apply_btn"); + if (apply_btn) + { + apply_btn->setCommitCallback(boost::bind(&LLPanelRegionGeneralInfo::onBtnSet, this)); + } + + refresh(); + return TRUE; } void LLPanelRegionGeneralInfo::onBtnSet() { - if(mObjBonusFactor == getChild("object_bonus_spin")->getValue().asReal()) - { - if (sendUpdate()) - { - disableButton("apply_btn"); - } - } - else - { - LLNotificationsUtil::add("ChangeObjectBonusFactor", LLSD(), LLSD(), boost::bind(&LLPanelRegionGeneralInfo::onChangeObjectBonus, this, _1, _2)); - } + if(mObjBonusFactor == getChild("object_bonus_spin")->getValue().asReal()) + { + if (sendUpdate()) + { + disableButton("apply_btn"); + } + } + else + { + LLNotificationsUtil::add("ChangeObjectBonusFactor", LLSD(), LLSD(), boost::bind(&LLPanelRegionGeneralInfo::onChangeObjectBonus, this, _1, _2)); + } } bool LLPanelRegionGeneralInfo::onChangeObjectBonus(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - if (sendUpdate()) - { - disableButton("apply_btn"); - } - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + if (sendUpdate()) + { + disableButton("apply_btn"); + } + } + return false; } void LLPanelRegionGeneralInfo::onClickKick() { - LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKick" << LL_ENDL; + LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKick" << LL_ENDL; - // this depends on the grandparent view being a floater - // in order to set up floater dependency + // this depends on the grandparent view being a floater + // in order to set up floater dependency LLView * button = findChild("kick_btn"); - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName(), button); - if (child_floater) - { - parent_floater->addDependentFloater(child_floater); - } + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids) { - if (ids.empty()) return; - if(ids[0].notNull()) - { - strings_t strings; - // [0] = our agent id - // [1] = target agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); + if (ids.empty()) return; + if(ids[0].notNull()) + { + strings_t strings; + // [0] = our agent id + // [1] = target agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); - ids[0].toString(buffer); - strings.push_back(strings_t::value_type(buffer)); + ids[0].toString(buffer); + strings.push_back(strings_t::value_type(buffer)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); - } + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); + } } // static void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata) { - LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKickAll" << LL_ENDL; - LLNotificationsUtil::add("KickUsersFromRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); + LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKickAll" << LL_ENDL; + LLNotificationsUtil::add("KickUsersFromRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); } bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - strings_t strings; - // [0] = our agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + strings_t strings; + // [0] = our agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - // historical message name - sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); - } - return false; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + // historical message name + sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); + } + return false; } // static void LLPanelRegionGeneralInfo::onClickMessage(void* userdata) { - LL_INFOS() << "LLPanelRegionGeneralInfo::onClickMessage" << LL_ENDL; - LLNotificationsUtil::add("MessageRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); + LL_INFOS() << "LLPanelRegionGeneralInfo::onClickMessage" << LL_ENDL; + LLNotificationsUtil::add("MessageRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); } // static bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response) { - if(LLNotificationsUtil::getSelectedOption(notification, response) != 0) return false; - - std::string text = response["message"].asString(); - if (text.empty()) return false; - - LL_INFOS() << "Message to everyone: " << text << LL_ENDL; - strings_t strings; - // [0] grid_x, unused here - // [1] grid_y, unused here - // [2] agent_id of sender - // [3] sender name - // [4] message - strings.push_back("-1"); - strings.push_back("-1"); - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - std::string name; - LLAgentUI::buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); - return false; + if(LLNotificationsUtil::getSelectedOption(notification, response) != 0) return false; + + std::string text = response["message"].asString(); + if (text.empty()) return false; + + LL_INFOS() << "Message to everyone: " << text << LL_ENDL; + strings_t strings; + // [0] grid_x, unused here + // [1] grid_y, unused here + // [2] agent_id of sender + // [3] sender name + // [4] message + strings.push_back("-1"); + strings.push_back("-1"); + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + std::string name; + LLAgentUI::buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); + return false; } // setregioninfo @@ -1026,74 +1026,74 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L // strings[9] = 'Y' - block parcel search, 'N' - allow BOOL LLPanelRegionGeneralInfo::sendUpdate() { - LL_INFOS() << "LLPanelRegionGeneralInfo::sendUpdate()" << LL_ENDL; - - // First try using a Cap. If that fails use the old method. - LLSD body; - std::string url = gAgent.getRegionCapability("DispatchRegionInfo"); - if (!url.empty()) - { - body["block_terraform"] = getChild("block_terraform_check")->getValue(); - body["block_fly"] = getChild("block_fly_check")->getValue(); - body["block_fly_over"] = getChild("block_fly_over_check")->getValue(); - body["allow_damage"] = getChild("allow_damage_check")->getValue(); - body["allow_land_resell"] = getChild("allow_land_resell_check")->getValue(); - body["agent_limit"] = getChild("agent_limit_spin")->getValue(); - body["prim_bonus"] = getChild("object_bonus_spin")->getValue(); - body["sim_access"] = getChild("access_combo")->getValue(); - body["restrict_pushobject"] = getChild("restrict_pushobject")->getValue(); - body["allow_parcel_changes"] = getChild("allow_parcel_changes_check")->getValue(); - body["block_parcel_search"] = getChild("block_parcel_search_check")->getValue(); + LL_INFOS() << "LLPanelRegionGeneralInfo::sendUpdate()" << LL_ENDL; + + // First try using a Cap. If that fails use the old method. + LLSD body; + std::string url = gAgent.getRegionCapability("DispatchRegionInfo"); + if (!url.empty()) + { + body["block_terraform"] = getChild("block_terraform_check")->getValue(); + body["block_fly"] = getChild("block_fly_check")->getValue(); + body["block_fly_over"] = getChild("block_fly_over_check")->getValue(); + body["allow_damage"] = getChild("allow_damage_check")->getValue(); + body["allow_land_resell"] = getChild("allow_land_resell_check")->getValue(); + body["agent_limit"] = getChild("agent_limit_spin")->getValue(); + body["prim_bonus"] = getChild("object_bonus_spin")->getValue(); + body["sim_access"] = getChild("access_combo")->getValue(); + body["restrict_pushobject"] = getChild("restrict_pushobject")->getValue(); + body["allow_parcel_changes"] = getChild("allow_parcel_changes_check")->getValue(); + body["block_parcel_search"] = getChild("block_parcel_search_check")->getValue(); LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, "Region info update posted.", "Region info update not posted."); - } - else - { - strings_t strings; - std::string buffer; + } + else + { + strings_t strings; + std::string buffer; - buffer = llformat("%s", (getChild("block_terraform_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("block_terraform_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%s", (getChild("block_fly_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("block_fly_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%s", (getChild("allow_damage_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("allow_damage_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%s", (getChild("allow_land_resell_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("allow_land_resell_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - F32 value = (F32)getChild("agent_limit_spin")->getValue().asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); + F32 value = (F32)getChild("agent_limit_spin")->getValue().asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); - value = (F32)getChild("object_bonus_spin")->getValue().asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); + value = (F32)getChild("object_bonus_spin")->getValue().asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%d", getChild("access_combo")->getValue().asInteger()); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%d", getChild("access_combo")->getValue().asInteger()); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%s", (getChild("restrict_pushobject")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("restrict_pushobject")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - buffer = llformat("%s", (getChild("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); + buffer = llformat("%s", (getChild("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); - } + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); + } - // if we changed access levels, tell user about it - LLViewerRegion* region = gAgent.getRegion(); - if (region && (getChild("access_combo")->getValue().asInteger() != region->getSimAccess()) ) - { - LLNotificationsUtil::add("RegionMaturityChange"); - } + // if we changed access levels, tell user about it + LLViewerRegion* region = gAgent.getRegion(); + if (region && (getChild("access_combo")->getValue().asInteger() != region->getSimAccess()) ) + { + LLNotificationsUtil::add("RegionMaturityChange"); + } - return TRUE; + return TRUE; } ///////////////////////////////////////////////////////////////////////////// @@ -1101,216 +1101,216 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate() ///////////////////////////////////////////////////////////////////////////// BOOL LLPanelRegionDebugInfo::postBuild() { - LLPanelRegionInfo::postBuild(); - initCtrl("disable_scripts_check"); - initCtrl("disable_collisions_check"); - initCtrl("disable_physics_check"); + LLPanelRegionInfo::postBuild(); + initCtrl("disable_scripts_check"); + initCtrl("disable_collisions_check"); + initCtrl("disable_physics_check"); - childSetAction("choose_avatar_btn", boost::bind(&LLPanelRegionDebugInfo::onClickChooseAvatar, this)); - childSetAction("return_btn", onClickReturn, this); - childSetAction("top_colliders_btn", onClickTopColliders, this); - childSetAction("top_scripts_btn", onClickTopScripts, this); - childSetAction("restart_btn", onClickRestart, this); - childSetAction("cancel_restart_btn", onClickCancelRestart, this); - childSetAction("region_debug_console_btn", onClickDebugConsole, this); + childSetAction("choose_avatar_btn", boost::bind(&LLPanelRegionDebugInfo::onClickChooseAvatar, this)); + childSetAction("return_btn", onClickReturn, this); + childSetAction("top_colliders_btn", onClickTopColliders, this); + childSetAction("top_scripts_btn", onClickTopScripts, this); + childSetAction("restart_btn", onClickRestart, this); + childSetAction("cancel_restart_btn", onClickCancelRestart, this); + childSetAction("region_debug_console_btn", onClickDebugConsole, this); - return TRUE; + return TRUE; } // virtual bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) { - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - getChildView("apply_btn")->setEnabled(FALSE); - getChildView("target_avatar_name")->setEnabled(FALSE); - - getChildView("choose_avatar_btn")->setEnabled(allow_modify); - getChildView("return_scripts")->setEnabled(allow_modify && !mTargetAvatar.isNull()); - getChildView("return_other_land")->setEnabled(allow_modify && !mTargetAvatar.isNull()); - getChildView("return_estate_wide")->setEnabled(allow_modify && !mTargetAvatar.isNull()); - getChildView("return_btn")->setEnabled(allow_modify && !mTargetAvatar.isNull()); - getChildView("top_colliders_btn")->setEnabled(allow_modify); - getChildView("top_scripts_btn")->setEnabled(allow_modify); - getChildView("restart_btn")->setEnabled(allow_modify); - getChildView("cancel_restart_btn")->setEnabled(allow_modify); - getChildView("region_debug_console_btn")->setEnabled(allow_modify); - - return LLPanelRegionInfo::refreshFromRegion(region); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + getChildView("apply_btn")->setEnabled(FALSE); + getChildView("target_avatar_name")->setEnabled(FALSE); + + getChildView("choose_avatar_btn")->setEnabled(allow_modify); + getChildView("return_scripts")->setEnabled(allow_modify && !mTargetAvatar.isNull()); + getChildView("return_other_land")->setEnabled(allow_modify && !mTargetAvatar.isNull()); + getChildView("return_estate_wide")->setEnabled(allow_modify && !mTargetAvatar.isNull()); + getChildView("return_btn")->setEnabled(allow_modify && !mTargetAvatar.isNull()); + getChildView("top_colliders_btn")->setEnabled(allow_modify); + getChildView("top_scripts_btn")->setEnabled(allow_modify); + getChildView("restart_btn")->setEnabled(allow_modify); + getChildView("cancel_restart_btn")->setEnabled(allow_modify); + getChildView("region_debug_console_btn")->setEnabled(allow_modify); + + return LLPanelRegionInfo::refreshFromRegion(region); } // virtual BOOL LLPanelRegionDebugInfo::sendUpdate() { - LL_INFOS() << "LLPanelRegionDebugInfo::sendUpdate" << LL_ENDL; - strings_t strings; - std::string buffer; + LL_INFOS() << "LLPanelRegionDebugInfo::sendUpdate" << LL_ENDL; + strings_t strings; + std::string buffer; - buffer = llformat("%s", (getChild("disable_scripts_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(buffer); + buffer = llformat("%s", (getChild("disable_scripts_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(buffer); - buffer = llformat("%s", (getChild("disable_collisions_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(buffer); + buffer = llformat("%s", (getChild("disable_collisions_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(buffer); - buffer = llformat("%s", (getChild("disable_physics_check")->getValue().asBoolean() ? "Y" : "N")); - strings.push_back(buffer); + buffer = llformat("%s", (getChild("disable_physics_check")->getValue().asBoolean() ? "Y" : "N")); + strings.push_back(buffer); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); - return TRUE; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); + return TRUE; } void LLPanelRegionDebugInfo::onClickChooseAvatar() { LLView * button = findChild("choose_avatar_btn"); LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), + LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, parent_floater->getName(), button); - if (child_floater) - { - parent_floater->addDependentFloater(child_floater); - } + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::vector names) { - if (ids.empty() || names.empty()) return; - mTargetAvatar = ids[0]; - getChild("target_avatar_name")->setValue(LLSD(names[0].getCompleteName())); - refreshFromRegion( gAgent.getRegion() ); + if (ids.empty() || names.empty()) return; + mTargetAvatar = ids[0]; + getChild("target_avatar_name")->setValue(LLSD(names[0].getCompleteName())); + refreshFromRegion( gAgent.getRegion() ); } // static void LLPanelRegionDebugInfo::onClickReturn(void* data) { - LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; - if (panelp->mTargetAvatar.isNull()) return; - - LLSD args; - args["USER_NAME"] = panelp->getChild("target_avatar_name")->getValue().asString(); - LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - - U32 flags = SWD_ALWAYS_RETURN_OBJECTS; - - if (panelp->getChild("return_scripts")->getValue().asBoolean()) - { - flags |= SWD_SCRIPTED_ONLY; - } - - if (panelp->getChild("return_other_land")->getValue().asBoolean()) - { - flags |= SWD_OTHERS_LAND_ONLY; - } - payload["flags"] = int(flags); - payload["return_estate_wide"] = panelp->getChild("return_estate_wide")->getValue().asBoolean(); - LLNotificationsUtil::add("EstateObjectReturn", args, payload, - boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); + LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; + if (panelp->mTargetAvatar.isNull()) return; + + LLSD args; + args["USER_NAME"] = panelp->getChild("target_avatar_name")->getValue().asString(); + LLSD payload; + payload["avatar_id"] = panelp->mTargetAvatar; + + U32 flags = SWD_ALWAYS_RETURN_OBJECTS; + + if (panelp->getChild("return_scripts")->getValue().asBoolean()) + { + flags |= SWD_SCRIPTED_ONLY; + } + + if (panelp->getChild("return_other_land")->getValue().asBoolean()) + { + flags |= SWD_OTHERS_LAND_ONLY; + } + payload["flags"] = int(flags); + payload["return_estate_wide"] = panelp->getChild("return_estate_wide")->getValue().asBoolean(); + LLNotificationsUtil::add("EstateObjectReturn", args, payload, + boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); } bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; - - LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); - if (!target_avatar.isNull()) - { - U32 flags = notification["payload"]["flags"].asInteger(); - bool return_estate_wide = notification["payload"]["return_estate_wide"]; - if (return_estate_wide) - { - // send as estate message - routed by spaceserver to all regions in estate - strings_t strings; - strings.push_back(llformat("%d", flags)); - strings.push_back(target_avatar.asString()); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); - } - else - { - // send to this simulator only - send_sim_wide_deletes(target_avatar, flags); - } - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; + + LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); + if (!target_avatar.isNull()) + { + U32 flags = notification["payload"]["flags"].asInteger(); + bool return_estate_wide = notification["payload"]["return_estate_wide"]; + if (return_estate_wide) + { + // send as estate message - routed by spaceserver to all regions in estate + strings_t strings; + strings.push_back(llformat("%d", flags)); + strings.push_back(target_avatar.asString()); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); + } + else + { + // send to this simulator only + send_sim_wide_deletes(target_avatar, flags); + } + } + return false; } // static void LLPanelRegionDebugInfo::onClickTopColliders(void* data) { - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("1"); // one physics step - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); - if(!instance) return; - LLFloaterReg::showInstance("top_objects"); - instance->clearList(); - instance->disableRefreshBtn(); + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("1"); // one physics step + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); + instance->disableRefreshBtn(); - self->getChildView("top_colliders_btn")->setEnabled(false); - self->getChildView("top_scripts_btn")->setEnabled(false); + self->getChildView("top_colliders_btn")->setEnabled(false); + self->getChildView("top_scripts_btn")->setEnabled(false); - self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); + self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } // static void LLPanelRegionDebugInfo::onClickTopScripts(void* data) { - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("6"); // top 5 scripts - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); - if(!instance) return; - LLFloaterReg::showInstance("top_objects"); - instance->clearList(); - instance->disableRefreshBtn(); + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("6"); // top 5 scripts + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); + if(!instance) return; + LLFloaterReg::showInstance("top_objects"); + instance->clearList(); + instance->disableRefreshBtn(); - self->getChildView("top_colliders_btn")->setEnabled(false); - self->getChildView("top_scripts_btn")->setEnabled(false); + self->getChildView("top_colliders_btn")->setEnabled(false); + self->getChildView("top_scripts_btn")->setEnabled(false); - self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); + self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } // static void LLPanelRegionDebugInfo::onClickRestart(void* data) { - LLNotificationsUtil::add("ConfirmRestart", LLSD(), LLSD(), - boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); + LLNotificationsUtil::add("ConfirmRestart", LLSD(), LLSD(), + boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); } bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; - strings_t strings; - strings.push_back("120"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); - return false; + strings_t strings; + strings.push_back("120"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); + return false; } // static void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) { - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("-1"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("-1"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); } // static void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) { - LLFloaterReg::showInstance("region_debug_console"); + LLFloaterReg::showInstance("region_debug_console"); } bool LLPanelRegionTerrainInfo::validateTextureSizes() @@ -1325,30 +1325,30 @@ bool LLPanelRegionTerrainInfo::validateTextureSizes() bool valid = true; static LLCachedControl max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); const S32 max_terrain_texture_size = (S32)max_texture_resolution; - for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) - { + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i]; - if (!texture_ctrl) continue; - - LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); - S32 components = img->getComponents(); - // Must ask for highest resolution version's width. JC - S32 width = img->getFullWidth(); - S32 height = img->getFullHeight(); - - //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL; - - if (components != 3 && components != 4) - { - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + if (!texture_ctrl) continue; + + LLUUID image_asset_id = texture_ctrl->getImageAssetID(); + LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); + S32 components = img->getComponents(); + // Must ask for highest resolution version's width. JC + S32 width = img->getFullWidth(); + S32 height = img->getFullHeight(); + + //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL; + + if (components != 3 && components != 4) + { + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); args["MAX_SIZE"] = max_terrain_texture_size; - LLNotificationsUtil::add("InvalidTerrainBitDepth", args); + LLNotificationsUtil::add("InvalidTerrainBitDepth", args); valid = false; - continue; - } + continue; + } if (components == 4) { @@ -1380,20 +1380,20 @@ bool LLPanelRegionTerrainInfo::validateTextureSizes() } } - if (width > max_terrain_texture_size || height > max_terrain_texture_size) - { + if (width > max_terrain_texture_size || height > max_terrain_texture_size) + { - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_SIZE_X"] = width; - args["TEXTURE_SIZE_Y"] = height; + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_SIZE_X"] = width; + args["TEXTURE_SIZE_Y"] = height; args["MAX_SIZE"] = max_terrain_texture_size; - LLNotificationsUtil::add("InvalidTerrainSize", args); - valid = false; - } - } + LLNotificationsUtil::add("InvalidTerrainSize", args); + valid = false; + } + } - return valid; + return valid; } bool LLPanelRegionTerrainInfo::validateMaterials() @@ -1470,18 +1470,18 @@ bool LLPanelRegionTerrainInfo::validateMaterials() BOOL LLPanelRegionTerrainInfo::validateTextureHeights() { - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - std::string low = llformat("height_start_spin_%d", i); - std::string high = llformat("height_range_spin_%d", i); + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + std::string low = llformat("height_start_spin_%d", i); + std::string high = llformat("height_range_spin_%d", i); - if (getChild(low)->getValue().asReal() > getChild(high)->getValue().asReal()) - { - return FALSE; - } - } + if (getChild(low)->getValue().asReal() > getChild(high)->getValue().asReal()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } ///////////////////////////////////////////////////////////////////////////// @@ -1506,46 +1506,46 @@ LLPanelRegionTerrainInfo::LLPanelRegionTerrainInfo() BOOL LLPanelRegionTerrainInfo::postBuild() { - LLPanelRegionInfo::postBuild(); - - initCtrl("water_height_spin"); - initCtrl("terrain_raise_spin"); - initCtrl("terrain_lower_spin"); + LLPanelRegionInfo::postBuild(); + + initCtrl("water_height_spin"); + initCtrl("terrain_raise_spin"); + initCtrl("terrain_lower_spin"); mMaterialTypeCtrl = findChild("terrain_material_type"); if (mMaterialTypeCtrl) { mMaterialTypeCtrl->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); } - std::string buffer; + std::string buffer; - for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - initCtrl(buffer); + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + initCtrl(buffer); mTextureDetailCtrl[i] = findChild(buffer); - } - for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - initCtrl(buffer); + } + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + initCtrl(buffer); mMaterialDetailCtrl[i] = findChild(buffer); - } + } - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - initCtrl(buffer); - buffer = llformat("height_range_spin_%d", i); - initCtrl(buffer); - } + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + initCtrl(buffer); + buffer = llformat("height_range_spin_%d", i); + initCtrl(buffer); + } - childSetAction("download_raw_btn", onClickDownloadRaw, this); - childSetAction("upload_raw_btn", onClickUploadRaw, this); - childSetAction("bake_terrain_btn", onClickBakeTerrain, this); + childSetAction("download_raw_btn", onClickDownloadRaw, this); + childSetAction("upload_raw_btn", onClickUploadRaw, this); + childSetAction("bake_terrain_btn", onClickBakeTerrain, this); - mAskedTextureHeights = false; - mConfirmedTextureHeights = false; + mAskedTextureHeights = false; + mConfirmedTextureHeights = false; - return LLPanelRegionInfo::postBuild(); + return LLPanelRegionInfo::postBuild(); } void LLPanelRegionTerrainInfo::onSelectMaterialType() @@ -1581,9 +1581,9 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() // Toggle visibility of labels LLUICtrl* texture_label = findChild("detail_texture_text"); - if (texture_label) { texture_label->setVisible(show_texture_controls); } + if (texture_label) { texture_label->setVisible(show_texture_controls); } LLUICtrl* material_label = findChild("detail_material_text"); - if (material_label) { material_label->setVisible(show_material_controls); } + if (material_label) { material_label->setVisible(show_material_controls); } // Toggle visibility of documentation labels for terrain blending ranges const std::vector doc_suffixes { "5", "10", "11" }; @@ -1602,19 +1602,19 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { - BOOL owner_or_god = gAgent.isGodlike() - || (region && (region->getOwner() == gAgent.getID())); - BOOL owner_or_god_or_manager = owner_or_god - || (region && region->isEstateManager()); - setCtrlsEnabled(owner_or_god_or_manager); + BOOL owner_or_god = gAgent.isGodlike() + || (region && (region->getOwner() == gAgent.getID())); + BOOL owner_or_god_or_manager = owner_or_god + || (region && region->isEstateManager()); + setCtrlsEnabled(owner_or_god_or_manager); - getChildView("apply_btn")->setEnabled(FALSE); + getChildView("apply_btn")->setEnabled(FALSE); - if (region) - { - getChild("region_text")->setValue(LLSD(region->getName())); + if (region) + { + getChild("region_text")->setValue(LLSD(region->getName())); - LLVLComposition* compp = region->getComposition(); + LLVLComposition* compp = region->getComposition(); static LLCachedControl feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); @@ -1707,42 +1707,42 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) } } - std::string buffer; - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - getChild(buffer)->setValue(LLSD(compp->getStartHeight(i))); - buffer = llformat("height_range_spin_%d", i); - getChild(buffer)->setValue(LLSD(compp->getHeightRange(i))); - } - } - else - { - LL_DEBUGS() << "no region set" << LL_ENDL; - getChild("region_text")->setValue(LLSD("")); - } - + std::string buffer; + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + getChild(buffer)->setValue(LLSD(compp->getStartHeight(i))); + buffer = llformat("height_range_spin_%d", i); + getChild(buffer)->setValue(LLSD(compp->getHeightRange(i))); + } + } + else + { + LL_DEBUGS() << "no region set" << LL_ENDL; + getChild("region_text")->setValue(LLSD("")); + } + // Update visibility of terrain swatches, etc refresh(); - getChildView("download_raw_btn")->setEnabled(owner_or_god); - getChildView("upload_raw_btn")->setEnabled(owner_or_god); - getChildView("bake_terrain_btn")->setEnabled(owner_or_god); + getChildView("download_raw_btn")->setEnabled(owner_or_god); + getChildView("upload_raw_btn")->setEnabled(owner_or_god); + getChildView("bake_terrain_btn")->setEnabled(owner_or_god); - return LLPanelRegionInfo::refreshFromRegion(region); + return LLPanelRegionInfo::refreshFromRegion(region); } // virtual BOOL LLPanelRegionTerrainInfo::sendUpdate() { - LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL; + LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL; - // Make sure user hasn't chosen wacky textures. - if (!validateTextureSizes()) - { - return FALSE; - } + // Make sure user hasn't chosen wacky textures. + if (!validateTextureSizes()) + { + return FALSE; + } // Prevent applying unsupported alpha blend/double-sided materials if (!validateMaterials()) @@ -1750,20 +1750,20 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() return FALSE; } - // Check if terrain Elevation Ranges are correct - if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights()) - { - if (!mAskedTextureHeights) - { - LLNotificationsUtil::add("ConfirmTextureHeights", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackTextureHeights, this, _1, _2)); - mAskedTextureHeights = true; - return FALSE; - } - else if (!mConfirmedTextureHeights) - { - return FALSE; - } - } + // Check if terrain Elevation Ranges are correct + if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights()) + { + if (!mAskedTextureHeights) + { + LLNotificationsUtil::add("ConfirmTextureHeights", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackTextureHeights, this, _1, _2)); + mAskedTextureHeights = true; + return FALSE; + } + else if (!mConfirmedTextureHeights) + { + return FALSE; + } + } std::string buffer; strings_t strings; @@ -1781,8 +1781,8 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() // ======================================= // Assemble and send texturedetail message - std::string id_str; - LLMessageSystem* msg = gMessageSystem; + std::string id_str; + LLMessageSystem* msg = gMessageSystem; // Send either material IDs instead of texture IDs depending on // material_type - they both occupy the same slot. @@ -1816,145 +1816,145 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() mLastSetTextures[i] = tmp_id; } } - sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); - strings.clear(); + sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); + strings.clear(); - // ======================================== - // Assemble and send textureheights message + // ======================================== + // Assemble and send textureheights message - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - std::string buffer2 = llformat("height_range_spin_%d", i); - std::string buffer3 = llformat("%d %f %f", i, (F32)getChild(buffer)->getValue().asReal(), (F32)getChild(buffer2)->getValue().asReal()); - strings.push_back(buffer3); - } - sendEstateOwnerMessage(msg, "textureheights", invoice, strings); - strings.clear(); + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + std::string buffer2 = llformat("height_range_spin_%d", i); + std::string buffer3 = llformat("%d %f %f", i, (F32)getChild(buffer)->getValue().asReal(), (F32)getChild(buffer2)->getValue().asReal()); + strings.push_back(buffer3); + } + sendEstateOwnerMessage(msg, "textureheights", invoice, strings); + strings.clear(); - // ======================================== - // Send texturecommit message + // ======================================== + // Send texturecommit message - sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); + sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); - return TRUE; + return TRUE; } bool LLPanelRegionTerrainInfo::callbackTextureHeights(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) // ok - { - mConfirmedTextureHeights = true; - } - else if (option == 1) // cancel - { - mConfirmedTextureHeights = false; - } - else if (option == 2) // don't ask - { - gSavedSettings.setBOOL("RegionCheckTextureHeights", FALSE); - mConfirmedTextureHeights = true; - } + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) // ok + { + mConfirmedTextureHeights = true; + } + else if (option == 1) // cancel + { + mConfirmedTextureHeights = false; + } + else if (option == 2) // don't ask + { + gSavedSettings.setBOOL("RegionCheckTextureHeights", FALSE); + mConfirmedTextureHeights = true; + } - onBtnSet(); + onBtnSet(); - mAskedTextureHeights = false; - return false; + mAskedTextureHeights = false; + return false; } // static void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data) { - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) - { - LL_WARNS() << "No file" << LL_ENDL; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForRequest(filepath); + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) + { + LL_WARNS() << "No file" << LL_ENDL; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForRequest(filepath); - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("download filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("download filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); } // static void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data) { - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) - { - LL_WARNS() << "No file" << LL_ENDL; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForTransfer(filepath); + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) + { + LL_WARNS() << "No file" << LL_ENDL; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForTransfer(filepath); - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("upload filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("upload filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - LLNotificationsUtil::add("RawUploadStarted"); + LLNotificationsUtil::add("RawUploadStarted"); } // static void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data) { - LLNotificationsUtil::add("ConfirmBakeTerrain", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2)); + LLNotificationsUtil::add("ConfirmBakeTerrain", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2)); } bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; - strings_t strings; - strings.push_back("bake"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + strings_t strings; + strings.push_back("bake"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - return false; + return false; } ///////////////////////////////////////////////////////////////////////////// // LLPanelEstateInfo // -LLPanelEstateInfo::LLPanelEstateInfo() -: LLPanelRegionInfo(), - mEstateID(0) // invalid +LLPanelEstateInfo::LLPanelEstateInfo() +: LLPanelRegionInfo(), + mEstateID(0) // invalid { - LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this)); - estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this)); + LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); + estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this)); + estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this)); } // static void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) { - std::string name; - - name.assign("estateupdateinfo"); - static LLDispatchEstateUpdateInfo estate_update_info; - dispatch.addHandler(name, &estate_update_info); + std::string name; + + name.assign("estateupdateinfo"); + static LLDispatchEstateUpdateInfo estate_update_info; + dispatch.addHandler(name, &estate_update_info); - name.assign("setaccess"); - static LLDispatchSetEstateAccess set_access; - dispatch.addHandler(name, &set_access); + name.assign("setaccess"); + static LLDispatchSetEstateAccess set_access; + dispatch.addHandler(name, &set_access); - name.assign("setexperience"); - static LLDispatchSetEstateExperience set_experience; - dispatch.addHandler(name, &set_experience); + name.assign("setexperience"); + static LLDispatchSetEstateExperience set_experience; + dispatch.addHandler(name, &set_experience); - estate_dispatch_initialized = true; + estate_dispatch_initialized = true; } //--------------------------------------------------------------------------- @@ -1963,49 +1963,49 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) void LLPanelEstateInfo::onClickKickUser() { - // this depends on the grandparent view being a floater - // in order to set up floater dependency + // this depends on the grandparent view being a floater + // in order to set up floater dependency LLView * button = findChild("kick_user_from_estate_btn"); - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName(), button); - if (child_floater) - { - parent_floater->addDependentFloater(child_floater); - } + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids) { - if (ids.empty()) return; - - //Bring up a confirmation dialog - LLSD args; - args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString(); - LLSD payload; - payload["agent_id"] = ids[0]; - LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2)); + if (ids.empty()) return; + + //Bring up a confirmation dialog + LLSD args; + args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString(); + LLSD payload; + payload["agent_id"] = ids[0]; + LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2)); } bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: - { - //Kick User - strings_t strings; - strings.push_back(notification["payload"]["agent_id"].asString()); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch(option) + { + case 0: + { + //Kick User + strings_t strings; + strings.push_back(notification["payload"]["agent_id"].asString()); - sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); - break; - } - default: - break; - } - return false; + sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); + break; + } + default: + break; + } + return false; } //--------------------------------------------------------------------------- @@ -2016,270 +2016,270 @@ bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& re //--------------------------------------------------------------------------- std::string all_estates_text() { - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")"; - - LLStringUtil::format_map_t args; - std::string owner = panel->getOwnerName(); - - LLViewerRegion* region = gAgent.getRegion(); - if (gAgent.isGodlike()) - { - args["[OWNER]"] = owner.c_str(); - return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args); - } - else if (region && region->getOwner() == gAgent.getID()) - { - return LLTrans::getString("RegionInfoAllEstatesYouOwn"); - } - else if (region && region->isEstateManager()) - { - args["[OWNER]"] = owner.c_str(); - return LLTrans::getString("RegionInfoAllEstatesYouManage", args); - } - else - { - return "(" + LLTrans::getString("RegionInfoError") + ")"; - } + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")"; + + LLStringUtil::format_map_t args; + std::string owner = panel->getOwnerName(); + + LLViewerRegion* region = gAgent.getRegion(); + if (gAgent.isGodlike()) + { + args["[OWNER]"] = owner.c_str(); + return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args); + } + else if (region && region->getOwner() == gAgent.getID()) + { + return LLTrans::getString("RegionInfoAllEstatesYouOwn"); + } + else if (region && region->isEstateManager()) + { + args["[OWNER]"] = owner.c_str(); + return LLTrans::getString("RegionInfoAllEstatesYouManage", args); + } + else + { + return "(" + LLTrans::getString("RegionInfoError") + ")"; + } } // static bool LLPanelEstateInfo::isLindenEstate() { - U32 estate_id = LLEstateInfoModel::instance().getID(); - return (estate_id <= ESTATE_LAST_LINDEN); + U32 estate_id = LLEstateInfoModel::instance().getID(); + return (estate_id <= ESTATE_LAST_LINDEN); } struct LLEstateAccessChangeInfo { - LLEstateAccessChangeInfo(const LLSD& sd) - { - mDialogName = sd["dialog_name"].asString(); - mOperationFlag = (U32)sd["operation"].asInteger(); - LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); - for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); - id_it != end_it; - ++id_it) - { - mAgentOrGroupIDs.push_back(id_it->asUUID()); - } - } - - const LLSD asLLSD() const - { - LLSD sd; - sd["name"] = mDialogName; - sd["operation"] = (S32)mOperationFlag; - for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i) - { - sd["allowed_ids"].append(mAgentOrGroupIDs[i]); - if (mAgentNames.size() > i) - { - sd["allowed_names"].append(mAgentNames[i].asLLSD()); - } - } - return sd; - } - - U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. - std::string mDialogName; - uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change - std::vector mAgentNames; // Optional list of the agent names for notifications + LLEstateAccessChangeInfo(const LLSD& sd) + { + mDialogName = sd["dialog_name"].asString(); + mOperationFlag = (U32)sd["operation"].asInteger(); + LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); + for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); + id_it != end_it; + ++id_it) + { + mAgentOrGroupIDs.push_back(id_it->asUUID()); + } + } + + const LLSD asLLSD() const + { + LLSD sd; + sd["name"] = mDialogName; + sd["operation"] = (S32)mOperationFlag; + for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i) + { + sd["allowed_ids"].append(mAgentOrGroupIDs[i]); + if (mAgentNames.size() > i) + { + sd["allowed_names"].append(mAgentNames[i].asLLSD()); + } + } + return sd; + } + + U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. + std::string mDialogName; + uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change + std::vector mAgentNames; // Optional list of the agent names for notifications }; // static void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name) { - LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); - if (panelp) - { - panelp->setOwnerName(name); - } + LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); + if (panelp) + { + panelp->setOwnerName(name); + } } // static void LLPanelEstateInfo::updateEstateName(const std::string& name) { - LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); - if (panelp) - { - panelp->getChildRef("estate_name").setText(name); - } + LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate(); + if (panelp) + { + panelp->getChildRef("estate_name").setText(name); + } } void LLPanelEstateInfo::updateControls(LLViewerRegion* region) { - BOOL god = gAgent.isGodlike(); - BOOL owner = (region && (region->getOwner() == gAgent.getID())); - BOOL manager = (region && region->isEstateManager()); - setCtrlsEnabled(god || owner || manager); - - getChildView("apply_btn")->setEnabled(FALSE); + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + 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); + getChildView("message_estate_btn")->setEnabled(god || owner || manager); + getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); - refresh(); + refresh(); } bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) { - updateControls(region); - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); + updateControls(region); + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + + // We want estate info. To make sure it works across region + // boundaries and multiple packets, we add a serial number to the + // integers and track against that on update. + strings_t strings; + //integers_t integers; + //LLFloaterRegionInfo::incrementSerial(); + LLFloaterRegionInfo::nextInvoice(); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); - // We want estate info. To make sure it works across region - // boundaries and multiple packets, we add a serial number to the - // integers and track against that on update. - strings_t strings; - //integers_t integers; - //LLFloaterRegionInfo::incrementSerial(); - LLFloaterRegionInfo::nextInvoice(); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); - - sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); + sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); - refresh(); + refresh(); - return rv; + return rv; } void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) { - // Ensure appropriate state of the management ui. - updateControls(gAgent.getRegion()); + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); } bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) { - LL_INFOS() << "LLPanelEstateInfo::estateUpdate()" << LL_ENDL; - return false; + LL_INFOS() << "LLPanelEstateInfo::estateUpdate()" << LL_ENDL; + return false; } BOOL LLPanelEstateInfo::postBuild() { - // set up the callbacks for the generic controls - initCtrl("externally_visible_radio"); - initCtrl("allow_direct_teleport"); - initCtrl("limit_payment"); - initCtrl("limit_age_verified"); + // set up the callbacks for the generic controls + initCtrl("externally_visible_radio"); + initCtrl("allow_direct_teleport"); + initCtrl("limit_payment"); + initCtrl("limit_age_verified"); initCtrl("limit_bots"); - initCtrl("voice_chat_check"); + initCtrl("voice_chat_check"); initCtrl("parcel_access_override"); - childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this)); - childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this)); + childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this)); + childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this)); - getChild("parcel_access_override")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAccessOverride, this)); + getChild("parcel_access_override")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAccessOverride, this)); - getChild("externally_visible_radio")->setFocus(TRUE); + getChild("externally_visible_radio")->setFocus(TRUE); getChild("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend); - return LLPanelRegionInfo::postBuild(); + return LLPanelRegionInfo::postBuild(); } void LLPanelEstateInfo::refresh() { - // Disable access restriction controls if they make no sense. - bool public_access = ("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); + // Disable access restriction controls if they make no sense. + bool public_access = ("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); - getChildView("Only Allow")->setEnabled(public_access); - getChildView("limit_payment")->setEnabled(public_access); - getChildView("limit_age_verified")->setEnabled(public_access); + getChildView("Only Allow")->setEnabled(public_access); + getChildView("limit_payment")->setEnabled(public_access); + getChildView("limit_age_verified")->setEnabled(public_access); getChildView("limit_bots")->setEnabled(public_access); - // if this is set to false, then the limit fields are meaningless and should be turned off - if (public_access == false) - { - getChild("limit_payment")->setValue(false); - getChild("limit_age_verified")->setValue(false); + // if this is set to false, then the limit fields are meaningless and should be turned off + if (public_access == false) + { + getChild("limit_payment")->setValue(false); + getChild("limit_age_verified")->setValue(false); getChild("limit_bots")->setValue(false); - } + } } void LLPanelEstateInfo::refreshFromEstate() { - const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); + const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - getChild("estate_name")->setValue(estate_info.getName()); - setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString()); + getChild("estate_name")->setValue(estate_info.getName()); + setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString()); - getChild("externally_visible_radio")->setValue(estate_info.getIsExternallyVisible() ? "estate_public_access" : "estate_restricted_access"); - getChild("voice_chat_check")->setValue(estate_info.getAllowVoiceChat()); - getChild("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport()); - getChild("limit_payment")->setValue(estate_info.getDenyAnonymous()); - getChild("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); + getChild("externally_visible_radio")->setValue(estate_info.getIsExternallyVisible() ? "estate_public_access" : "estate_restricted_access"); + getChild("voice_chat_check")->setValue(estate_info.getAllowVoiceChat()); + getChild("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport()); + getChild("limit_payment")->setValue(estate_info.getDenyAnonymous()); + getChild("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); getChild("parcel_access_override")->setValue(estate_info.getAllowAccessOverride()); getChild("limit_bots")->setValue(estate_info.getDenyScriptedAgents()); - // Ensure appriopriate state of the management UI - updateControls(gAgent.getRegion()); - refresh(); + // Ensure appriopriate state of the management UI + updateControls(gAgent.getRegion()); + refresh(); } BOOL LLPanelEstateInfo::sendUpdate() { - LL_INFOS() << "LLPanelEsateInfo::sendUpdate()" << LL_ENDL; + LL_INFOS() << "LLPanelEsateInfo::sendUpdate()" << LL_ENDL; - LLNotification::Params params("ChangeLindenEstate"); - params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); + LLNotification::Params params("ChangeLindenEstate"); + params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); - if (isLindenEstate()) - { - // trying to change reserved estate, warn - LLNotifications::instance().add(params); - } - else - { - // for normal estates, just make the change - LLNotifications::instance().forceResponse(params, 0); - } - return TRUE; + if (isLindenEstate()) + { + // trying to change reserved estate, warn + LLNotifications::instance().add(params); + } + else + { + // for normal estates, just make the change + LLNotifications::instance().forceResponse(params, 0); + } + return TRUE; } bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: - { - LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - - // update model - estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore - estate_info.setIsExternallyVisible("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); - estate_info.setAllowDirectTeleport(getChild("allow_direct_teleport")->getValue().asBoolean()); - estate_info.setDenyAnonymous(getChild("limit_payment")->getValue().asBoolean()); - estate_info.setDenyAgeUnverified(getChild("limit_age_verified")->getValue().asBoolean()); - estate_info.setAllowVoiceChat(getChild("voice_chat_check")->getValue().asBoolean()); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch(option) + { + case 0: + { + LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); + + // update model + estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore + estate_info.setIsExternallyVisible("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); + estate_info.setAllowDirectTeleport(getChild("allow_direct_teleport")->getValue().asBoolean()); + estate_info.setDenyAnonymous(getChild("limit_payment")->getValue().asBoolean()); + estate_info.setDenyAgeUnverified(getChild("limit_age_verified")->getValue().asBoolean()); + estate_info.setAllowVoiceChat(getChild("voice_chat_check")->getValue().asBoolean()); estate_info.setAllowAccessOverride(getChild("parcel_access_override")->getValue().asBoolean()); estate_info.setDenyScriptedAgents(getChild("limit_bots")->getValue().asBoolean()); // JIGGLYPUFF //estate_info.setAllowAccessOverride(getChild("")->getValue().asBoolean()); - // send the update to sim - estate_info.sendEstateInfo(); - } - - // we don't want to do this because we'll get it automatically from the sim - // after the spaceserver processes it -// else -// { -// // caps method does not automatically send this info -// LLFloaterRegionInfo::requestRegionInfo(); -// } - break; - case 1: - default: - // do nothing - break; - } - return false; + // send the update to sim + estate_info.sendEstateInfo(); + } + + // we don't want to do this because we'll get it automatically from the sim + // after the spaceserver processes it +// else +// { +// // caps method does not automatically send this info +// LLFloaterRegionInfo::requestRegionInfo(); +// } + break; + case 1: + default: + // do nothing + break; + } + return false; } @@ -2289,326 +2289,326 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con // IParam[0] = serial void LLPanelEstateInfo::getEstateOwner() { - // TODO -- disable the panel - // and call this function whenever we cross a region boundary - // re-enable when owner matches, and get new estate info - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_EstateOwnerRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + // TODO -- disable the panel + // and call this function whenever we cross a region boundary + // re-enable when owner matches, and get new estate info + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_EstateOwnerRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->nextBlockFast(_PREHASH_RequestData); - msg->addStringFast(_PREHASH_Request, "getowner"); + msg->nextBlockFast(_PREHASH_RequestData); + msg->addStringFast(_PREHASH_Request, "getowner"); - // we send an empty string so that the variable block is not empty - msg->nextBlockFast(_PREHASH_StringData); - msg->addStringFast(_PREHASH_SParam, ""); + // we send an empty string so that the variable block is not empty + msg->nextBlockFast(_PREHASH_StringData); + msg->addStringFast(_PREHASH_SParam, ""); - msg->nextBlockFast(_PREHASH_IntegerData); - msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); + msg->nextBlockFast(_PREHASH_IntegerData); + msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); - gAgent.sendMessage(); + gAgent.sendMessage(); } */ const std::string LLPanelEstateInfo::getOwnerName() const { - return getChild("estate_owner")->getValue().asString(); + return getChild("estate_owner")->getValue().asString(); } void LLPanelEstateInfo::setOwnerName(const std::string& name) { - getChild("estate_owner")->setValue(LLSD(name)); + getChild("estate_owner")->setValue(LLSD(name)); } // static void LLPanelEstateInfo::onClickMessageEstate(void* userdata) { - LL_INFOS() << "LLPanelEstateInfo::onClickMessageEstate" << LL_ENDL; - LLNotificationsUtil::add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); + LL_INFOS() << "LLPanelEstateInfo::onClickMessageEstate" << LL_ENDL; + LLNotificationsUtil::add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); } bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - std::string text = response["message"].asString(); - if(option != 0) return false; - if(text.empty()) return false; - LL_INFOS() << "Message to everyone: " << text << LL_ENDL; - strings_t strings; - //integers_t integers; - std::string name; - LLAgentUI::buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + std::string text = response["message"].asString(); + if(option != 0) return false; + if(text.empty()) return false; + LL_INFOS() << "Message to everyone: " << text << LL_ENDL; + strings_t strings; + //integers_t integers; + std::string name; + LLAgentUI::buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); + return false; } void LLPanelEstateInfo::onChangeAccessOverride() { - if (!getChild("parcel_access_override")->getValue().asBoolean()) - { - LLNotificationsUtil::add("EstateParcelAccessOverride"); - } + if (!getChild("parcel_access_override")->getValue().asBoolean()) + { + LLNotificationsUtil::add("EstateParcelAccessOverride"); + } } LLPanelEstateCovenant::LLPanelEstateCovenant() - : - mCovenantID(LLUUID::null), - mAssetStatus(ASSET_ERROR) + : + mCovenantID(LLUUID::null), + mAssetStatus(ASSET_ERROR) { } -// virtual +// virtual bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) { - LLTextBox* region_name = getChild("region_name_text"); - if (region_name) - { - region_name->setText(region->getName()); - } - - LLTextBox* resellable_clause = getChild("resellable_clause"); - if (resellable_clause) - { - if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) - { - resellable_clause->setText(getString("can_not_resell")); - } - else - { - resellable_clause->setText(getString("can_resell")); - } - } - - LLTextBox* changeable_clause = getChild("changeable_clause"); - if (changeable_clause) - { - if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) - { - changeable_clause->setText(getString("can_change")); - } - else - { - changeable_clause->setText(getString("can_not_change")); - } - } - - LLTextBox* region_maturity = getChild("region_maturity_text"); - if (region_maturity) - { - region_maturity->setText(region->getSimAccessString()); - } - - LLTextBox* region_landtype = getChild("region_landtype_text"); - region_landtype->setText(region->getLocalizedSimProductName()); + LLTextBox* region_name = getChild("region_name_text"); + if (region_name) + { + region_name->setText(region->getName()); + } + + LLTextBox* resellable_clause = getChild("resellable_clause"); + if (resellable_clause) + { + if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) + { + resellable_clause->setText(getString("can_not_resell")); + } + else + { + resellable_clause->setText(getString("can_resell")); + } + } + + LLTextBox* changeable_clause = getChild("changeable_clause"); + if (changeable_clause) + { + if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) + { + changeable_clause->setText(getString("can_change")); + } + else + { + changeable_clause->setText(getString("can_not_change")); + } + } + + LLTextBox* region_maturity = getChild("region_maturity_text"); + if (region_maturity) + { + region_maturity->setText(region->getSimAccessString()); + } + + LLTextBox* region_landtype = getChild("region_landtype_text"); + region_landtype->setText(region->getLocalizedSimProductName()); getChild("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate())); - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); - LLMessageSystem *msg = gMessageSystem; - msg->newMessage("EstateCovenantRequest"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); - msg->sendReliable(region->getHost()); - return rv; -} - -// virtual + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + LLMessageSystem *msg = gMessageSystem; + msg->newMessage("EstateCovenantRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->sendReliable(region->getHost()); + return rv; +} + +// virtual bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) { - LL_INFOS() << "LLPanelEstateCovenant::estateUpdate()" << LL_ENDL; - return true; + LL_INFOS() << "LLPanelEstateCovenant::estateUpdate()" << LL_ENDL; + return true; } - -// virtual + +// virtual BOOL LLPanelEstateCovenant::postBuild() { - mEstateNameText = getChild("estate_name_text"); - mEstateOwnerText = getChild("estate_owner_text"); + mEstateNameText = getChild("estate_name_text"); + mEstateOwnerText = getChild("estate_owner_text"); mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend); - mLastModifiedText = getChild("covenant_timestamp_text"); - mEditor = getChild("covenant_editor"); - LLButton* reset_button = getChild("reset_covenant"); - reset_button->setEnabled(gAgent.canManageEstate()); - reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); + mLastModifiedText = getChild("covenant_timestamp_text"); + mEditor = getChild("covenant_editor"); + LLButton* reset_button = getChild("reset_covenant"); + reset_button->setEnabled(gAgent.canManageEstate()); + reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); - return LLPanelRegionInfo::postBuild(); + return LLPanelRegionInfo::postBuild(); } -// virtual +// virtual void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl) { } // virtual BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLInventoryItem* item = (LLInventoryItem*)cargo_data; - - if (!gAgent.canManageEstate()) - { - *accept = ACCEPT_NO; - return TRUE; - } - - switch(cargo_type) - { - case DAD_NOTECARD: - *accept = ACCEPT_YES_COPY_SINGLE; - if (item && drop) - { - LLSD payload; - payload["item_id"] = item->getUUID(); - LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), payload, - LLPanelEstateCovenant::confirmChangeCovenantCallback); - } - break; - default: - *accept = ACCEPT_NO; - break; - } - - return TRUE; -} - -// static + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + + if (!gAgent.canManageEstate()) + { + *accept = ACCEPT_NO; + return TRUE; + } + + switch(cargo_type) + { + case DAD_NOTECARD: + *accept = ACCEPT_YES_COPY_SINGLE; + if (item && drop) + { + LLSD payload; + payload["item_id"] = item->getUUID(); + LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), payload, + LLPanelEstateCovenant::confirmChangeCovenantCallback); + } + break; + default: + *accept = ACCEPT_NO; + break; + } + + return TRUE; +} + +// static bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - if (!item || !self) return false; + if (!item || !self) return false; - switch(option) - { - case 0: - self->loadInvItem(item); - break; - default: - break; - } - return false; + switch(option) + { + case 0: + self->loadInvItem(item); + break; + default: + break; + } + return false; } // static void LLPanelEstateCovenant::resetCovenantID(void* userdata) { - LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); + LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); } // static bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response) { - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - if (!self) return false; + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + if (!self) return false; - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: - self->loadInvItem(NULL); - break; - default: - break; - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch(option) + { + case 0: + self->loadInvItem(NULL); + break; + default: + break; + } + return false; } void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp) { - const BOOL high_priority = TRUE; - if (itemp) - { - gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), - gAgent.getID(), - gAgent.getSessionID(), - itemp->getPermissions().getOwner(), - LLUUID::null, - itemp->getUUID(), - itemp->getAssetUUID(), - itemp->getType(), + const BOOL high_priority = TRUE; + if (itemp) + { + gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), + gAgent.getID(), + gAgent.getSessionID(), + itemp->getPermissions().getOwner(), + LLUUID::null, + itemp->getUUID(), + itemp->getAssetUUID(), + itemp->getType(), onLoadComplete, - (void*)this, - high_priority); - mAssetStatus = ASSET_LOADING; - } - else - { - mAssetStatus = ASSET_LOADED; - setCovenantTextEditor(LLTrans::getString("RegionNoCovenant")); - sendChangeCovenantID(LLUUID::null); - } + (void*)this, + high_priority); + mAssetStatus = ASSET_LOADING; + } + else + { + mAssetStatus = ASSET_LOADED; + setCovenantTextEditor(LLTrans::getString("RegionNoCovenant")); + sendChangeCovenantID(LLUUID::null); + } } // static void LLPanelEstateCovenant::onLoadComplete(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) -{ - LL_INFOS() << "LLPanelEstateCovenant::onLoadComplete()" << LL_ENDL; - LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; - if( panelp ) - { - if(0 == status) - { - LLFileSystem file(asset_uuid, type, LLFileSystem::READ); - - S32 file_length = file.getSize(); - - std::vector buffer(file_length+1); - file.read((U8*)&buffer[0], file_length); - // put a EOS at the end - buffer[file_length] = 0; - - if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) ) - { - if( !panelp->mEditor->importBuffer( &buffer[0], file_length+1 ) ) - { - LL_WARNS() << "Problem importing estate covenant." << LL_ENDL; - LLNotificationsUtil::add("ProblemImportingEstateCovenant"); - } - else - { - panelp->sendChangeCovenantID(asset_uuid); - } - } - else - { - // Version 0 (just text, doesn't include version number) - panelp->sendChangeCovenantID(asset_uuid); - } - } - else - { - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || - LL_ERR_FILE_EMPTY == status) - { - LLNotificationsUtil::add("MissingNotecardAssetID"); - } - else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) - { - LLNotificationsUtil::add("NotAllowedToViewNotecard"); - } - else - { - LLNotificationsUtil::add("UnableToLoadNotecardAsset"); - } - - LL_WARNS() << "Problem loading notecard: " << status << LL_ENDL; - } - panelp->mAssetStatus = ASSET_LOADED; - panelp->setCovenantID(asset_uuid); - } + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + LL_INFOS() << "LLPanelEstateCovenant::onLoadComplete()" << LL_ENDL; + LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; + if( panelp ) + { + if(0 == status) + { + LLFileSystem file(asset_uuid, type, LLFileSystem::READ); + + S32 file_length = file.getSize(); + + std::vector buffer(file_length+1); + file.read((U8*)&buffer[0], file_length); + // put a EOS at the end + buffer[file_length] = 0; + + if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) ) + { + if( !panelp->mEditor->importBuffer( &buffer[0], file_length+1 ) ) + { + LL_WARNS() << "Problem importing estate covenant." << LL_ENDL; + LLNotificationsUtil::add("ProblemImportingEstateCovenant"); + } + else + { + panelp->sendChangeCovenantID(asset_uuid); + } + } + else + { + // Version 0 (just text, doesn't include version number) + panelp->sendChangeCovenantID(asset_uuid); + } + } + else + { + if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLNotificationsUtil::add("MissingNotecardAssetID"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + LLNotificationsUtil::add("NotAllowedToViewNotecard"); + } + else + { + LLNotificationsUtil::add("UnableToLoadNotecardAsset"); + } + + LL_WARNS() << "Problem loading notecard: " << status << LL_ENDL; + } + panelp->mAssetStatus = ASSET_LOADED; + panelp->setCovenantID(asset_uuid); + } } // key = "estatechangecovenantid" @@ -2616,97 +2616,97 @@ void LLPanelEstateCovenant::onLoadComplete(const LLUUID& asset_uuid, // strings[1] = str(covenant_id) void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) { - if (asset_id != getCovenantID()) - { + if (asset_id != getCovenantID()) + { setCovenantID(asset_id); - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", "estatechangecovenantid"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + msg->nextBlock("MethodData"); + msg->addString("Method", "estatechangecovenantid"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - msg->nextBlock("ParamList"); - msg->addString("Parameter", getCovenantID().asString()); - gAgent.sendReliableMessage(); - } + msg->nextBlock("ParamList"); + msg->addString("Parameter", getCovenantID().asString()); + gAgent.sendReliableMessage(); + } } -// virtual +// virtual BOOL LLPanelEstateCovenant::sendUpdate() { - return TRUE; + return TRUE; } std::string LLPanelEstateCovenant::getEstateName() const { - return mEstateNameText->getText(); + return mEstateNameText->getText(); } void LLPanelEstateCovenant::setEstateName(const std::string& name) { - mEstateNameText->setText(name); + mEstateNameText->setText(name); } // static void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) { - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEditor->setText(string); - panelp->setCovenantID(asset_id); - } + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEditor->setText(string); + panelp->setCovenantID(asset_id); + } } // static void LLPanelEstateCovenant::updateEstateName(const std::string& name) { - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateNameText->setText(name); - } + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateNameText->setText(name); + } } // static void LLPanelEstateCovenant::updateLastModified(const std::string& text) { - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mLastModifiedText->setText(text); - } + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mLastModifiedText->setText(text); + } } // static void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) { - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateOwnerText->setText(name); - } + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateOwnerText->setText(name); + } } std::string LLPanelEstateCovenant::getOwnerName() const { - return mEstateOwnerText->getText(); + return mEstateOwnerText->getText(); } void LLPanelEstateCovenant::setOwnerName(const std::string& name) { - mEstateOwnerText->setText(name); + mEstateOwnerText->setText(name); } void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) { - mEditor->setText(text); + mEditor->setText(text); } // key = "estateupdateinfo" @@ -2721,47 +2721,47 @@ void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) // strings[8] = str(send_to_agent_only) // strings[9] = str(abuse_email_addr) bool LLDispatchEstateUpdateInfo::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) { - LL_DEBUGS() << "Received estate update" << LL_ENDL; + LL_DEBUGS() << "Received estate update" << LL_ENDL; - // Update estate info model. - // This will call LLPanelEstateInfo::refreshFromEstate(). - // *TODO: Move estate message handling stuff to llestateinfomodel.cpp. - LLEstateInfoModel::instance().update(strings); + // Update estate info model. + // This will call LLPanelEstateInfo::refreshFromEstate(). + // *TODO: Move estate message handling stuff to llestateinfomodel.cpp. + LLEstateInfoModel::instance().update(strings); - return true; + return true; } bool LLDispatchSetEstateAccess::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (panel && panel->getPendingUpdate()) - { - panel->setPendingUpdate(false); - panel->updateLists(); - } - return true; + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel && panel->getPendingUpdate()) + { + panel->setPendingUpdate(false); + panel->updateLists(); + } + return true; } // static LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count ) { - LLSD idList = LLSD::emptyArray(); - LLUUID id; - while (count-- > 0 && it < end) - { - memcpy(id.mData, (*(it++)).data(), UUID_BYTES); - idList.append(id); - } - return idList; + LLSD idList = LLSD::emptyArray(); + LLUUID id; + while (count-- > 0 && it < end) + { + memcpy(id.mData, (*(it++)).data(), UUID_BYTES); + idList.append(id); + } + return idList; } // key = "setexperience" @@ -2773,92 +2773,92 @@ LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_ // strings[5] = bin(uuid) ... // ... bool LLDispatchSetEstateExperience::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) { - LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); - if (!panel) - return true; + LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); + if (!panel) + return true; - const sparam_t::size_type MIN_SIZE = 5; - if (strings.size() < MIN_SIZE) - return true; + const sparam_t::size_type MIN_SIZE = 5; + if (strings.size() < MIN_SIZE) + return true; - // Skip 2 parameters - sparam_t::const_iterator it = strings.begin(); - ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10); - ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10); + // Skip 2 parameters + sparam_t::const_iterator it = strings.begin(); + ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10); + ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10); - // Read 3 parameters - LLUUID id; - S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10); - S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10); - S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10); + // Read 3 parameters + LLUUID id; + S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10); + S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10); + S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10); - LLSD ids = LLSD::emptyMap() - .with("blocked", getIDs(it, strings.end(), num_blocked)) - .with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted)) - .with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed)); + LLSD ids = LLSD::emptyMap() + .with("blocked", getIDs(it, strings.end(), num_blocked)) + .with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted)) + .with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed)); - panel->processResponse(ids); + panel->processResponse(ids); - return true; + return true; } BOOL LLPanelRegionExperiences::postBuild() { - mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE); - mTrusted = setupList("panel_trusted", ESTATE_EXPERIENCE_TRUSTED_ADD, ESTATE_EXPERIENCE_TRUSTED_REMOVE); - mBlocked = setupList("panel_blocked", ESTATE_EXPERIENCE_BLOCKED_ADD, ESTATE_EXPERIENCE_BLOCKED_REMOVE); + mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE); + mTrusted = setupList("panel_trusted", ESTATE_EXPERIENCE_TRUSTED_ADD, ESTATE_EXPERIENCE_TRUSTED_REMOVE); + mBlocked = setupList("panel_blocked", ESTATE_EXPERIENCE_BLOCKED_ADD, ESTATE_EXPERIENCE_BLOCKED_REMOVE); - getChild("trusted_layout_panel")->setVisible(TRUE); - getChild("experiences_help_text")->setText(getString("estate_caption")); - getChild("trusted_text_help")->setText(getString("trusted_estate_text")); - getChild("allowed_text_help")->setText(getString("allowed_estate_text")); - getChild("blocked_text_help")->setText(getString("blocked_estate_text")); + getChild("trusted_layout_panel")->setVisible(TRUE); + getChild("experiences_help_text")->setText(getString("estate_caption")); + getChild("trusted_text_help")->setText(getString("trusted_estate_text")); + getChild("allowed_text_help")->setText(getString("allowed_estate_text")); + getChild("blocked_text_help")->setText(getString("blocked_estate_text")); - return LLPanelRegionInfo::postBuild(); + return LLPanelRegionInfo::postBuild(); } LLPanelExperienceListEditor* LLPanelRegionExperiences::setupList( const char* control_name, U32 add_id, U32 remove_id ) { - LLPanelExperienceListEditor* child = findChild(control_name); - if(child) - { - child->getChild("text_name")->setText(child->getString(control_name)); - child->setMaxExperienceIDs(ESTATE_MAX_EXPERIENCE_IDS); - child->setAddedCallback( boost::bind(&LLPanelRegionExperiences::itemChanged, this, add_id, _1)); - child->setRemovedCallback(boost::bind(&LLPanelRegionExperiences::itemChanged, this, remove_id, _1)); - } + LLPanelExperienceListEditor* child = findChild(control_name); + if(child) + { + child->getChild("text_name")->setText(child->getString(control_name)); + child->setMaxExperienceIDs(ESTATE_MAX_EXPERIENCE_IDS); + child->setAddedCallback( boost::bind(&LLPanelRegionExperiences::itemChanged, this, add_id, _1)); + child->setRemovedCallback(boost::bind(&LLPanelRegionExperiences::itemChanged, this, remove_id, _1)); + } - return child; + return child; } void LLPanelRegionExperiences::processResponse( const LLSD& content ) { - if(content.has("default")) - { - mDefaultExperience = content["default"].asUUID(); - } + if(content.has("default")) + { + mDefaultExperience = content["default"].asUUID(); + } + + mAllowed->setExperienceIds(content["allowed"]); + mBlocked->setExperienceIds(content["blocked"]); - mAllowed->setExperienceIds(content["allowed"]); - mBlocked->setExperienceIds(content["blocked"]); + LLSD trusted = content["trusted"]; + if(mDefaultExperience.notNull()) + { + mTrusted->setStickyFunction(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + trusted.append(mDefaultExperience); + } - LLSD trusted = content["trusted"]; - if(mDefaultExperience.notNull()) - { - mTrusted->setStickyFunction(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); - trusted.append(mDefaultExperience); - } + mTrusted->setExperienceIds(trusted); - mTrusted->setExperienceIds(trusted); - - mAllowed->refreshExperienceCounter(); - mBlocked->refreshExperienceCounter(); - mTrusted->refreshExperienceCounter(); + mAllowed->refreshExperienceCounter(); + mBlocked->refreshExperienceCounter(); + mTrusted->refreshExperienceCounter(); } @@ -2867,81 +2867,81 @@ void LLPanelRegionExperiences::processResponse( const LLSD& content ) // static bool LLPanelRegionExperiences::experienceCoreConfirm(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); - - LLViewerRegion* region = gAgent.getRegion(); - - LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); - - for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); - iter != end_it; - iter++) - { - U32 flags = originalFlags; - if (iter + 1 != end_it) - flags |= ESTATE_ACCESS_NO_REPLY; - - const LLUUID id = iter->asUUID(); - switch(option) - { - case 0: - // This estate - sendEstateExperienceDelta(flags, id); - break; - case 1: - { - // All estates, either than I own or manage for this owner. - // This will be verified on simulator. JC - if (!region) break; - if (region->getOwner() == gAgent.getID() - || gAgent.isGodlike()) - { - flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; - sendEstateExperienceDelta(flags, id); - } - else if (region->isEstateManager()) - { - flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; - sendEstateExperienceDelta(flags, id); - } - break; - } - case 2: - default: - break; - } - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + + LLViewerRegion* region = gAgent.getRegion(); + + LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); + + for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); + iter != end_it; + iter++) + { + U32 flags = originalFlags; + if (iter + 1 != end_it) + flags |= ESTATE_ACCESS_NO_REPLY; + + const LLUUID id = iter->asUUID(); + switch(option) + { + case 0: + // This estate + sendEstateExperienceDelta(flags, id); + break; + case 1: + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) break; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + sendEstateExperienceDelta(flags, id); + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + sendEstateExperienceDelta(flags, id); + } + break; + } + case 2: + default: + break; + } + } + return false; } // Send the actual "estateexperiencedelta" message void LLPanelRegionExperiences::sendEstateExperienceDelta(U32 flags, const LLUUID& experience_id) { - strings_t str(3, std::string()); - gAgent.getID().toString(str[0]); - str[1] = llformat("%u", flags); - experience_id.toString(str[2]); + strings_t str(3, std::string()); + gAgent.getID().toString(str[0]); + str[1] = llformat("%u", flags); + experience_id.toString(str[2]); - LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); - if (panel) - { - panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str); - } + LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); + if (panel) + { + panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str); + } } void LLPanelRegionExperiences::infoCallback(LLHandle handle, const LLSD& content) -{ - if(handle.isDead()) - return; +{ + if(handle.isDead()) + return; - LLPanelRegionExperiences* floater = handle.get(); - if (floater) - { - floater->processResponse(content); - } + LLPanelRegionExperiences* floater = handle.get(); + if (floater) + { + floater->processResponse(content); + } } /*static*/ @@ -2954,26 +2954,26 @@ std::string LLPanelRegionExperiences::regionCapabilityQuery(LLViewerRegion* regi bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region) { - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - mAllowed->loading(); - mAllowed->setReadonly(!allow_modify); - // remove grid-wide experiences - mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID)); - // remove default experience - mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + mAllowed->loading(); + mAllowed->setReadonly(!allow_modify); + // remove grid-wide experiences + mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID)); + // remove default experience + mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); - mBlocked->loading(); - mBlocked->setReadonly(!allow_modify); - // only grid-wide experiences - mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithoutProperty, _1, LLExperienceCache::PROPERTY_GRID)); - // but not privileged ones - mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED)); - // remove default experience - mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + mBlocked->loading(); + mBlocked->setReadonly(!allow_modify); + // only grid-wide experiences + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithoutProperty, _1, LLExperienceCache::PROPERTY_GRID)); + // but not privileged ones + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED)); + // remove default experience + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); - mTrusted->loading(); - mTrusted->setReadonly(!allow_modify); + mTrusted->loading(); + mTrusted->setReadonly(!allow_modify); LLExperienceCache::instance().getRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1), boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle(), _1)); @@ -2983,87 +2983,87 @@ bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region) LLSD LLPanelRegionExperiences::addIds(LLPanelExperienceListEditor* panel) { - LLSD ids; - const uuid_list_t& id_list = panel->getExperienceIds(); - for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it) - { - ids.append(*it); - } - return ids; + LLSD ids; + const uuid_list_t& id_list = panel->getExperienceIds(); + for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it) + { + ids.append(*it); + } + return ids; } BOOL LLPanelRegionExperiences::sendUpdate() { - LLViewerRegion* region = gAgent.getRegion(); + LLViewerRegion* region = gAgent.getRegion(); LLSD content; - content["allowed"]=addIds(mAllowed); - content["blocked"]=addIds(mBlocked); - content["trusted"]=addIds(mTrusted); + content["allowed"]=addIds(mAllowed); + content["blocked"]=addIds(mBlocked); + content["trusted"]=addIds(mTrusted); LLExperienceCache::instance().setRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1), content, boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle(), _1)); - return TRUE; + return TRUE; } void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id ) { - std::string dialog_name; - switch (event_type) - { - case ESTATE_EXPERIENCE_ALLOWED_ADD: - dialog_name = "EstateAllowedExperienceAdd"; - break; + std::string dialog_name; + switch (event_type) + { + case ESTATE_EXPERIENCE_ALLOWED_ADD: + dialog_name = "EstateAllowedExperienceAdd"; + break; - case ESTATE_EXPERIENCE_ALLOWED_REMOVE: - dialog_name = "EstateAllowedExperienceRemove"; - break; + case ESTATE_EXPERIENCE_ALLOWED_REMOVE: + dialog_name = "EstateAllowedExperienceRemove"; + break; - case ESTATE_EXPERIENCE_TRUSTED_ADD: - dialog_name = "EstateTrustedExperienceAdd"; - break; + case ESTATE_EXPERIENCE_TRUSTED_ADD: + dialog_name = "EstateTrustedExperienceAdd"; + break; - case ESTATE_EXPERIENCE_TRUSTED_REMOVE: - dialog_name = "EstateTrustedExperienceRemove"; - break; + case ESTATE_EXPERIENCE_TRUSTED_REMOVE: + dialog_name = "EstateTrustedExperienceRemove"; + break; - case ESTATE_EXPERIENCE_BLOCKED_ADD: - dialog_name = "EstateBlockedExperienceAdd"; - break; + case ESTATE_EXPERIENCE_BLOCKED_ADD: + dialog_name = "EstateBlockedExperienceAdd"; + break; - case ESTATE_EXPERIENCE_BLOCKED_REMOVE: - dialog_name = "EstateBlockedExperienceRemove"; - break; + case ESTATE_EXPERIENCE_BLOCKED_REMOVE: + dialog_name = "EstateBlockedExperienceRemove"; + break; - default: - return; - } + default: + return; + } - LLSD payload; - payload["operation"] = (S32)event_type; - payload["dialog_name"] = dialog_name; - payload["allowed_ids"].append(id); + LLSD payload; + payload["operation"] = (S32)event_type; + payload["dialog_name"] = dialog_name; + payload["allowed_ids"].append(id); - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); - LLNotification::Params params(dialog_name); - params.payload(payload) - .substitutions(args) - .functor.function(LLPanelRegionExperiences::experienceCoreConfirm); - if (LLPanelEstateInfo::isLindenEstate()) - { - LLNotifications::instance().forceResponse(params, 0); - } - else - { - LLNotifications::instance().add(params); - } + LLNotification::Params params(dialog_name); + params.payload(payload) + .substitutions(args) + .functor.function(LLPanelRegionExperiences::experienceCoreConfirm); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } - onChangeAnything(); + onChangeAnything(); } @@ -3073,583 +3073,583 @@ LLPanelEstateAccess::LLPanelEstateAccess() BOOL LLPanelEstateAccess::postBuild() { - getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); - if (avatar_name_list) - { - avatar_name_list->setCommitOnSelectionChange(TRUE); - avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - getChild("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2)); - childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this)); - childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this)); - childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this)); - - getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); - if (group_name_list) - { - group_name_list->setCommitOnSelectionChange(TRUE); - group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - getChild("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2)); - getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this)); - childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this)); - childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this)); - - getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); - if (banned_name_list) - { - banned_name_list->setCommitOnSelectionChange(TRUE); - banned_name_list->setMaxItemCount(ESTATE_MAX_BANNED_IDS); - } - - getChild("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2)); - childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this)); - childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this)); - childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this)); - - getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); - if (manager_name_list) - { - manager_name_list->setCommitOnSelectionChange(TRUE); - manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue - } - - childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this)); - childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this)); - - return TRUE; -} - -void LLPanelEstateAccess::updateControls(LLViewerRegion* region) -{ - BOOL god = gAgent.isGodlike(); - BOOL owner = (region && (region->getOwner() == gAgent.getID())); - BOOL manager = (region && region->isEstateManager()); - BOOL enable_cotrols = god || owner || manager; - setCtrlsEnabled(enable_cotrols); - - BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; - - getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols); - getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols); - getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols); - - getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols); - getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols); - getChildView("allowed_group_name_list")->setEnabled(enable_cotrols); - - // Can't ban people from mainland, orientation islands, etc. because this - // creates much network traffic and server load. - // Disable their accounts in CSR tool instead. - bool linden_estate = LLPanelEstateInfo::isLindenEstate(); - bool enable_ban = enable_cotrols && !linden_estate; - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols); - - // estate managers can't add estate managers - getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); - getChildView("estate_manager_name_list")->setEnabled(god || owner); - - if (enable_cotrols != mCtrlsEnabled) - { - mCtrlsEnabled = enable_cotrols; - updateLists(); // update the lists on the agent's access level change - } -} + getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); + if (avatar_name_list) + { + avatar_name_list->setCommitOnSelectionChange(TRUE); + avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } -//--------------------------------------------------------------------------- -// Add/Remove estate access button callbacks -//--------------------------------------------------------------------------- -void LLPanelEstateAccess::onClickAddAllowedAgent() -{ - LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - //args + getChild("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2)); + childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this)); + childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this)); + childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this)); - LLSD args; - args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); + getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); + if (group_name_list) + { + group_name_list->setCommitOnSelectionChange(TRUE); + group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + getChild("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2)); + getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this)); + childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this)); + childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this)); + + getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); + if (banned_name_list) + { + banned_name_list->setCommitOnSelectionChange(TRUE); + banned_name_list->setMaxItemCount(ESTATE_MAX_BANNED_IDS); + } + + getChild("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2)); + childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this)); + childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this)); + childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this)); + + getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); + if (manager_name_list) + { + manager_name_list->setCommitOnSelectionChange(TRUE); + manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue + } + + childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this)); + childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this)); + + return TRUE; +} + +void LLPanelEstateAccess::updateControls(LLViewerRegion* region) +{ + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + BOOL enable_cotrols = god || owner || manager; + setCtrlsEnabled(enable_cotrols); + + BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + + getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols); + getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols); + + getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols); + getChildView("allowed_group_name_list")->setEnabled(enable_cotrols); + + // Can't ban people from mainland, orientation islands, etc. because this + // creates much network traffic and server load. + // Disable their accounts in CSR tool instead. + bool linden_estate = LLPanelEstateInfo::isLindenEstate(); + bool enable_ban = enable_cotrols && !linden_estate; + getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols); + + // estate managers can't add estate managers + getChildView("add_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); + getChildView("estate_manager_name_list")->setEnabled(god || owner); + + if (enable_cotrols != mCtrlsEnabled) + { + mCtrlsEnabled = enable_cotrols; + updateLists(); // update the lists on the agent's access level change + } +} + +//--------------------------------------------------------------------------- +// Add/Remove estate access button callbacks +//--------------------------------------------------------------------------- +void LLPanelEstateAccess::onClickAddAllowedAgent() +{ + LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + //args + + LLSD args; + args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); } void LLPanelEstateAccess::onClickRemoveAllowedAgent() { - accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); + accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); } void LLPanelEstateAccess::onClickAddAllowedGroup() { - LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_GROUPS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); - return; - } - - LLNotification::Params params("ChangeLindenAccess"); - params.functor.function(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2)); - if (LLPanelEstateInfo::isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } + LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_GROUPS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); + return; + } + + LLNotification::Params params("ChangeLindenAccess"); + params.functor.function(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2)); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } } bool LLPanelEstateAccess::addAllowedGroup(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; - LLFloater* parent_floater = gFloaterView->getParentFloater(this); + LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); - if (widget) - { - widget->removeNoneOption(); - widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1)); - if (parent_floater) - { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); - widget->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(widget); - } - } + LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance("group_picker", LLSD(gAgent.getID())); + if (widget) + { + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1)); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); + widget->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(widget); + } + } - return false; + return false; } void LLPanelEstateAccess::onClickRemoveAllowedGroup() { - accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); + accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); } void LLPanelEstateAccess::onClickAddBannedAgent() { - LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_BANNED_IDS) - { - LLSD args; - args["MAX_BANNED"] = llformat("%d", ESTATE_MAX_BANNED_IDS); - LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); + LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_BANNED_IDS) + { + LLSD args; + args["MAX_BANNED"] = llformat("%d", ESTATE_MAX_BANNED_IDS); + LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); } void LLPanelEstateAccess::onClickRemoveBannedAgent() { - accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); + accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); } void LLPanelEstateAccess::onClickCopyAllowedList() { - copyListToClipboard("allowed_avatar_name_list"); + copyListToClipboard("allowed_avatar_name_list"); } void LLPanelEstateAccess::onClickCopyAllowedGroupList() { - copyListToClipboard("allowed_group_name_list"); + copyListToClipboard("allowed_group_name_list"); } void LLPanelEstateAccess::onClickCopyBannedList() { - copyListToClipboard("banned_avatar_name_list"); + copyListToClipboard("banned_avatar_name_list"); } // static void LLPanelEstateAccess::onClickAddEstateManager() { - LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_MANAGERS) - { // Tell user they can't add more managers - LLSD args; - args["MAX_MANAGER"] = llformat("%d", ESTATE_MAX_MANAGERS); - LLNotificationsUtil::add("MaxManagersOnRegion", args); - } - else - { // Go pick managers to add - accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); - } + LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_MANAGERS) + { // Tell user they can't add more managers + LLSD args; + args["MAX_MANAGER"] = llformat("%d", ESTATE_MAX_MANAGERS); + LLNotificationsUtil::add("MaxManagersOnRegion", args); + } + else + { // Go pick managers to add + accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); + } } // static void LLPanelEstateAccess::onClickRemoveEstateManager() { - accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); + accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); } // Special case callback for groups, since it has different callback format than names void LLPanelEstateAccess::addAllowedGroup2(LLUUID id) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (panel) - { - LLNameListCtrl* group_list = panel->getChild("allowed_group_name_list"); - LLScrollListItem* item = group_list->getNameItemByAgentId(id); - if (item) - { - LLSD args; - args["GROUP"] = item->getColumn(0)->getValue().asString(); - LLNotificationsUtil::add("GroupIsAlreadyInList", args); - return; - } - } - - LLSD payload; - payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; - payload["dialog_name"] = "EstateAllowedGroupAdd"; - payload["allowed_ids"].append(id); - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params("EstateAllowedGroupAdd"); - params.payload(payload) - .substitutions(args) - .functor.function(accessCoreConfirm); - if (LLPanelEstateInfo::isLindenEstate()) - { - LLNotifications::instance().forceResponse(params, 0); - } - else - { - LLNotifications::instance().add(params); - } + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + LLNameListCtrl* group_list = panel->getChild("allowed_group_name_list"); + LLScrollListItem* item = group_list->getNameItemByAgentId(id); + if (item) + { + LLSD args; + args["GROUP"] = item->getColumn(0)->getValue().asString(); + LLNotificationsUtil::add("GroupIsAlreadyInList", args); + return; + } + } + + LLSD payload; + payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; + payload["dialog_name"] = "EstateAllowedGroupAdd"; + payload["allowed_ids"].append(id); + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params("EstateAllowedGroupAdd"); + params.payload(payload) + .substitutions(args) + .functor.function(accessCoreConfirm); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } } // static void LLPanelEstateAccess::accessAddCore(U32 operation_flag, const std::string& dialog_name) { - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - // agent id filled in after avatar picker + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + // agent id filled in after avatar picker - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor.function(accessAddCore2); + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor.function(accessAddCore2); - if (LLPanelEstateInfo::isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - // same as clicking "OK" - LLNotifications::instance().forceResponse(params, 0); - } + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + // same as clicking "OK" + LLNotifications::instance().forceResponse(params, 0); + } } // static bool LLPanelEstateAccess::accessAddCore2(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // abort change - return false; - } - - LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); - //Get parent floater name - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; - const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : ""; - - //Determine the button that triggered opening of the avatar picker - //(so that a shadow frustum from the button to the avatar picker can be created) - LLView * button = NULL; - switch (change_info->mOperationFlag) - { - case ESTATE_ACCESS_ALLOWED_AGENT_ADD: - button = panel->findChild("add_allowed_avatar_btn"); - break; - - case ESTATE_ACCESS_BANNED_AGENT_ADD: - button = panel->findChild("add_banned_avatar_btn"); - break; - - case ESTATE_ACCESS_MANAGER_ADD: - button = panel->findChild("add_estate_manager_btn"); - break; - } - - // avatar picker yes multi-select, yes close-on-select - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, (void*)change_info), - TRUE, TRUE, FALSE, parent_floater_name, button); - - //Allows the closed parent floater to close the child floater (avatar picker) - if (child_floater) - { - parent_floater->addDependentFloater(child_floater); - } - - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // abort change + return false; + } + + LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + //Get parent floater name + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; + const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : ""; + + //Determine the button that triggered opening of the avatar picker + //(so that a shadow frustum from the button to the avatar picker can be created) + LLView * button = NULL; + switch (change_info->mOperationFlag) + { + case ESTATE_ACCESS_ALLOWED_AGENT_ADD: + button = panel->findChild("add_allowed_avatar_btn"); + break; + + case ESTATE_ACCESS_BANNED_AGENT_ADD: + button = panel->findChild("add_banned_avatar_btn"); + break; + + case ESTATE_ACCESS_MANAGER_ADD: + button = panel->findChild("add_estate_manager_btn"); + break; + } + + // avatar picker yes multi-select, yes close-on-select + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, (void*)change_info), + TRUE, TRUE, FALSE, parent_floater_name, button); + + //Allows the closed parent floater to close the child floater (avatar picker) + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } + + return false; } // static void LLPanelEstateAccess::accessAddCore3(const uuid_vec_t& ids, std::vector names, void* data) { - LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; - if (!change_info) return; - if (ids.empty()) - { - // User didn't select a name. - delete change_info; - change_info = NULL; - return; - } - // User did select a name. - change_info->mAgentOrGroupIDs = ids; - // Can't put estate owner on ban list - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLViewerRegion* region = gAgent.getRegion(); - if (!region) return; - - if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) - { - LLNameListCtrl* name_list = panel->getChild("allowed_avatar_name_list"); - int currentCount = (name_list ? name_list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d", ids.size()); - args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); - args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - - uuid_vec_t ids_allowed; - std::vector names_allowed; - std::string already_allowed; - bool single = true; - for (U32 i = 0; i < ids.size(); ++i) - { - LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); - if (item) - { - if (!already_allowed.empty()) - { - already_allowed += ", "; - single = false; - } - already_allowed += item->getColumn(0)->getValue().asString(); - } - else - { - ids_allowed.push_back(ids[i]); - names_allowed.push_back(names[i]); - } - } - if (!already_allowed.empty()) - { - LLSD args; - args["AGENT"] = already_allowed; - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); - LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); - if (ids_allowed.empty()) - { - delete change_info; - return; - } - } - change_info->mAgentOrGroupIDs = ids_allowed; - change_info->mAgentNames = names_allowed; - } - if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) - { - LLNameListCtrl* name_list = panel->getChild("banned_avatar_name_list"); - LLNameListCtrl* em_list = panel->getChild("estate_manager_name_list"); - int currentCount = (name_list ? name_list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_BANNED_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d", ids.size()); - args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_BANNED_IDS); - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); - args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_BANNED_IDS); - LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - - uuid_vec_t ids_allowed; - std::vector names_allowed; - std::string already_banned; - std::string em_ban; - bool single = true; - for (U32 i = 0; i < ids.size(); ++i) - { - bool is_allowed = true; - LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]); - if (em_item) - { - if (!em_ban.empty()) - { - em_ban += ", "; - } - em_ban += em_item->getColumn(0)->getValue().asString(); - is_allowed = false; - } - - LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); - if (item) - { - if (!already_banned.empty()) - { - already_banned += ", "; - single = false; - } - already_banned += item->getColumn(0)->getValue().asString(); - is_allowed = false; - } - - if (is_allowed) - { - ids_allowed.push_back(ids[i]); - names_allowed.push_back(names[i]); - } - } - if (!em_ban.empty()) - { - LLSD args; - args["AGENT"] = em_ban; - LLNotificationsUtil::add("ProblemBanningEstateManager", args); - if (ids_allowed.empty()) - { - delete change_info; - return; - } - } - if (!already_banned.empty()) - { - LLSD args; - args["AGENT"] = already_banned; - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); - LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); - if (ids_allowed.empty()) - { - delete change_info; - return; - } - } - change_info->mAgentOrGroupIDs = ids_allowed; - change_info->mAgentNames = names_allowed; - } - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - LLNotification::Params params(change_info->mDialogName); - params.substitutions(args) - .payload(change_info->asLLSD()) - .functor.function(accessCoreConfirm); - - if (LLPanelEstateInfo::isLindenEstate()) - { - // just apply to this estate - LLNotifications::instance().forceResponse(params, 0); - } - else - { - // ask if this estate or all estates with this owner - LLNotifications::instance().add(params); - } + LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; + if (!change_info) return; + if (ids.empty()) + { + // User didn't select a name. + delete change_info; + change_info = NULL; + return; + } + // User did select a name. + change_info->mAgentOrGroupIDs = ids; + // Can't put estate owner on ban list + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("allowed_avatar_name_list"); + int currentCount = (name_list ? name_list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d", ids.size()); + args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_allowed; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_allowed.empty()) + { + already_allowed += ", "; + single = false; + } + already_allowed += item->getColumn(0)->getValue().asString(); + } + else + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!already_allowed.empty()) + { + LLSD args; + args["AGENT"] = already_allowed; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("banned_avatar_name_list"); + LLNameListCtrl* em_list = panel->getChild("estate_manager_name_list"); + int currentCount = (name_list ? name_list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_BANNED_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d", ids.size()); + args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_BANNED_IDS); + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_BANNED_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_banned; + std::string em_ban; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + bool is_allowed = true; + LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]); + if (em_item) + { + if (!em_ban.empty()) + { + em_ban += ", "; + } + em_ban += em_item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_banned.empty()) + { + already_banned += ", "; + single = false; + } + already_banned += item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + if (is_allowed) + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!em_ban.empty()) + { + LLSD args; + args["AGENT"] = em_ban; + LLNotificationsUtil::add("ProblemBanningEstateManager", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + if (!already_banned.empty()) + { + LLSD args; + args["AGENT"] = already_banned; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotification::Params params(change_info->mDialogName); + params.substitutions(args) + .payload(change_info->asLLSD()) + .functor.function(accessCoreConfirm); + + if (LLPanelEstateInfo::isLindenEstate()) + { + // just apply to this estate + LLNotifications::instance().forceResponse(params, 0); + } + else + { + // ask if this estate or all estates with this owner + LLNotifications::instance().add(params); + } } // static void LLPanelEstateAccess::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); - if (!name_list) return; - - std::vector list_vector = name_list->getAllSelected(); - if (list_vector.size() == 0) - return; - - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - - for (std::vector::const_iterator iter = list_vector.begin(); - iter != list_vector.end(); - iter++) - { - LLScrollListItem *item = (*iter); - payload["allowed_ids"].append(item->getUUID()); - } - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor.function(accessRemoveCore2); - - if (LLPanelEstateInfo::isLindenEstate()) - { - // warn on change linden estate - LLNotifications::instance().add(params); - } - else - { - // just proceed, as if clicking OK - LLNotifications::instance().forceResponse(params, 0); - } + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllSelected(); + if (list_vector.size() == 0) + return; + + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + payload["allowed_ids"].append(item->getUUID()); + } + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor.function(accessRemoveCore2); + + if (LLPanelEstateInfo::isLindenEstate()) + { + // warn on change linden estate + LLNotifications::instance().add(params); + } + else + { + // just proceed, as if clicking OK + LLNotifications::instance().forceResponse(params, 0); + } } // static bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // abort - return false; - } - - // If Linden estate, can only apply to "this" estate, not all estates - // owned by NULL. - if (LLPanelEstateInfo::isLindenEstate()) - { - accessCoreConfirm(notification, response); - } - else - { - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - LLNotificationsUtil::add(notification["payload"]["dialog_name"], - args, - notification["payload"], - accessCoreConfirm); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // abort + return false; + } + + // If Linden estate, can only apply to "this" estate, not all estates + // owned by NULL. + if (LLPanelEstateInfo::isLindenEstate()) + { + accessCoreConfirm(notification, response); + } + else + { + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotificationsUtil::add(notification["payload"]["dialog_name"], + args, + notification["payload"], + accessCoreConfirm); + } + return false; } // Used for both access add and remove operations, depending on the mOperationFlag @@ -3657,133 +3657,133 @@ bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD // static bool LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); - U32 flags = originalFlags; - - LLViewerRegion* region = gAgent.getRegion(); - - if (option == 2) // cancel - { - return false; - } - else if (option == 1) - { - // All estates, either than I own or manage for this owner. - // This will be verified on simulator. JC - if (!region) return false; - if (region->getOwner() == gAgent.getID() - || gAgent.isGodlike()) - { - flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; - } - else if (region->isEstateManager()) - { - flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; - } - } - - std::string names; - U32 listed_names = 0; - for (U32 i = 0; i < notification["payload"]["allowed_ids"].size(); ++i) - { - if (i + 1 != notification["payload"]["allowed_ids"].size()) - { - flags |= ESTATE_ACCESS_NO_REPLY; - } - else - { - flags &= ~ESTATE_ACCESS_NO_REPLY; - } - - const LLUUID id = notification["payload"]["allowed_ids"][i].asUUID(); - if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) - && region && (region->getOwner() == id)) - { - LLNotificationsUtil::add("OwnerCanNotBeDenied"); - break; - } - - sendEstateAccessDelta(flags, id); - - if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0) - { - // fill the name list for confirmation - if (listed_names < MAX_LISTED_NAMES) - { - if (!names.empty()) - { - names += ", "; - } - if (!notification["payload"]["allowed_names"][i]["display_name"].asString().empty()) - { - names += notification["payload"]["allowed_names"][i]["display_name"].asString(); - } - else - { //try to get an agent name from cache - LLAvatarName av_name; - if (LLAvatarNameCache::get(id, &av_name)) - { - names += av_name.getCompleteName(); - } - } - - } - listed_names++; - } - } - if (listed_names > MAX_LISTED_NAMES) - { - LLSD args; - args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES); - names += " " + LLTrans::getString("AndNMore", args); - } - - if (!names.empty()) // show the conirmation - { - LLSD args; - args["AGENT"] = names; - - if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE)) - { - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); - } - else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) - { - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); - } - - if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES) - { - args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates"); - } - else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES) - { - args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates"); - } - else - { - args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate"); - } - - bool single = (listed_names == 1); - if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD)) - { - LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args); - } - else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) - { - LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args); - } - } - - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (panel) - { - panel->setPendingUpdate(true); - } - - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + U32 flags = originalFlags; + + LLViewerRegion* region = gAgent.getRegion(); + + if (option == 2) // cancel + { + return false; + } + else if (option == 1) + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) return false; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + } + } + + std::string names; + U32 listed_names = 0; + for (U32 i = 0; i < notification["payload"]["allowed_ids"].size(); ++i) + { + if (i + 1 != notification["payload"]["allowed_ids"].size()) + { + flags |= ESTATE_ACCESS_NO_REPLY; + } + else + { + flags &= ~ESTATE_ACCESS_NO_REPLY; + } + + const LLUUID id = notification["payload"]["allowed_ids"][i].asUUID(); + if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) + && region && (region->getOwner() == id)) + { + LLNotificationsUtil::add("OwnerCanNotBeDenied"); + break; + } + + sendEstateAccessDelta(flags, id); + + if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0) + { + // fill the name list for confirmation + if (listed_names < MAX_LISTED_NAMES) + { + if (!names.empty()) + { + names += ", "; + } + if (!notification["payload"]["allowed_names"][i]["display_name"].asString().empty()) + { + names += notification["payload"]["allowed_names"][i]["display_name"].asString(); + } + else + { //try to get an agent name from cache + LLAvatarName av_name; + if (LLAvatarNameCache::get(id, &av_name)) + { + names += av_name.getCompleteName(); + } + } + + } + listed_names++; + } + } + if (listed_names > MAX_LISTED_NAMES) + { + LLSD args; + args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES); + names += " " + LLTrans::getString("AndNMore", args); + } + + if (!names.empty()) // show the conirmation + { + LLSD args; + args["AGENT"] = names; + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + } + else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + } + + if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates"); + } + else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates"); + } + else + { + args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate"); + } + + bool single = (listed_names == 1); + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD)) + { + LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args); + } + else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args); + } + } + + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + panel->setPendingUpdate(true); + } + + return false; } // key = "estateaccessdelta" @@ -3794,164 +3794,164 @@ bool LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD // static void LLPanelEstateAccess::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) { - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", "estateaccessdelta"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + msg->nextBlock("MethodData"); + msg->addString("Method", "estateaccessdelta"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - std::string buf; - gAgent.getID().toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); + std::string buf; + gAgent.getID().toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); - buf = llformat("%u", flags); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); + buf = llformat("%u", flags); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); - agent_or_group_id.toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); + agent_or_group_id.toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); - gAgent.sendReliableMessage(); + gAgent.sendReliableMessage(); } void LLPanelEstateAccess::updateChild(LLUICtrl* child_ctrl) { - // Ensure appropriate state of the management ui. - updateControls(gAgent.getRegion()); + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); } void LLPanelEstateAccess::updateLists() { - std::string cap_url = gAgent.getRegionCapability("EstateAccess"); - if (!cap_url.empty()) - { - LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url)); - } + std::string cap_url = gAgent.getRegionCapability("EstateAccess"); + if (!cap_url.empty()) + { + LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url)); + } } void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url) { - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - - LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); - if (allowed_agent_name_list && result.has("AllowedAgents")) - { - LLStringUtil::format_map_t args; - args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size()); - args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); - panel->getChild("allow_resident_label")->setValue(LLSD(msg)); - - allowed_agent_name_list->clearSortOrder(); - allowed_agent_name_list->deleteAllItems(); - for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it) - { - LLUUID id = (*it)["id"].asUUID(); - allowed_agent_name_list->addNameItem(id); - } - allowed_agent_name_list->sortByName(TRUE); - } - - LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); - if (banned_agent_name_list && result.has("BannedAgents")) - { - LLStringUtil::format_map_t args; - args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size()); - args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_BANNED_IDS); - std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); - panel->getChild("ban_resident_label")->setValue(LLSD(msg)); - - banned_agent_name_list->clearSortOrder(); - banned_agent_name_list->deleteAllItems(); - for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it) - { - LLSD item; - item["id"] = (*it)["id"].asUUID(); - LLSD& columns = item["columns"]; - - columns[0]["column"] = "name"; // to be populated later - - columns[1]["column"] = "last_login_date"; - columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds - - std::string ban_date = (*it)["ban_date"].asString(); - columns[2]["column"] = "ban_date"; - columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : LLTrans::getString("na"); // server returns the "0000-00-00 00:00:00" date in case it doesn't know it - - columns[3]["column"] = "bannedby"; - LLUUID banning_id = (*it)["banning_id"].asUUID(); - LLAvatarName av_name; - if (banning_id.isNull()) - { - columns[3]["value"] = LLTrans::getString("na"); - } - else if (LLAvatarNameCache::get(banning_id, &av_name)) - { - columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached - } - - banned_agent_name_list->addElement(item); - } - banned_agent_name_list->sortByName(TRUE); - } - - LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); - if (allowed_group_name_list && result.has("AllowedGroups")) - { - LLStringUtil::format_map_t args; - args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size()); - args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); - panel->getChild("allow_group_label")->setValue(LLSD(msg)); - - allowed_group_name_list->clearSortOrder(); - allowed_group_name_list->deleteAllItems(); - for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it) - { - LLUUID id = (*it)["id"].asUUID(); - allowed_group_name_list->addGroupNameItem(id); - } - allowed_group_name_list->sortByName(TRUE); - } - - LLNameListCtrl* estate_manager_name_list = panel->getChild("estate_manager_name_list"); - if (estate_manager_name_list && result.has("Managers")) - { - LLStringUtil::format_map_t args; - args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size()); - args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); - std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); - panel->getChild("estate_manager_label")->setValue(LLSD(msg)); - - estate_manager_name_list->clearSortOrder(); - estate_manager_name_list->deleteAllItems(); - for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it) - { - LLUUID id = (*it)["agent_id"].asUUID(); - estate_manager_name_list->addNameItem(id); - } - estate_manager_name_list->sortByName(TRUE); - } - - - panel->updateControls(gAgent.getRegion()); + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + if (allowed_agent_name_list && result.has("AllowedAgents")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); + panel->getChild("allow_resident_label")->setValue(LLSD(msg)); + + allowed_agent_name_list->clearSortOrder(); + allowed_agent_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_agent_name_list->addNameItem(id); + } + allowed_agent_name_list->sortByName(TRUE); + } + + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + if (banned_agent_name_list && result.has("BannedAgents")) + { + LLStringUtil::format_map_t args; + args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size()); + args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_BANNED_IDS); + std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); + panel->getChild("ban_resident_label")->setValue(LLSD(msg)); + + banned_agent_name_list->clearSortOrder(); + banned_agent_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it) + { + LLSD item; + item["id"] = (*it)["id"].asUUID(); + LLSD& columns = item["columns"]; + + columns[0]["column"] = "name"; // to be populated later + + columns[1]["column"] = "last_login_date"; + columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds + + std::string ban_date = (*it)["ban_date"].asString(); + columns[2]["column"] = "ban_date"; + columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : LLTrans::getString("na"); // server returns the "0000-00-00 00:00:00" date in case it doesn't know it + + columns[3]["column"] = "bannedby"; + LLUUID banning_id = (*it)["banning_id"].asUUID(); + LLAvatarName av_name; + if (banning_id.isNull()) + { + columns[3]["value"] = LLTrans::getString("na"); + } + else if (LLAvatarNameCache::get(banning_id, &av_name)) + { + columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached + } + + banned_agent_name_list->addElement(item); + } + banned_agent_name_list->sortByName(TRUE); + } + + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + if (allowed_group_name_list && result.has("AllowedGroups")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); + panel->getChild("allow_group_label")->setValue(LLSD(msg)); + + allowed_group_name_list->clearSortOrder(); + allowed_group_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_group_name_list->addGroupNameItem(id); + } + allowed_group_name_list->sortByName(TRUE); + } + + LLNameListCtrl* estate_manager_name_list = panel->getChild("estate_manager_name_list"); + if (estate_manager_name_list && result.has("Managers")) + { + LLStringUtil::format_map_t args; + args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size()); + args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); + std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); + panel->getChild("estate_manager_label")->setValue(LLSD(msg)); + + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it) + { + LLUUID id = (*it)["agent_id"].asUUID(); + estate_manager_name_list->addNameItem(id); + } + estate_manager_name_list->sortByName(TRUE); + } + + + panel->updateControls(gAgent.getRegion()); } //--------------------------------------------------------------------------- @@ -3959,76 +3959,76 @@ void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url) //--------------------------------------------------------------------------- void LLPanelEstateAccess::onAllowedSearchEdit(const std::string& search_string) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); - searchAgent(allowed_agent_name_list, search_string); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + searchAgent(allowed_agent_name_list, search_string); } void LLPanelEstateAccess::onAllowedGroupsSearchEdit(const std::string& search_string) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); - searchAgent(allowed_group_name_list, search_string); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + searchAgent(allowed_group_name_list, search_string); } void LLPanelEstateAccess::onBannedSearchEdit(const std::string& search_string) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); - searchAgent(banned_agent_name_list, search_string); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + searchAgent(banned_agent_name_list, search_string); } void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string) { - if (!listCtrl) return; + if (!listCtrl) return; - if (!search_string.empty()) - { - listCtrl->setSearchColumn(0); // name column - listCtrl->searchItems(search_string, false, true); - } - else - { - listCtrl->deselectAllItems(TRUE); - } + if (!search_string.empty()) + { + listCtrl->setSearchColumn(0); // name column + listCtrl->searchItems(search_string, false, true); + } + else + { + listCtrl->deselectAllItems(TRUE); + } } void LLPanelEstateAccess::copyListToClipboard(std::string list_name) { - LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); - if (!panel) return; - LLNameListCtrl* name_list = panel->getChild(list_name); - if (!name_list) return; - - std::vector list_vector = name_list->getAllData(); - if (list_vector.size() == 0) return; - - LLSD::String list_to_copy; - for (std::vector::const_iterator iter = list_vector.begin(); - iter != list_vector.end(); - iter++) - { - LLScrollListItem *item = (*iter); - if (item) - { - list_to_copy += item->getColumn(0)->getValue().asString(); - } - if (std::next(iter) != list_vector.end()) - { - list_to_copy += "\n"; - } - } - - LLClipboard::instance().copyToClipboard(utf8str_to_wstring(list_to_copy), 0, list_to_copy.length()); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllData(); + if (list_vector.size() == 0) return; + + LLSD::String list_to_copy; + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + if (item) + { + list_to_copy += item->getColumn(0)->getValue().asString(); + } + if (std::next(iter) != list_vector.end()) + { + list_to_copy += "\n"; + } + } + + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(list_to_copy), 0, list_to_copy.length()); } bool LLPanelEstateAccess::refreshFromRegion(LLViewerRegion* region) { - updateLists(); - return LLPanelRegionInfo::refreshFromRegion(region); + updateLists(); + return LLPanelRegionInfo::refreshFromRegion(region); } //========================================================================= @@ -4164,10 +4164,10 @@ void LLPanelRegionEnvironment::onChkAllowOverride(bool value) if (LLPanelEstateInfo::isLindenEstate()) notification = "ChangeLindenEstate"; - LLSD args; - args["ESTATENAME"] = LLEstateInfoModel::instance().getName(); - LLNotification::Params params(notification); - params.substitutions(args); + LLSD args; + args["ESTATENAME"] = LLEstateInfoModel::instance().getName(); + LLNotification::Params params(notification); + params.substitutions(args); params.functor.function([this](const LLSD& notification, const LLSD& response) { confirmUpdateEstateEnvironment(notification, response); }); if (!value || LLPanelEstateInfo::isLindenEstate()) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index da17212016..c96e11b5be 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -1,4 +1,4 @@ -/** +/** * @file llfloaterregioninfo.h * @author Aaron Brashears * @brief Declaration of the region info and controls floater and panels. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -73,58 +73,58 @@ class LLEventTimer; class LLFloaterRegionInfo : public LLFloater { - friend class LLFloaterReg; + friend class LLFloaterReg; public: - void onOpen(const LLSD& key) override; - void onClose(bool app_quitting) override; - BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void onClose(bool app_quitting) override; + BOOL postBuild() override; + + static void processEstateOwnerRequest(LLMessageSystem* msg, void**); - static void processEstateOwnerRequest(LLMessageSystem* msg, void**); + // get and process region info if necessary. + static void processRegionInfo(LLMessageSystem* msg); - // get and process region info if necessary. - static void processRegionInfo(LLMessageSystem* msg); + static const LLUUID& getLastInvoice() { return sRequestInvoice; } + static void nextInvoice() { sRequestInvoice.generate(); } + //static S32 getSerial() { return sRequestSerial; } + //static void incrementSerial() { sRequestSerial++; } - static const LLUUID& getLastInvoice() { return sRequestInvoice; } - static void nextInvoice() { sRequestInvoice.generate(); } - //static S32 getSerial() { return sRequestSerial; } - //static void incrementSerial() { sRequestSerial++; } + static LLPanelEstateInfo* getPanelEstate(); + static LLPanelEstateAccess* getPanelAccess(); + static LLPanelEstateCovenant* getPanelCovenant(); + static LLPanelRegionTerrainInfo* getPanelRegionTerrain(); + static LLPanelRegionExperiences* getPanelExperiences(); + static LLPanelRegionGeneralInfo* getPanelGeneral(); + static LLPanelRegionEnvironment* getPanelEnvironment(); - static LLPanelEstateInfo* getPanelEstate(); - static LLPanelEstateAccess* getPanelAccess(); - static LLPanelEstateCovenant* getPanelCovenant(); - static LLPanelRegionTerrainInfo* getPanelRegionTerrain(); - static LLPanelRegionExperiences* getPanelExperiences(); - static LLPanelRegionGeneralInfo* getPanelGeneral(); - static LLPanelRegionEnvironment* getPanelEnvironment(); + // from LLPanel + void refresh() override; - // from LLPanel - void refresh() override; - - void onRegionChanged(); - void requestRegionInfo(); - void enableTopButtons(); - void disableTopButtons(); + void onRegionChanged(); + void requestRegionInfo(); + void enableTopButtons(); + void disableTopButtons(); private: - - LLFloaterRegionInfo(const LLSD& seed); - ~LLFloaterRegionInfo(); + + LLFloaterRegionInfo(const LLSD& seed); + ~LLFloaterRegionInfo(); protected: - void onTabSelected(const LLSD& param); - void disableTabCtrls(); - void refreshFromRegion(LLViewerRegion* region); - void onGodLevelChange(U8 god_level); - - // member data - LLTabContainer* mTab; - typedef std::vector info_panels_t; - info_panels_t mInfoPanels; + void onTabSelected(const LLSD& param); + void disableTabCtrls(); + void refreshFromRegion(LLViewerRegion* region); + void onGodLevelChange(U8 god_level); + + // member data + LLTabContainer* mTab; + typedef std::vector info_panels_t; + info_panels_t mInfoPanels; LLPanelRegionEnvironment *mEnvironmentPanel; - //static S32 sRequestSerial; // serial # of last EstateOwnerRequest - static LLUUID sRequestInvoice; + //static S32 sRequestSerial; // serial # of last EstateOwnerRequest + static LLUUID sRequestInvoice; private: LLAgent::god_level_change_slot_t mGodLevelChangeSlot; @@ -136,42 +136,42 @@ private: class LLPanelRegionInfo : public LLPanel { public: - LLPanelRegionInfo(); - - void onBtnSet(); - void onChangeChildCtrl(LLUICtrl* ctrl); - void onChangeAnything(); - static void onChangeText(LLLineEditor* caller, void* user_data); - - virtual bool refreshFromRegion(LLViewerRegion* region); - virtual bool estateUpdate(LLMessageSystem* msg) { return true; } - - BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); - - void enableButton(const std::string& btn_name, BOOL enable = TRUE); - void disableButton(const std::string& btn_name); - - void onClickManageTelehub(); - + LLPanelRegionInfo(); + + void onBtnSet(); + void onChangeChildCtrl(LLUICtrl* ctrl); + void onChangeAnything(); + static void onChangeText(LLLineEditor* caller, void* user_data); + + virtual bool refreshFromRegion(LLViewerRegion* region); + virtual bool estateUpdate(LLMessageSystem* msg) { return true; } + + BOOL postBuild() override; + virtual void updateChild(LLUICtrl* child_ctrl); + + void enableButton(const std::string& btn_name, BOOL enable = TRUE); + void disableButton(const std::string& btn_name); + + void onClickManageTelehub(); + protected: - void initCtrl(const std::string& name); - - // Returns TRUE if update sent and apply button should be - // disabled. - virtual BOOL sendUpdate() { return TRUE; } - - typedef std::vector strings_t; - //typedef std::vector integers_t; - void sendEstateOwnerMessage( - LLMessageSystem* msg, - const std::string& request, - const LLUUID& invoice, - const strings_t& strings); - - - // member data - LLHost mHost; + void initCtrl(const std::string& name); + + // Returns TRUE if update sent and apply button should be + // disabled. + virtual BOOL sendUpdate() { return TRUE; } + + typedef std::vector strings_t; + //typedef std::vector integers_t; + void sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings); + + + // member data + LLHost mHost; }; ///////////////////////////////////////////////////////////////////////////// @@ -180,30 +180,30 @@ protected: class LLPanelRegionGeneralInfo : public LLPanelRegionInfo { - + public: - LLPanelRegionGeneralInfo() - : LLPanelRegionInfo() {} - ~LLPanelRegionGeneralInfo() {} - - bool refreshFromRegion(LLViewerRegion* region) override; - - BOOL postBuild() override; - - void onBtnSet(); - void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;} + LLPanelRegionGeneralInfo() + : LLPanelRegionInfo() {} + ~LLPanelRegionGeneralInfo() {} + + bool refreshFromRegion(LLViewerRegion* region) override; + + BOOL postBuild() override; + + void onBtnSet(); + void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;} protected: - BOOL sendUpdate() override; - void onClickKick(); - void onKickCommit(const uuid_vec_t& ids); - static void onClickKickAll(void* userdata); - bool onKickAllCommit(const LLSD& notification, const LLSD& response); - static void onClickMessage(void* userdata); - bool onMessageCommit(const LLSD& notification, const LLSD& response); - bool onChangeObjectBonus(const LLSD& notification, const LLSD& response); + BOOL sendUpdate() override; + void onClickKick(); + void onKickCommit(const uuid_vec_t& ids); + static void onClickKickAll(void* userdata); + bool onKickAllCommit(const LLSD& notification, const LLSD& response); + static void onClickMessage(void* userdata); + bool onMessageCommit(const LLSD& notification, const LLSD& response); + bool onChangeObjectBonus(const LLSD& notification, const LLSD& response); - F32 mObjBonusFactor; + F32 mObjBonusFactor; }; @@ -212,68 +212,68 @@ protected: class LLPanelRegionDebugInfo : public LLPanelRegionInfo { public: - LLPanelRegionDebugInfo() - : LLPanelRegionInfo(), mTargetAvatar() {} - ~LLPanelRegionDebugInfo() {} - - BOOL postBuild() override; - - bool refreshFromRegion(LLViewerRegion* region) override; - + LLPanelRegionDebugInfo() + : LLPanelRegionInfo(), mTargetAvatar() {} + ~LLPanelRegionDebugInfo() {} + + BOOL postBuild() override; + + bool refreshFromRegion(LLViewerRegion* region) override; + protected: - BOOL sendUpdate() override; - - void onClickChooseAvatar(); - void callbackAvatarID(const uuid_vec_t& ids, const std::vector names); - static void onClickReturn(void *); - bool callbackReturn(const LLSD& notification, const LLSD& response); - static void onClickTopColliders(void*); - static void onClickTopScripts(void*); - static void onClickRestart(void* data); - bool callbackRestart(const LLSD& notification, const LLSD& response); - static void onClickCancelRestart(void* data); - static void onClickDebugConsole(void* data); - + BOOL sendUpdate() override; + + void onClickChooseAvatar(); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector names); + static void onClickReturn(void *); + bool callbackReturn(const LLSD& notification, const LLSD& response); + static void onClickTopColliders(void*); + static void onClickTopScripts(void*); + static void onClickRestart(void* data); + bool callbackRestart(const LLSD& notification, const LLSD& response); + static void onClickCancelRestart(void* data); + static void onClickDebugConsole(void* data); + private: - LLUUID mTargetAvatar; + LLUUID mTargetAvatar; }; ///////////////////////////////////////////////////////////////////////////// class LLPanelRegionTerrainInfo : public LLPanelRegionInfo { - LOG_CLASS(LLPanelRegionTerrainInfo); + LOG_CLASS(LLPanelRegionTerrainInfo); public: - LLPanelRegionTerrainInfo(); - ~LLPanelRegionTerrainInfo() {} - - BOOL postBuild() override; - + LLPanelRegionTerrainInfo(); + ~LLPanelRegionTerrainInfo() {} + + BOOL postBuild() override; + bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator - void setEnvControls(bool available); // Whether environment settings are available for this region + void setEnvControls(bool available); // Whether environment settings are available for this region bool validateTextureSizes(); bool validateMaterials(); - BOOL validateTextureHeights(); + BOOL validateTextureHeights(); + + //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button - //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button - void onSelectMaterialType(); void updateForMaterialType(); - static void onClickDownloadRaw(void*); - static void onClickUploadRaw(void*); - static void onClickBakeTerrain(void*); - bool callbackBakeTerrain(const LLSD& notification, const LLSD& response); - bool callbackTextureHeights(const LLSD& notification, const LLSD& response); + static void onClickDownloadRaw(void*); + static void onClickUploadRaw(void*); + static void onClickBakeTerrain(void*); + bool callbackBakeTerrain(const LLSD& notification, const LLSD& response); + bool callbackTextureHeights(const LLSD& notification, const LLSD& response); protected: - BOOL sendUpdate() override; + BOOL sendUpdate() override; private: - bool mConfirmedTextureHeights; - bool mAskedTextureHeights; + bool mConfirmedTextureHeights; + bool mAskedTextureHeights; LLCheckBoxCtrl* mMaterialTypeCtrl = nullptr; LLTextureCtrl* mTextureDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; LLTextureCtrl* mMaterialDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; @@ -286,59 +286,59 @@ private: class LLPanelEstateInfo : public LLPanelRegionInfo { public: - static void initDispatch(LLDispatcher& dispatch); - - void onChangeFixedSun(); - void onChangeUseGlobalTime(); - void onChangeAccessOverride(); - - void onClickEditSky(); - void onClickEditSkyHelp(); - void onClickEditDayCycle(); - void onClickEditDayCycleHelp(); - - void onClickKickUser(); - - - bool kickUserConfirm(const LLSD& notification, const LLSD& response); - - void onKickUserCommit(const uuid_vec_t& ids); - static void onClickMessageEstate(void* data); - bool onMessageCommit(const LLSD& notification, const LLSD& response); - - LLPanelEstateInfo(); - ~LLPanelEstateInfo() {} - - void updateControls(LLViewerRegion* region); - - static void updateEstateName(const std::string& name); - static void updateEstateOwnerName(const std::string& name); - - bool refreshFromRegion(LLViewerRegion* region) override; - bool estateUpdate(LLMessageSystem* msg) override; - - BOOL postBuild() override; - void updateChild(LLUICtrl* child_ctrl) override; - void refresh() override; - - void refreshFromEstate(); - - static bool isLindenEstate(); - - const std::string getOwnerName() const; - void setOwnerName(const std::string& name); + static void initDispatch(LLDispatcher& dispatch); + + void onChangeFixedSun(); + void onChangeUseGlobalTime(); + void onChangeAccessOverride(); + + void onClickEditSky(); + void onClickEditSkyHelp(); + void onClickEditDayCycle(); + void onClickEditDayCycleHelp(); + + void onClickKickUser(); + + + bool kickUserConfirm(const LLSD& notification, const LLSD& response); + + void onKickUserCommit(const uuid_vec_t& ids); + static void onClickMessageEstate(void* data); + bool onMessageCommit(const LLSD& notification, const LLSD& response); + + LLPanelEstateInfo(); + ~LLPanelEstateInfo() {} + + void updateControls(LLViewerRegion* region); + + static void updateEstateName(const std::string& name); + static void updateEstateOwnerName(const std::string& name); + + bool refreshFromRegion(LLViewerRegion* region) override; + bool estateUpdate(LLMessageSystem* msg) override; + + BOOL postBuild() override; + void updateChild(LLUICtrl* child_ctrl) override; + void refresh() override; + + void refreshFromEstate(); + + static bool isLindenEstate(); + + const std::string getOwnerName() const; + void setOwnerName(const std::string& name); protected: - BOOL sendUpdate() override; - // confirmation dialog callback - bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response); + BOOL sendUpdate() override; + // confirmation dialog callback + bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response); + + void commitEstateAccess(); + void commitEstateManagers(); - void commitEstateAccess(); - void commitEstateManagers(); - - BOOL checkSunHourSlider(LLUICtrl* child_ctrl); + BOOL checkSunHourSlider(LLUICtrl* child_ctrl); - U32 mEstateID; + U32 mEstateID; }; ///////////////////////////////////////////////////////////////////////////// @@ -346,59 +346,59 @@ protected: class LLPanelEstateCovenant : public LLPanelRegionInfo { public: - LLPanelEstateCovenant(); - ~LLPanelEstateCovenant() {} - - BOOL postBuild() override; - void updateChild(LLUICtrl* child_ctrl) override; - bool refreshFromRegion(LLViewerRegion* region) override; - bool estateUpdate(LLMessageSystem* msg) override; - - // LLView overrides - BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, - void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg) override; - static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response); - static void resetCovenantID(void* userdata); - static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response); - void sendChangeCovenantID(const LLUUID &asset_id); - void loadInvItem(LLInventoryItem *itemp); - static void onLoadComplete(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status); - - // Accessor functions - static void updateCovenantText(const std::string& string, const LLUUID& asset_id); - static void updateEstateName(const std::string& name); - static void updateLastModified(const std::string& text); - static void updateEstateOwnerName(const std::string& name); - - const LLUUID& getCovenantID() const { return mCovenantID; } - void setCovenantID(const LLUUID& id) { mCovenantID = id; } - std::string getEstateName() const; - void setEstateName(const std::string& name); - std::string getOwnerName() const; - void setOwnerName(const std::string& name); - void setCovenantTextEditor(const std::string& text); - - typedef enum e_asset_status - { - ASSET_ERROR, - ASSET_UNLOADED, - ASSET_LOADING, - ASSET_LOADED - } EAssetStatus; + LLPanelEstateCovenant(); + ~LLPanelEstateCovenant() {} + + BOOL postBuild() override; + void updateChild(LLUICtrl* child_ctrl) override; + bool refreshFromRegion(LLViewerRegion* region) override; + bool estateUpdate(LLMessageSystem* msg) override; + + // LLView overrides + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg) override; + static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response); + static void resetCovenantID(void* userdata); + static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response); + void sendChangeCovenantID(const LLUUID &asset_id); + void loadInvItem(LLInventoryItem *itemp); + static void onLoadComplete(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status); + + // Accessor functions + static void updateCovenantText(const std::string& string, const LLUUID& asset_id); + static void updateEstateName(const std::string& name); + static void updateLastModified(const std::string& text); + static void updateEstateOwnerName(const std::string& name); + + const LLUUID& getCovenantID() const { return mCovenantID; } + void setCovenantID(const LLUUID& id) { mCovenantID = id; } + std::string getEstateName() const; + void setEstateName(const std::string& name); + std::string getOwnerName() const; + void setOwnerName(const std::string& name); + void setCovenantTextEditor(const std::string& text); + + typedef enum e_asset_status + { + ASSET_ERROR, + ASSET_UNLOADED, + ASSET_LOADING, + ASSET_LOADED + } EAssetStatus; protected: - BOOL sendUpdate() override; - LLTextBox* mEstateNameText; - LLTextBox* mEstateOwnerText; - LLTextBox* mLastModifiedText; - // CovenantID from sim - LLUUID mCovenantID; - LLViewerTextEditor* mEditor; - EAssetStatus mAssetStatus; + BOOL sendUpdate() override; + LLTextBox* mEstateNameText; + LLTextBox* mEstateOwnerText; + LLTextBox* mLastModifiedText; + // CovenantID from sim + LLUUID mCovenantID; + LLViewerTextEditor* mEditor; + EAssetStatus mAssetStatus; }; ///////////////////////////////////////////////////////////////////////////// @@ -409,96 +409,96 @@ class LLPanelRegionExperiences : public LLPanelRegionInfo LOG_CLASS(LLPanelRegionExperiences); public: - LLPanelRegionExperiences(){} - BOOL postBuild() override; - - static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); - static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); + LLPanelRegionExperiences(){} + BOOL postBuild() override; - static void infoCallback(LLHandle handle, const LLSD& content); - bool refreshFromRegion(LLViewerRegion* region) override; - void sendPurchaseRequest()const; - void processResponse( const LLSD& content ); + static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); + static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); + + static void infoCallback(LLHandle handle, const LLSD& content); + bool refreshFromRegion(LLViewerRegion* region) override; + void sendPurchaseRequest()const; + void processResponse( const LLSD& content ); protected: - BOOL sendUpdate() override; + BOOL sendUpdate() override; private: - void refreshRegionExperiences(); + void refreshRegionExperiences(); static std::string regionCapabilityQuery(LLViewerRegion* region, const std::string &cap); - LLPanelExperienceListEditor* setupList(const char* control_name, U32 add_id, U32 remove_id); - static LLSD addIds( LLPanelExperienceListEditor* panel ); + LLPanelExperienceListEditor* setupList(const char* control_name, U32 add_id, U32 remove_id); + static LLSD addIds( LLPanelExperienceListEditor* panel ); - void itemChanged(U32 event_type, const LLUUID& id); + void itemChanged(U32 event_type, const LLUUID& id); - LLPanelExperienceListEditor* mTrusted; - LLPanelExperienceListEditor* mAllowed; - LLPanelExperienceListEditor* mBlocked; - LLUUID mDefaultExperience; + LLPanelExperienceListEditor* mTrusted; + LLPanelExperienceListEditor* mAllowed; + LLPanelExperienceListEditor* mBlocked; + LLUUID mDefaultExperience; }; class LLPanelEstateAccess : public LLPanelRegionInfo { - LOG_CLASS(LLPanelEstateAccess); + LOG_CLASS(LLPanelEstateAccess); public: - LLPanelEstateAccess(); + LLPanelEstateAccess(); - BOOL postBuild() override; - void updateChild(LLUICtrl* child_ctrl) override; + BOOL postBuild() override; + void updateChild(LLUICtrl* child_ctrl) override; - void updateControls(LLViewerRegion* region); - void updateLists(); + void updateControls(LLViewerRegion* region); + void updateLists(); - void setPendingUpdate(bool pending) { mPendingUpdate = pending; } - bool getPendingUpdate() { return mPendingUpdate; } + void setPendingUpdate(bool pending) { mPendingUpdate = pending; } + bool getPendingUpdate() { return mPendingUpdate; } - bool refreshFromRegion(LLViewerRegion* region) override; + bool refreshFromRegion(LLViewerRegion* region) override; private: - void onClickAddAllowedAgent(); - void onClickRemoveAllowedAgent(); - void onClickCopyAllowedList(); - void onClickAddAllowedGroup(); - void onClickRemoveAllowedGroup(); - void onClickCopyAllowedGroupList(); - void onClickAddBannedAgent(); - void onClickRemoveBannedAgent(); + void onClickAddAllowedAgent(); + void onClickRemoveAllowedAgent(); + void onClickCopyAllowedList(); + void onClickAddAllowedGroup(); + void onClickRemoveAllowedGroup(); + void onClickCopyAllowedGroupList(); + void onClickAddBannedAgent(); + void onClickRemoveBannedAgent(); void onClickCopyBannedList(); - void onClickAddEstateManager(); - void onClickRemoveEstateManager(); - void onAllowedSearchEdit(const std::string& search_string); - void onAllowedGroupsSearchEdit(const std::string& search_string); - void onBannedSearchEdit(const std::string& search_string); - - // Group picker callback is different, can't use core methods below - bool addAllowedGroup(const LLSD& notification, const LLSD& response); - void addAllowedGroup2(LLUUID id); + void onClickAddEstateManager(); + void onClickRemoveEstateManager(); + void onAllowedSearchEdit(const std::string& search_string); + void onAllowedGroupsSearchEdit(const std::string& search_string); + void onBannedSearchEdit(const std::string& search_string); + + // Group picker callback is different, can't use core methods below + bool addAllowedGroup(const LLSD& notification, const LLSD& response); + void addAllowedGroup2(LLUUID id); - // Core methods for all above add/remove button clicks - static void accessAddCore(U32 operation_flag, const std::string& dialog_name); - static bool accessAddCore2(const LLSD& notification, const LLSD& response); - static void accessAddCore3(const uuid_vec_t& ids, std::vector names, void* data); + // Core methods for all above add/remove button clicks + static void accessAddCore(U32 operation_flag, const std::string& dialog_name); + static bool accessAddCore2(const LLSD& notification, const LLSD& response); + static void accessAddCore3(const uuid_vec_t& ids, std::vector names, void* data); - static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); - static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); + static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); + static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); - // used for both add and remove operations - static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); + // used for both add and remove operations + static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); - // Send the actual EstateOwnerRequest "estateaccessdelta" message - static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); + // Send the actual EstateOwnerRequest "estateaccessdelta" message + static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); - static void requestEstateGetAccessCoro(std::string url); + static void requestEstateGetAccessCoro(std::string url); - void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string); - void copyListToClipboard(std::string list_name); + void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string); + void copyListToClipboard(std::string list_name); - bool mPendingUpdate; - BOOL mCtrlsEnabled; + bool mPendingUpdate; + BOOL mCtrlsEnabled; }; #endif diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 1c39f1ae7d..730a625879 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -302,12 +302,12 @@ PreviewSphere create_preview_sphere(LLPointer& material, LLStrider texcoords; LLStrider colors; LLStrider tangents; - buf->getIndexStrider(indices); - buf->getVertexStrider(positions); - buf->getNormalStrider(normals); - buf->getTexCoord0Strider(texcoords); - buf->getColorStrider(colors); - buf->getTangentStrider(tangents); + buf->getIndexStrider(indices); + buf->getVertexStrider(positions); + buf->getNormalStrider(normals); + buf->getTexCoord0Strider(texcoords); + buf->getColorStrider(colors); + buf->getTangentStrider(tangents); U32 index_offset = 0; U32 vertex_offset = 0; for (const LLVolumeFace& face : volume->getVolumeFaces()) @@ -427,7 +427,7 @@ BOOL LLGLTFPreviewTexture::render() glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + LLGLDepthTest(GL_FALSE); LLGLDisable stencil(GL_STENCIL_TEST); LLGLDisable scissor(GL_SCISSOR_TEST); @@ -527,27 +527,27 @@ BOOL LLGLTFPreviewTexture::render() LLVertexBuffer::unbind(); gPipeline.generateGlow(&gPipeline.mPostMap); gPipeline.combineGlow(&gPipeline.mPostMap, &screen); - gPipeline.renderDoF(&screen, &gPipeline.mPostMap); - gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + gPipeline.renderDoF(&screen, &gPipeline.mPostMap); + gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); // Final render - gDeferredPostNoDoFProgram.bind(); + gDeferredPostNoDoFProgram.bind(); - // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); + // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - gPipeline.mScreenTriangleVB->setBuffer(); - gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - gDeferredPostNoDoFProgram.unbind(); + gDeferredPostNoDoFProgram.unbind(); // Clean up gPipeline.setupHWLights(); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 55539a49d8..208dfe45bd 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -66,7 +66,7 @@ LLHeroProbeManager::LLHeroProbeManager() LLHeroProbeManager::~LLHeroProbeManager() { - cleanup(); + cleanup(); mHeroVOList.clear(); mNearestHero = nullptr; @@ -130,7 +130,7 @@ void LLHeroProbeManager::update() float center_distance = cameraDirection * (vo->getPositionAgent() - camera_pos); if (distance > LLViewerCamera::instance().getFar()) - continue; + continue; LLVector4a center; center.load3(vo->getPositionAgent().mV); @@ -142,18 +142,18 @@ void LLHeroProbeManager::update() if (distance < last_distance && center_distance < camera_center_distance && visible) { - probe_present = true; - mNearestHero = vo; - last_distance = distance; + probe_present = true; + mNearestHero = vo; + last_distance = distance; camera_center_distance = center_distance; - } + } } else { unregisterViewerObject(vo); } } - + // Don't even try to do anything if we didn't find a single mirror present. if (!probe_present) return; @@ -162,7 +162,7 @@ void LLHeroProbeManager::update() { LLVector3 hero_pos = mNearestHero->getPositionAgent(); LLVector3 face_normal = LLVector3(0, 0, 1); - + face_normal *= mNearestHero->mDrawable->getWorldRotation(); face_normal.normalize(); @@ -180,8 +180,8 @@ void LLHeroProbeManager::update() // Detect visible faces of a cube based on camera direction and distance // Define the cube faces - static LLVector3 cubeFaces[6] = { - LLVector3(1, 0, 0), + static LLVector3 cubeFaces[6] = { + LLVector3(1, 0, 0), LLVector3(-1, 0, 0), LLVector3(0, 1, 0), LLVector3(0, -1, 0), @@ -193,7 +193,7 @@ void LLHeroProbeManager::update() for (int i = 0; i < 6; i++) { float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])) * 0.6 + 0.4; - + float updateRate; if (cube_facing < 0.1f) { @@ -208,18 +208,18 @@ void LLHeroProbeManager::update() } } else - { + { mNearestHero = nullptr; } - + mHeroProbeStrength = 1; } else { probe_pos.load3(camera_pos.mV); } - - + + static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); @@ -228,9 +228,9 @@ void LLHeroProbeManager::update() LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); // Probe 0 is always our mirror probe. mProbes[0]->mOrigin = probe_pos; - + bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass(); - + gPipeline.mReflectionMapManager.mRadiancePass = true; mRenderingMirror = true; @@ -249,19 +249,19 @@ void LLHeroProbeManager::update() generateRadiance(mProbes[j]); } mRenderingMirror = false; - + gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; mProbes[0]->mViewerObject = mNearestHero; mProbes[0]->autoAdjustOrigin(); } - + mCurrentProbeUpdateFrame++; } // Do the reflection map update render passes. // For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated -// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate +// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate // a simple mip chain (not convolution filter). // At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. @@ -273,11 +273,11 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool gPipeline.mRT = &gPipeline.mHeroProbeRT; probe->update(mRenderTarget.getWidth(), face, is_dynamic, near_clip); - + gPipeline.mRT = &gPipeline.mMainRT; S32 sourceIdx = mReflectionProbeCount; - + // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. sourceIdx += 1; @@ -285,7 +285,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); LLGLDisable blend(GL_BLEND); - + // downsample to placeholder map { gGL.matrixMode(gGL.MM_MODELVIEW); @@ -351,14 +351,14 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool } gGL.getTexUnit(depthChannel)->bind(depth_rt, true); - + gReflectionMipProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2)); gReflectionMipProgram.uniform1f(znear, probe->getNearClip()); gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP); - + gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - + res /= 2; S32 mip = i - (mMipChain.size() - mips); @@ -459,13 +459,13 @@ void LLHeroProbeManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - + LLMatrix4a modelview; modelview.loadu(gGLModelView); LLVector4a oa; // scratch space for transformed origin oa.set(0, 0, 0, 0); mHeroData.heroProbeCount = 1; - + if (mNearestHero != nullptr && !mNearestHero->isDead()) { if (mNearestHero->getReflectionProbeIsBox()) @@ -477,18 +477,18 @@ void LLHeroProbeManager::updateUniforms() { mProbes[0]->mRadius = mNearestHero->getScale().mV[0] * 0.5f; } - + modelview.affineTransform(mProbes[0]->mOrigin, oa); mHeroData.heroShape = 0; if (!mProbes[0]->getBox(mHeroData.heroBox)) { mHeroData.heroShape = 1; } - + mHeroData.heroSphere.set(oa.getF32ptr()); mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius; } - + mHeroData.heroMipCount = mMipChain.size(); } @@ -537,14 +537,14 @@ void LLHeroProbeManager::initReflectionMaps() llassert(mProbes[0] == mDefaultProbe); // For hero probes, we treat this as the main mirror probe. - + mDefaultProbe->mCubeIndex = 0; mDefaultProbe->mCubeArray = mTexture; mDefaultProbe->mDistance = gSavedSettings.getF32("RenderHeroProbeDistance"); mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); - + mProbes.push_back(mDefaultProbe); } @@ -555,9 +555,9 @@ void LLHeroProbeManager::initReflectionMaps() buff->allocateBuffer(4, 0); LLStrider v; - + buff->getVertexStrider(v); - + v[0] = LLVector3(-1, -1, -1); v[1] = LLVector3(1, -1, -1); v[2] = LLVector3(-1, 1, -1); @@ -569,8 +569,8 @@ void LLHeroProbeManager::initReflectionMaps() } } -void LLHeroProbeManager::cleanup() -{ +void LLHeroProbeManager::cleanup() +{ mVertexBuffer = nullptr; mRenderTarget.release(); mHeroRenderTarget.release(); @@ -582,7 +582,7 @@ void LLHeroProbeManager::cleanup() mProbes.clear(); mReflectionMaps.clear(); - + mDefaultProbe = nullptr; mUpdatingProbe = nullptr; /* @@ -618,7 +618,7 @@ bool LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) mHeroVOList.push_back(drawablep); return true; } - + return false; } diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 8a284686ad..f43613be9f 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmanip.cpp * @brief LLManip class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,7 +49,7 @@ #include "llviewerobject.h" #include "llviewerwindow.h" #include "llvoavatar.h" -#include "llworld.h" // for LLWorld::getInstance() +#include "llworld.h" // for LLWorld::getInstance() #include "llresmgr.h" #include "pipeline.h" #include "llglheaders.h" @@ -57,39 +57,39 @@ // Local constants... const S32 VERTICAL_OFFSET = 50; -F32 LLManip::sHelpTextVisibleTime = 2.f; -F32 LLManip::sHelpTextFadeTime = 2.f; -S32 LLManip::sNumTimesHelpTextShown = 0; -S32 LLManip::sMaxTimesShowHelpText = 5; -F32 LLManip::sGridMaxSubdivisionLevel = 32.f; -F32 LLManip::sGridMinSubdivisionLevel = 1.f / 32.f; +F32 LLManip::sHelpTextVisibleTime = 2.f; +F32 LLManip::sHelpTextFadeTime = 2.f; +S32 LLManip::sNumTimesHelpTextShown = 0; +S32 LLManip::sMaxTimesShowHelpText = 5; +F32 LLManip::sGridMaxSubdivisionLevel = 32.f; +F32 LLManip::sGridMinSubdivisionLevel = 1.f / 32.f; LLVector2 LLManip::sTickLabelSpacing(60.f, 25.f); //static void LLManip::rebuild(LLViewerObject* vobj) { - LLDrawable* drawablep = vobj->mDrawable; - if (drawablep && drawablep->getVOVolume()) - { - gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME); - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED - drawablep->updateMove(); - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (group) - { - group->dirtyGeom(); - gPipeline.markRebuild(group); - } - - LLViewerObject::const_child_list_t& child_list = vobj->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end(); - iter != endIter; ++iter) - { - LLViewerObject* child = *iter; - rebuild(child); - } - } + LLDrawable* drawablep = vobj->mDrawable; + if (drawablep && drawablep->getVOVolume()) + { + gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME); + drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED + drawablep->updateMove(); + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + gPipeline.markRebuild(group); + } + + LLViewerObject::const_child_list_t& child_list = vobj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end(); + iter != endIter; ++iter) + { + LLViewerObject* child = *iter; + rebuild(child); + } + } } ////////////////////////////////////////////////////////////////////////////// @@ -97,204 +97,204 @@ void LLManip::rebuild(LLViewerObject* vobj) LLManip::LLManip( const std::string& name, LLToolComposite* composite ) - : - LLTool( name, composite ), - mInSnapRegime(FALSE), - mHighlightedPart(LL_NO_PART), - mManipPart(LL_NO_PART) + : + LLTool( name, composite ), + mInSnapRegime(FALSE), + mHighlightedPart(LL_NO_PART), + mManipPart(LL_NO_PART) { } void LLManip::getManipNormal(LLViewerObject* object, EManipPart manip, LLVector3 &normal) { - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW) - { - LLVector3 arrow_axis; - getManipAxis(object, manip, arrow_axis); - - LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis(); - normal = cross % arrow_axis; - normal.normVec(); - } - else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE) - { - switch (manip) - { - case LL_YZ_PLANE: - normal = LLVector3::x_axis; - break; - case LL_XZ_PLANE: - normal = LLVector3::y_axis; - break; - case LL_XY_PLANE: - normal = LLVector3::z_axis; - break; - default: - break; - } - normal.rotVec(grid_rotation); - } - else - { - normal.clearVec(); - } + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW) + { + LLVector3 arrow_axis; + getManipAxis(object, manip, arrow_axis); + + LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis(); + normal = cross % arrow_axis; + normal.normVec(); + } + else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE) + { + switch (manip) + { + case LL_YZ_PLANE: + normal = LLVector3::x_axis; + break; + case LL_XZ_PLANE: + normal = LLVector3::y_axis; + break; + case LL_XY_PLANE: + normal = LLVector3::z_axis; + break; + default: + break; + } + normal.rotVec(grid_rotation); + } + else + { + normal.clearVec(); + } } BOOL LLManip::getManipAxis(LLViewerObject* object, EManipPart manip, LLVector3 &axis) { - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - if (manip == LL_X_ARROW) - { - axis = LLVector3::x_axis; - } - else if (manip == LL_Y_ARROW) - { - axis = LLVector3::y_axis; - } - else if (manip == LL_Z_ARROW) - { - axis = LLVector3::z_axis; - } - else - { - return FALSE; - } - - axis.rotVec( grid_rotation ); - return TRUE; + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + if (manip == LL_X_ARROW) + { + axis = LLVector3::x_axis; + } + else if (manip == LL_Y_ARROW) + { + axis = LLVector3::y_axis; + } + else if (manip == LL_Z_ARROW) + { + axis = LLVector3::z_axis; + } + else + { + return FALSE; + } + + axis.rotVec( grid_rotation ); + return TRUE; } F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVector3 &translate_axis, F32 grid_scale, S32 min_pixel_spacing, F32 min_subdivisions, F32 max_subdivisions) { - //update current snap subdivision level - LLVector3 cam_to_reference; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f); - } - else - { - cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin(); - } - F32 current_range = cam_to_reference.normVec(); - - F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec(); - F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f); - // figure out nearest power of 2 that subdivides grid_scale with result > min_pixel_spacing - subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), min_subdivisions, max_subdivisions); - - return subdivisions; + //update current snap subdivision level + LLVector3 cam_to_reference; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f); + } + else + { + cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin(); + } + F32 current_range = cam_to_reference.normVec(); + + F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec(); + F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f); + // figure out nearest power of 2 that subdivides grid_scale with result > min_pixel_spacing + subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), min_subdivisions, max_subdivisions); + + return subdivisions; } void LLManip::handleSelect() { - mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); } void LLManip::handleDeselect() { - mHighlightedPart = LL_NO_PART; - mManipPart = LL_NO_PART; - mObjectSelection = NULL; + mHighlightedPart = LL_NO_PART; + mManipPart = LL_NO_PART; + mObjectSelection = NULL; } LLObjectSelectionHandle LLManip::getSelection() { - return mObjectSelection; + return mObjectSelection; } BOOL LLManip::handleHover(S32 x, S32 y, MASK mask) { - // We only handle the event if mousedown started with us - if( hasMouseCapture() ) - { - if( mObjectSelection->isEmpty() ) - { - // Somehow the object got deselected while we were dragging it. - // Release the mouse - setMouseCapture( FALSE ); - } - - LL_DEBUGS("UserInput") << "hover handled by LLManip (active)" << LL_ENDL; - } - else - { - LL_DEBUGS("UserInput") << "hover handled by LLManip (inactive)" << LL_ENDL; - } - gViewerWindow->setCursor(UI_CURSOR_ARROW); - return TRUE; + // We only handle the event if mousedown started with us + if( hasMouseCapture() ) + { + if( mObjectSelection->isEmpty() ) + { + // Somehow the object got deselected while we were dragging it. + // Release the mouse + setMouseCapture( FALSE ); + } + + LL_DEBUGS("UserInput") << "hover handled by LLManip (active)" << LL_ENDL; + } + else + { + LL_DEBUGS("UserInput") << "hover handled by LLManip (inactive)" << LL_ENDL; + } + gViewerWindow->setCursor(UI_CURSOR_ARROW); + return TRUE; } BOOL LLManip::handleMouseUp(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; - if( hasMouseCapture() ) - { - handled = TRUE; - setMouseCapture( FALSE ); - } - return handled; + BOOL handled = FALSE; + if( hasMouseCapture() ) + { + handled = TRUE; + setMouseCapture( FALSE ); + } + return handled; } void LLManip::updateGridSettings() { - sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f; + sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f; } BOOL LLManip::getMousePointOnPlaneAgent(LLVector3& point, S32 x, S32 y, LLVector3 origin, LLVector3 normal) { - LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin); - LLVector3d global_point; - BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal); - point = gAgent.getPosAgentFromGlobal(global_point); - return result; + LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin); + LLVector3d global_point; + BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal); + point = gAgent.getPosAgentFromGlobal(global_point); + return result; } BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVector3d origin, LLVector3 normal) const { - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - BOOL result = FALSE; - F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; - F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom; - - LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin); - LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y); - if (llabs(normal.mV[VX]) < 0.001f) - { - // use largish value that should be outside HUD manipulation range - mouse_pos.mV[VX] = 10.f; - } - else - { - mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos)) - / (normal.mV[VX]); - result = TRUE; - } - - point = gAgent.getPosGlobalFromAgent(mouse_pos); - return result; - } - else - { - return gViewerWindow->mousePointOnPlaneGlobal( - point, x, y, origin, normal ); - } - - //return FALSE; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + BOOL result = FALSE; + F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom; + + LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin); + LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y); + if (llabs(normal.mV[VX]) < 0.001f) + { + // use largish value that should be outside HUD manipulation range + mouse_pos.mV[VX] = 10.f; + } + else + { + mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos)) + / (normal.mV[VX]); + result = TRUE; + } + + point = gAgent.getPosGlobalFromAgent(mouse_pos); + return result; + } + else + { + return gViewerWindow->mousePointOnPlaneGlobal( + point, x, y, origin, normal ); + } + + //return FALSE; } // Given the line defined by mouse cursor (a1 + a_param*(a2-a1)) and the line defined by b1 + b_param*(b2-b1), @@ -302,159 +302,159 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect // Returns false if the two lines are parallel. BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, const LLVector3& b2, F32 &a_param, F32 &b_param ) { - LLVector3 a1; - LLVector3 a2; - - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; - F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom; - a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y); - a2 = a1 + LLVector3(1.f, 0.f, 0.f); - } - else - { - a1 = gAgentCamera.getCameraPositionAgent(); - a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y)); - } - - BOOL parallel = TRUE; - LLVector3 a = a2 - a1; - LLVector3 b = b2 - b1; - - LLVector3 normal; - F32 dist, denom; - normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b) - normal.normVec(); - dist = b1 * normal; // distance from origin to P - - denom = normal * a; - if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) - { - a_param = (dist - normal * a1) / denom; - parallel = FALSE; - } - - normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b) - normal.normVec(); - dist = a1 * normal; // distance from origin to P - denom = normal * b; - if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) - { - b_param = (dist - normal * b1) / denom; - parallel = FALSE; - } - - return parallel; + LLVector3 a1; + LLVector3 a2; + + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom; + a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y); + a2 = a1 + LLVector3(1.f, 0.f, 0.f); + } + else + { + a1 = gAgentCamera.getCameraPositionAgent(); + a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y)); + } + + BOOL parallel = TRUE; + LLVector3 a = a2 - a1; + LLVector3 b = b2 - b1; + + LLVector3 normal; + F32 dist, denom; + normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b) + normal.normVec(); + dist = b1 * normal; // distance from origin to P + + denom = normal * a; + if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) + { + a_param = (dist - normal * a1) / denom; + parallel = FALSE; + } + + normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b) + normal.normVec(); + dist = a1 * normal; // distance from origin to P + denom = normal * b; + if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) + { + b_param = (dist - normal * b1) / denom; + parallel = FALSE; + } + + return parallel; } LLVector3 LLManip::getSavedPivotPoint() const { - return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); + return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); } LLVector3 LLManip::getPivotPoint() { LLViewerObject* object = mObjectSelection->getFirstObject(); - if (object && mObjectSelection->getObjectCount() == 1 && mObjectSelection->getSelectType() != SELECT_TYPE_HUD) - { + if (object && mObjectSelection->getObjectCount() == 1 && mObjectSelection->getSelectType() != SELECT_TYPE_HUD) + { LLSelectNode* select_node = mObjectSelection->getFirstNode(); if (select_node->mSelectedGLTFNode != -1) { return object->getGLTFNodePositionAgent(select_node->mSelectedGLTFNode); } - return mObjectSelection->getFirstObject()->getPivotPositionAgent(); - } - return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); + return mObjectSelection->getFirstObject()->getPivotPositionAgent(); + } + return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); } void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) { - LLVector3 grid_origin; - LLQuaternion grid_rot; - LLVector3 grid_scale; - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale); - - const BOOL children_ok = TRUE; - LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok); - if (!object) - { - return; - } - - //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); - LLVector3 center_agent = getPivotPoint(); - - gGL.pushMatrix(); - { - gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]); - - F32 angle_radians, x, y, z; - - grid_rot.getAngleAxis(&angle_radians, &x, &y, &z); - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters(); - - const F32 LINE_ALPHA = 0.33f; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLUI::setLineWidth(1.5f); - - if (draw_x) - { - gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA); - gGL.begin(LLRender::LINES); - gGL.vertex3f( -region_size, 0.f, 0.f ); - gGL.vertex3f( region_size, 0.f, 0.f ); - gGL.end(); - } - - if (draw_y) - { - gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA); - gGL.begin(LLRender::LINES); - gGL.vertex3f( 0.f, -region_size, 0.f ); - gGL.vertex3f( 0.f, region_size, 0.f ); - gGL.end(); - } - - if (draw_z) - { - gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA); - gGL.begin(LLRender::LINES); - gGL.vertex3f( 0.f, 0.f, -region_size ); - gGL.vertex3f( 0.f, 0.f, region_size ); - gGL.end(); - } - LLUI::setLineWidth(1.0f); - } - gGL.popMatrix(); + LLVector3 grid_origin; + LLQuaternion grid_rot; + LLVector3 grid_scale; + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale); + + const BOOL children_ok = TRUE; + LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok); + if (!object) + { + return; + } + + //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); + LLVector3 center_agent = getPivotPoint(); + + gGL.pushMatrix(); + { + gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]); + + F32 angle_radians, x, y, z; + + grid_rot.getAngleAxis(&angle_radians, &x, &y, &z); + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); + + F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters(); + + const F32 LINE_ALPHA = 0.33f; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLUI::setLineWidth(1.5f); + + if (draw_x) + { + gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA); + gGL.begin(LLRender::LINES); + gGL.vertex3f( -region_size, 0.f, 0.f ); + gGL.vertex3f( region_size, 0.f, 0.f ); + gGL.end(); + } + + if (draw_y) + { + gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA); + gGL.begin(LLRender::LINES); + gGL.vertex3f( 0.f, -region_size, 0.f ); + gGL.vertex3f( 0.f, region_size, 0.f ); + gGL.end(); + } + + if (draw_z) + { + gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA); + gGL.begin(LLRender::LINES); + gGL.vertex3f( 0.f, 0.f, -region_size ); + gGL.vertex3f( 0.f, 0.f, region_size ); + gGL.end(); + } + LLUI::setLineWidth(1.0f); + } + gGL.popMatrix(); } -void LLManip::renderXYZ(const LLVector3 &vec) +void LLManip::renderXYZ(const LLVector3 &vec) { - const S32 PAD = 10; - std::string feedback_string; - S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; - S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2; - S32 vertical_offset = window_center_y - VERTICAL_OFFSET; - - - gGL.pushMatrix(); - { - LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); - gViewerWindow->setup2DRender(); - const LLVector2& display_scale = gViewerWindow->getDisplayScale(); - gGL.color4f(0.f, 0.f, 0.f, 0.7f); - - imagep->draw( - (window_center_x - 115) * display_scale.mV[VX], - (window_center_y + vertical_offset - PAD) * display_scale.mV[VY], - 235 * display_scale.mV[VX], - (PAD * 2 + 10) * display_scale.mV[VY], - LLColor4(0.f, 0.f, 0.f, 0.7f) ); + const S32 PAD = 10; + std::string feedback_string; + S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; + S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2; + S32 vertical_offset = window_center_y - VERTICAL_OFFSET; + + + gGL.pushMatrix(); + { + LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); + gViewerWindow->setup2DRender(); + const LLVector2& display_scale = gViewerWindow->getDisplayScale(); + gGL.color4f(0.f, 0.f, 0.f, 0.7f); + + imagep->draw( + (window_center_x - 115) * display_scale.mV[VX], + (window_center_y + vertical_offset - PAD) * display_scale.mV[VY], + 235 * display_scale.mV[VX], + (PAD * 2 + 10) * display_scale.mV[VY], + LLColor4(0.f, 0.f, 0.f, 0.7f) ); LLFontGL* font = LLFontGL::getFontSansSerif(); LLLocale locale(LLLocale::USER_LOCALE); @@ -500,129 +500,129 @@ void LLManip::renderXYZ(const LLVector3 &vec) void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color) { - const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); - - BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - LLVector3 render_pos = pos; - if (hud_selection) - { - F32 zoom_amt = gAgentCamera.mHUDCurZoom; - F32 inv_zoom_amt = 1.f / zoom_amt; - // scale text back up to counter-act zoom level - render_pos = pos * zoom_amt; - gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); - } - - // render shadow first - LLColor4 shadow_color = LLColor4::black; - shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; - gViewerWindow->setup3DViewport(1, -1); - hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); - gViewerWindow->setup3DViewport(); - hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); - - gGL.popMatrix(); + const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); + + BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + LLVector3 render_pos = pos; + if (hud_selection) + { + F32 zoom_amt = gAgentCamera.mHUDCurZoom; + F32 inv_zoom_amt = 1.f / zoom_amt; + // scale text back up to counter-act zoom level + render_pos = pos * zoom_amt; + gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); + } + + // render shadow first + LLColor4 shadow_color = LLColor4::black; + shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; + gViewerWindow->setup3DViewport(1, -1); + hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); + gViewerWindow->setup3DViewport(); + hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); + + gGL.popMatrix(); } void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string& suffix, const LLColor4 &color) { - LLLocale locale(LLLocale::USER_LOCALE); - - const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); - const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall(); - - std::string val_string; - std::string fraction_string; - F32 val_to_print = ll_round(value, 0.001f); - S32 fractional_portion = ll_round(fmodf(llabs(val_to_print), 1.f) * 100.f); - if (val_to_print < 0.f) - { - if (fractional_portion == 0) - { - val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str()); - } - else - { - val_string = llformat("-%d", lltrunc(llabs(val_to_print))); - } - } - else - { - if (fractional_portion == 0) - { - val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str()); - } - else - { - val_string = llformat("%d", lltrunc(val_to_print)); - } - } - - BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - { - LLVector3 render_pos = pos; - if (hud_selection) - { - F32 zoom_amt = gAgentCamera.mHUDCurZoom; - F32 inv_zoom_amt = 1.f / zoom_amt; - // scale text back up to counter-act zoom level - render_pos = pos * zoom_amt; - gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); - } - - LLColor4 shadow_color = LLColor4::black; - shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; - - if (fractional_portion != 0) - { - fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str()); - - hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); - hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection); - } - else - { - hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); - } - } - gGL.popMatrix(); + LLLocale locale(LLLocale::USER_LOCALE); + + const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); + const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall(); + + std::string val_string; + std::string fraction_string; + F32 val_to_print = ll_round(value, 0.001f); + S32 fractional_portion = ll_round(fmodf(llabs(val_to_print), 1.f) * 100.f); + if (val_to_print < 0.f) + { + if (fractional_portion == 0) + { + val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str()); + } + else + { + val_string = llformat("-%d", lltrunc(llabs(val_to_print))); + } + } + else + { + if (fractional_portion == 0) + { + val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str()); + } + else + { + val_string = llformat("%d", lltrunc(val_to_print)); + } + } + + BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + { + LLVector3 render_pos = pos; + if (hud_selection) + { + F32 zoom_amt = gAgentCamera.mHUDCurZoom; + F32 inv_zoom_amt = 1.f / zoom_amt; + // scale text back up to counter-act zoom level + render_pos = pos * zoom_amt; + gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); + } + + LLColor4 shadow_color = LLColor4::black; + shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; + + if (fractional_portion != 0) + { + fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str()); + + hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); + hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection); + } + else + { + hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); + } + } + gGL.popMatrix(); } LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass) { - static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor"); - static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor"); - static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor"); - - LLColor4 line_color; - F32 line_alpha = gSavedSettings.getF32("GridOpacity"); - - switch(pass) - { - case 0: - // shadow - gViewerWindow->setup3DViewport(1, -1); - line_color = grid_color_shadow; - line_color.mV[VALPHA] *= line_alpha; - LLUI::setLineWidth(2.f); - break; - case 1: - // hidden lines - gViewerWindow->setup3DViewport(); - line_color = grid_color_bg; - line_color.mV[VALPHA] *= line_alpha; - LLUI::setLineWidth(1.f); - break; - case 2: - // visible lines - line_color = grid_color_fg; - line_color.mV[VALPHA] *= line_alpha; - break; - } - - return line_color; + static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor"); + static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor"); + static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor"); + + LLColor4 line_color; + F32 line_alpha = gSavedSettings.getF32("GridOpacity"); + + switch(pass) + { + case 0: + // shadow + gViewerWindow->setup3DViewport(1, -1); + line_color = grid_color_shadow; + line_color.mV[VALPHA] *= line_alpha; + LLUI::setLineWidth(2.f); + break; + case 1: + // hidden lines + gViewerWindow->setup3DViewport(); + line_color = grid_color_bg; + line_color.mV[VALPHA] *= line_alpha; + LLUI::setLineWidth(1.f); + break; + case 2: + // visible lines + line_color = grid_color_fg; + line_color.mV[VALPHA] *= line_alpha; + break; + } + + return line_color; } diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 1ac1992fe0..54aa22be2b 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmaniprotate.cpp * @brief LLManipRotate class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -63,7 +63,7 @@ #include "llvoavatarself.h" #include "llhudrender.h" -const F32 RADIUS_PIXELS = 100.f; // size in screen space +const F32 RADIUS_PIXELS = 100.f; // size in screen space const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS; const F32 WIDTH_PIXELS = 8; const S32 CIRCLE_STEPS = 100; @@ -83,493 +83,493 @@ const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f; extern void handle_reset_rotation(void*); // in LLViewerWindow LLManipRotate::LLManipRotate( LLToolComposite* composite ) -: LLManip( std::string("Rotate"), composite ), - mRotationCenter(), - mCenterScreen(), - mRotation(), - mMouseDown(), - mMouseCur(), - mRadiusMeters(0.f), - mCenterToCam(), - mCenterToCamNorm(), - mCenterToCamMag(0.f), - mCenterToProfilePlane(), - mCenterToProfilePlaneMag(0.f), - mSendUpdateOnMouseUp( FALSE ), - mSmoothRotate( FALSE ), - mCamEdgeOn(FALSE), - mManipulatorScales(1.f, 1.f, 1.f, 1.f) +: LLManip( std::string("Rotate"), composite ), + mRotationCenter(), + mCenterScreen(), + mRotation(), + mMouseDown(), + mMouseCur(), + mRadiusMeters(0.f), + mCenterToCam(), + mCenterToCamNorm(), + mCenterToCamMag(0.f), + mCenterToProfilePlane(), + mCenterToProfilePlaneMag(0.f), + mSendUpdateOnMouseUp( FALSE ), + mSmoothRotate( FALSE ), + mCamEdgeOn(FALSE), + mManipulatorScales(1.f, 1.f, 1.f, 1.f) { } void LLManipRotate::handleSelect() { - // *FIX: put this in mouseDown? - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + // *FIX: put this in mouseDown? + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); if (gFloaterTools) { gFloaterTools->setStatusText("rotate"); } - LLManip::handleSelect(); + LLManip::handleSelect(); } void LLManipRotate::render() { - LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - LLGLDepthTest gls_depth(GL_TRUE); - LLGLEnable gl_blend(GL_BLEND); - - // You can rotate if you can move - LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE); - if( !first_object ) - { - return; - } - - if( !updateVisiblity() ) - { - return; - } - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - F32 zoom = gAgentCamera.mHUDCurZoom; - gGL.scalef(zoom, zoom, zoom); - } - - - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - - LLColor4 highlight_outside( 1.f, 1.f, 0.f, 1.f ); - LLColor4 highlight_inside( 0.7f, 0.7f, 0.f, 0.5f ); - F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS; - - gGL.pushMatrix(); - { - - // are we in the middle of a constrained drag? - if (mManipPart >= LL_ROT_X && mManipPart <= LL_ROT_Z) - { - renderSnapGuides(); - } - else - { - gDebugProgram.bind(); - - LLGLEnable cull_face(GL_CULL_FACE); - LLGLDepthTest gls_depth(GL_FALSE); - gGL.pushMatrix(); - { - // Draw "sphere" (intersection of sphere with tangent cone that has apex at camera) - gGL.translatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] ); - gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] ); - - // Inverse change of basis vectors - LLVector3 forward = mCenterToCamNorm; - LLVector3 left = gAgent.getUpAxis() % forward; - left.normVec(); - LLVector3 up = forward % left; - - LLVector4 a(-forward); - a.mV[3] = 0; - LLVector4 b(up); - b.mV[3] = 0; - LLVector4 c(left); - c.mV[3] = 0; - LLMatrix4 mat; - mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f)); - - gGL.multMatrix( &mat.mMatrix[0][0] ); - - gGL.rotatef( -90, 0.f, 1.f, 0.f); - LLColor4 color; - if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL) - { - color.setVec(0.8f, 0.8f, 0.8f, 0.8f); - gGL.scalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]); - } - else - { - color.setVec( 0.7f, 0.7f, 0.7f, 0.6f ); - } - gGL.diffuseColor4fv(color.mV); - gl_washer_2d(mRadiusMeters + width_meters, mRadiusMeters, CIRCLE_STEPS, color, color); - - - if (mManipPart == LL_NO_PART) - { - gGL.color4f( 0.7f, 0.7f, 0.7f, 0.3f ); - gGL.diffuseColor4f(0.7f, 0.7f, 0.7f, 0.3f); - gl_circle_2d( 0, 0, mRadiusMeters, CIRCLE_STEPS, TRUE ); - } - - gGL.flush(); - } - gGL.popMatrix(); - - gUIProgram.bind(); - } - - gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] ); - - LLQuaternion rot; - F32 angle_radians, x, y, z; - - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - - gDebugProgram.bind(); - - if (mManipPart == LL_ROT_Z) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.pushMatrix(); - { - // selected part - gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]); - renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f) , LLColor4( 0.f, 0.f, 1.f, 0.3f )); - } - gGL.popMatrix(); - } - else if (mManipPart == LL_ROT_Y) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.pushMatrix(); - { - gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); - gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); - renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f)); - } - gGL.popMatrix(); - } - else if (mManipPart == LL_ROT_X) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.pushMatrix(); - { - gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); - gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); - renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f)); - } - gGL.popMatrix(); - } - else if (mManipPart == LL_ROT_ROLL) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - } - else if (mManipPart == LL_NO_PART) - { - if (mHighlightedPart == LL_NO_PART) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - } - - LLGLEnable cull_face(GL_CULL_FACE); - LLGLEnable clip_plane0(GL_CLIP_PLANE0); - LLGLDepthTest gls_depth(GL_FALSE); - //LLGLDisable gls_stencil(GL_STENCIL_TEST); - - // First pass: centers. Second pass: sides. - for( S32 i=0; i<2; i++ ) - { - - gGL.pushMatrix(); - { - if (mHighlightedPart == LL_ROT_Z) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]); - // hovering over part - gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i); - } - else - { - // default - gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 0.8f, 0.8f ), LLColor4( 0.f, 0.f, 0.8f, 0.4f ), CIRCLE_STEPS, i); - } - } - gGL.popMatrix(); - - gGL.pushMatrix(); - { - gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); - if (mHighlightedPart == LL_ROT_Y) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); - // hovering over part - gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i); - } - else - { - // default - gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.8f, 0.f, 0.8f ), LLColor4( 0.f, 0.8f, 0.f, 0.4f ), CIRCLE_STEPS, i); - } - } - gGL.popMatrix(); - - gGL.pushMatrix(); - { - gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); - if (mHighlightedPart == LL_ROT_X) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); - - // hovering over part - gl_ring( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f ), LLColor4( 1.f, 0.f, 0.f, 0.5f ), CIRCLE_STEPS, i); - } - else - { - // default - gl_ring( mRadiusMeters, width_meters, LLColor4( 0.8f, 0.f, 0.f, 0.8f ), LLColor4( 0.8f, 0.f, 0.f, 0.4f ), CIRCLE_STEPS, i); - } - } - gGL.popMatrix(); - - if (mHighlightedPart == LL_ROT_ROLL) - { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); - } - - } - - } - - gUIProgram.bind(); - } - gGL.popMatrix(); - gGL.popMatrix(); - - - LLVector3 euler_angles; - LLQuaternion object_rot = first_object->getRotationEdit(); - object_rot.getEulerAngles(&(euler_angles.mV[VX]), &(euler_angles.mV[VY]), &(euler_angles.mV[VZ])); - euler_angles *= RAD_TO_DEG; - euler_angles.mV[VX] = ll_round(fmodf(euler_angles.mV[VX] + 360.f, 360.f), 0.05f); - euler_angles.mV[VY] = ll_round(fmodf(euler_angles.mV[VY] + 360.f, 360.f), 0.05f); - euler_angles.mV[VZ] = ll_round(fmodf(euler_angles.mV[VZ] + 360.f, 360.f), 0.05f); - - renderXYZ(euler_angles); + LLGLSUIDefault gls_ui; + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + LLGLDepthTest gls_depth(GL_TRUE); + LLGLEnable gl_blend(GL_BLEND); + + // You can rotate if you can move + LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE); + if( !first_object ) + { + return; + } + + if( !updateVisiblity() ) + { + return; + } + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + F32 zoom = gAgentCamera.mHUDCurZoom; + gGL.scalef(zoom, zoom, zoom); + } + + + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + + LLColor4 highlight_outside( 1.f, 1.f, 0.f, 1.f ); + LLColor4 highlight_inside( 0.7f, 0.7f, 0.f, 0.5f ); + F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS; + + gGL.pushMatrix(); + { + + // are we in the middle of a constrained drag? + if (mManipPart >= LL_ROT_X && mManipPart <= LL_ROT_Z) + { + renderSnapGuides(); + } + else + { + gDebugProgram.bind(); + + LLGLEnable cull_face(GL_CULL_FACE); + LLGLDepthTest gls_depth(GL_FALSE); + gGL.pushMatrix(); + { + // Draw "sphere" (intersection of sphere with tangent cone that has apex at camera) + gGL.translatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] ); + gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] ); + + // Inverse change of basis vectors + LLVector3 forward = mCenterToCamNorm; + LLVector3 left = gAgent.getUpAxis() % forward; + left.normVec(); + LLVector3 up = forward % left; + + LLVector4 a(-forward); + a.mV[3] = 0; + LLVector4 b(up); + b.mV[3] = 0; + LLVector4 c(left); + c.mV[3] = 0; + LLMatrix4 mat; + mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f)); + + gGL.multMatrix( &mat.mMatrix[0][0] ); + + gGL.rotatef( -90, 0.f, 1.f, 0.f); + LLColor4 color; + if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL) + { + color.setVec(0.8f, 0.8f, 0.8f, 0.8f); + gGL.scalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]); + } + else + { + color.setVec( 0.7f, 0.7f, 0.7f, 0.6f ); + } + gGL.diffuseColor4fv(color.mV); + gl_washer_2d(mRadiusMeters + width_meters, mRadiusMeters, CIRCLE_STEPS, color, color); + + + if (mManipPart == LL_NO_PART) + { + gGL.color4f( 0.7f, 0.7f, 0.7f, 0.3f ); + gGL.diffuseColor4f(0.7f, 0.7f, 0.7f, 0.3f); + gl_circle_2d( 0, 0, mRadiusMeters, CIRCLE_STEPS, TRUE ); + } + + gGL.flush(); + } + gGL.popMatrix(); + + gUIProgram.bind(); + } + + gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] ); + + LLQuaternion rot; + F32 angle_radians, x, y, z; + + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); + + + gDebugProgram.bind(); + + if (mManipPart == LL_ROT_Z) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.pushMatrix(); + { + // selected part + gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]); + renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f) , LLColor4( 0.f, 0.f, 1.f, 0.3f )); + } + gGL.popMatrix(); + } + else if (mManipPart == LL_ROT_Y) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.pushMatrix(); + { + gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); + gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); + renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f)); + } + gGL.popMatrix(); + } + else if (mManipPart == LL_ROT_X) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.pushMatrix(); + { + gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); + gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); + renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f)); + } + gGL.popMatrix(); + } + else if (mManipPart == LL_ROT_ROLL) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + } + else if (mManipPart == LL_NO_PART) + { + if (mHighlightedPart == LL_NO_PART) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + } + + LLGLEnable cull_face(GL_CULL_FACE); + LLGLEnable clip_plane0(GL_CLIP_PLANE0); + LLGLDepthTest gls_depth(GL_FALSE); + //LLGLDisable gls_stencil(GL_STENCIL_TEST); + + // First pass: centers. Second pass: sides. + for( S32 i=0; i<2; i++ ) + { + + gGL.pushMatrix(); + { + if (mHighlightedPart == LL_ROT_Z) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]); + // hovering over part + gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i); + } + else + { + // default + gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 0.8f, 0.8f ), LLColor4( 0.f, 0.f, 0.8f, 0.4f ), CIRCLE_STEPS, i); + } + } + gGL.popMatrix(); + + gGL.pushMatrix(); + { + gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); + if (mHighlightedPart == LL_ROT_Y) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); + // hovering over part + gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i); + } + else + { + // default + gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.8f, 0.f, 0.8f ), LLColor4( 0.f, 0.8f, 0.f, 0.4f ), CIRCLE_STEPS, i); + } + } + gGL.popMatrix(); + + gGL.pushMatrix(); + { + gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); + if (mHighlightedPart == LL_ROT_X) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); + + // hovering over part + gl_ring( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f ), LLColor4( 1.f, 0.f, 0.f, 0.5f ), CIRCLE_STEPS, i); + } + else + { + // default + gl_ring( mRadiusMeters, width_meters, LLColor4( 0.8f, 0.f, 0.f, 0.8f ), LLColor4( 0.8f, 0.f, 0.f, 0.4f ), CIRCLE_STEPS, i); + } + } + gGL.popMatrix(); + + if (mHighlightedPart == LL_ROT_ROLL) + { + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + } + + } + + } + + gUIProgram.bind(); + } + gGL.popMatrix(); + gGL.popMatrix(); + + + LLVector3 euler_angles; + LLQuaternion object_rot = first_object->getRotationEdit(); + object_rot.getEulerAngles(&(euler_angles.mV[VX]), &(euler_angles.mV[VY]), &(euler_angles.mV[VZ])); + euler_angles *= RAD_TO_DEG; + euler_angles.mV[VX] = ll_round(fmodf(euler_angles.mV[VX] + 360.f, 360.f), 0.05f); + euler_angles.mV[VY] = ll_round(fmodf(euler_angles.mV[VY] + 360.f, 360.f), 0.05f); + euler_angles.mV[VZ] = ll_round(fmodf(euler_angles.mV[VZ] + 360.f, 360.f), 0.05f); + + renderXYZ(euler_angles); } BOOL LLManipRotate::handleMouseDown(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; - - LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE); - if( first_object ) - { - if( mHighlightedPart != LL_NO_PART ) - { - handled = handleMouseDownOnPart( x, y, mask ); - } - } - - return handled; + BOOL handled = FALSE; + + LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE); + if( first_object ) + { + if( mHighlightedPart != LL_NO_PART ) + { + handled = handleMouseDownOnPart( x, y, mask ); + } + } + + return handled; } // Assumes that one of the parts of the manipulator was hit. BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) { - BOOL can_rotate = canAffectSelection(); - if (!can_rotate) - { - return FALSE; - } - - highlightManipulators(x, y); - S32 hit_part = mHighlightedPart; - // we just started a drag, so save initial object positions - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE); - - // save selection center - mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstance()->getSelectionCenterGlobal(); - - mManipPart = (EManipPart)hit_part; - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - - if( mManipPart == LL_ROT_GENERAL) - { - mMouseDown = intersectMouseWithSphere( x, y, center, mRadiusMeters); - } - else - { - // Project onto the plane of the ring - LLVector3 axis = getConstraintAxis(); - - F32 axis_onto_cam = llabs( axis * mCenterToCamNorm ); - const F32 AXIS_ONTO_CAM_TOL = cos( 85.f * DEG_TO_RAD ); - if( axis_onto_cam < AXIS_ONTO_CAM_TOL ) - { - LLVector3 up_from_axis = mCenterToCamNorm % axis; - up_from_axis.normVec(); - LLVector3 cur_intersection; - getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam); - cur_intersection -= center; - mMouseDown = projected_vec(cur_intersection, up_from_axis); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - F32 mouse_dist_sqrd = mMouseDown.magVecSquared(); - if (mouse_dist_sqrd > 0.0001f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - mouse_dist_sqrd); - } - LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, axis); - mMouseDown += mouse_depth * projected_center_to_cam; - - } - else - { - mMouseDown = findNearestPointOnRing( x, y, center, axis ) - center; - mMouseDown.normVec(); - } - } - - mMouseCur = mMouseDown; - mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value - - // Route future Mouse messages here preemptively. (Release on mouse up.) - setMouseCapture( TRUE ); - LLSelectMgr::getInstance()->enableSilhouette(FALSE); - - mHelpTextTimer.reset(); - sNumTimesHelpTextShown++; - return TRUE; + BOOL can_rotate = canAffectSelection(); + if (!can_rotate) + { + return FALSE; + } + + highlightManipulators(x, y); + S32 hit_part = mHighlightedPart; + // we just started a drag, so save initial object positions + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE); + + // save selection center + mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstance()->getSelectionCenterGlobal(); + + mManipPart = (EManipPart)hit_part; + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + + if( mManipPart == LL_ROT_GENERAL) + { + mMouseDown = intersectMouseWithSphere( x, y, center, mRadiusMeters); + } + else + { + // Project onto the plane of the ring + LLVector3 axis = getConstraintAxis(); + + F32 axis_onto_cam = llabs( axis * mCenterToCamNorm ); + const F32 AXIS_ONTO_CAM_TOL = cos( 85.f * DEG_TO_RAD ); + if( axis_onto_cam < AXIS_ONTO_CAM_TOL ) + { + LLVector3 up_from_axis = mCenterToCamNorm % axis; + up_from_axis.normVec(); + LLVector3 cur_intersection; + getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam); + cur_intersection -= center; + mMouseDown = projected_vec(cur_intersection, up_from_axis); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + F32 mouse_dist_sqrd = mMouseDown.magVecSquared(); + if (mouse_dist_sqrd > 0.0001f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + mouse_dist_sqrd); + } + LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, axis); + mMouseDown += mouse_depth * projected_center_to_cam; + + } + else + { + mMouseDown = findNearestPointOnRing( x, y, center, axis ) - center; + mMouseDown.normVec(); + } + } + + mMouseCur = mMouseDown; + mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value + + // Route future Mouse messages here preemptively. (Release on mouse up.) + setMouseCapture( TRUE ); + LLSelectMgr::getInstance()->enableSilhouette(FALSE); + + mHelpTextTimer.reset(); + sNumTimesHelpTextShown++; + return TRUE; } LLVector3 LLManipRotate::findNearestPointOnRing( S32 x, S32 y, const LLVector3& center, const LLVector3& axis ) { - // Project the delta onto the ring and rescale it by the radius so that it's _on_ the ring. - LLVector3 proj_onto_ring; - getMousePointOnPlaneAgent(proj_onto_ring, x, y, center, axis); - proj_onto_ring -= center; - proj_onto_ring.normVec(); + // Project the delta onto the ring and rescale it by the radius so that it's _on_ the ring. + LLVector3 proj_onto_ring; + getMousePointOnPlaneAgent(proj_onto_ring, x, y, center, axis); + proj_onto_ring -= center; + proj_onto_ring.normVec(); - return center + proj_onto_ring * mRadiusMeters; + return center + proj_onto_ring * mRadiusMeters; } BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask) { - // first, perform normal processing in case this was a quick-click - handleHover(x, y, mask); - - if( hasMouseCapture() ) - { - for (LLObjectSelection::iterator iter = mObjectSelection->begin(); - iter != mObjectSelection->end(); iter++) - { - LLSelectNode* selectNode = *iter; - LLViewerObject* object = selectNode->getObject(); - LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); - - // have permission to move and object is root of selection or individually selected - if (object->permMove() && !object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (object->isRootEdit() || selectNode->mIndividualSelection)) - { - object->mUnselectedChildrenPositions.clear() ; - } - } - - mManipPart = LL_NO_PART; - - // Might have missed last update due to timing. - LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION ); - LLSelectMgr::getInstance()->enableSilhouette(TRUE); - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); - - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - } - - return LLManip::handleMouseUp(x, y, mask); + // first, perform normal processing in case this was a quick-click + handleHover(x, y, mask); + + if( hasMouseCapture() ) + { + for (LLObjectSelection::iterator iter = mObjectSelection->begin(); + iter != mObjectSelection->end(); iter++) + { + LLSelectNode* selectNode = *iter; + LLViewerObject* object = selectNode->getObject(); + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); + + // have permission to move and object is root of selection or individually selected + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->isRootEdit() || selectNode->mIndividualSelection)) + { + object->mUnselectedChildrenPositions.clear() ; + } + } + + mManipPart = LL_NO_PART; + + // Might have missed last update due to timing. + LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION ); + LLSelectMgr::getInstance()->enableSilhouette(TRUE); + //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); + + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + } + + return LLManip::handleMouseUp(x, y, mask); } BOOL LLManipRotate::handleHover(S32 x, S32 y, MASK mask) { - if( hasMouseCapture() ) - { - if( mObjectSelection->isEmpty() ) - { - // Somehow the object got deselected while we were dragging it. - setMouseCapture( FALSE ); - } - else - { - drag(x, y); - } - - LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (active)" << LL_ENDL; - } - else - { - highlightManipulators(x, y); - LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (inactive)" << LL_ENDL; - } - - gViewerWindow->setCursor(UI_CURSOR_TOOLROTATE); - return TRUE; + if( hasMouseCapture() ) + { + if( mObjectSelection->isEmpty() ) + { + // Somehow the object got deselected while we were dragging it. + setMouseCapture( FALSE ); + } + else + { + drag(x, y); + } + + LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (active)" << LL_ENDL; + } + else + { + highlightManipulators(x, y); + LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (inactive)" << LL_ENDL; + } + + gViewerWindow->setCursor(UI_CURSOR_TOOLROTATE); + return TRUE; } -LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere ) +LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere ) { - F32 z = 0.f; - F32 dist_squared = x*x + y*y; + F32 z = 0.f; + F32 dist_squared = x*x + y*y; - *on_sphere = dist_squared <= SQ_RADIUS; + *on_sphere = dist_squared <= SQ_RADIUS; if( *on_sphere ) - { + { z = sqrt(SQ_RADIUS - dist_squared); } - return LLVector3( x, y, z ); + return LLVector3( x, y, z ); } // Freeform rotation void LLManipRotate::drag( S32 x, S32 y ) { - if( !updateVisiblity() ) - { - return; - } - - if( mManipPart == LL_ROT_GENERAL ) - { - mRotation = dragUnconstrained(x, y); - } - else - { - mRotation = dragConstrained(x, y); - } - - BOOL damped = mSmoothRotate; - mSmoothRotate = FALSE; - bool gltf_mode = false; + if( !updateVisiblity() ) + { + return; + } + + if( mManipPart == LL_ROT_GENERAL ) + { + mRotation = dragUnconstrained(x, y); + } + else + { + mRotation = dragConstrained(x, y); + } - for (LLObjectSelection::iterator iter = mObjectSelection->begin(); - iter != mObjectSelection->end(); iter++) - { - LLSelectNode* selectNode = *iter; - LLViewerObject* object = selectNode->getObject(); - LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); + BOOL damped = mSmoothRotate; + mSmoothRotate = FALSE; + bool gltf_mode = false; - // have permission to move and object is root of selection or individually selected - if (object->permMove() && !object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (object->isRootEdit() || selectNode->mIndividualSelection)) - { + for (LLObjectSelection::iterator iter = mObjectSelection->begin(); + iter != mObjectSelection->end(); iter++) + { + LLSelectNode* selectNode = *iter; + LLViewerObject* object = selectNode->getObject(); + LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit(); + + // have permission to move and object is root of selection or individually selected + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->isRootEdit() || selectNode->mIndividualSelection)) + { if (selectNode->mSelectedGLTFNode != -1) { @@ -643,10 +643,10 @@ void LLManipRotate::drag( S32 x, S32 y ) object->resetChildrenRotationAndPosition(child_rotations, child_positions); } } - } - } + } + } - // update positions + // update positions if (!gltf_mode) { for (LLObjectSelection::iterator iter = mObjectSelection->begin(); @@ -674,7 +674,7 @@ void LLManipRotate::drag( S32 x, S32 y ) { if (object->isAttachment() && object->mDrawable.notNull()) { - // need to work in drawable space to handle selected items from multiple attachments + // need to work in drawable space to handle selected items from multiple attachments // (which have no shared frame of reference other than their render positions) LLXform* parent_xform = object->mDrawable->getXform()->getParent(); new_position = (selectNode->mSavedPositionLocal * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition(); @@ -686,7 +686,7 @@ void LLManipRotate::drag( S32 x, S32 y ) old_position = object->getPositionAgent(); } - new_position = (new_position - center) * mRotation; // new relative rotated position + new_position = (new_position - center) * mRotation; // new relative rotated position new_position += center; if (object->isRootEdit() && !object->isAttachment()) @@ -742,1234 +742,1234 @@ void LLManipRotate::drag( S32 x, S32 y ) } } - // store changes to override updates - for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); - iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++) - { - LLSelectNode* selectNode = *iter; - LLViewerObject*cur = selectNode->getObject(); - LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); + // store changes to override updates + for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); + iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++) + { + LLSelectNode* selectNode = *iter; + LLViewerObject*cur = selectNode->getObject(); + LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar)) - { + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar)) + { selectNode->mLastRotation = cur->getRotation(); selectNode->mLastPositionLocal = cur->getPosition(); - } - } + } + } - LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); - // RN: just clear focus so camera doesn't follow spurious object updates - gAgentCamera.clearFocusObject(); - dialog_refresh_all(); + // RN: just clear focus so camera doesn't follow spurious object updates + gAgentCamera.clearFocusObject(); + dialog_refresh_all(); } void LLManipRotate::renderActiveRing( F32 radius, F32 width, const LLColor4& front_color, const LLColor4& back_color) { - LLGLEnable cull_face(GL_CULL_FACE); - { - gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, FALSE); - gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, TRUE); - } - { - LLGLDepthTest gls_depth(GL_FALSE); - gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, FALSE); - gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, TRUE); - } + LLGLEnable cull_face(GL_CULL_FACE); + { + gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, FALSE); + gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, TRUE); + } + { + LLGLDepthTest gls_depth(GL_FALSE); + gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, FALSE); + gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, TRUE); + } } void LLManipRotate::renderSnapGuides() { - static LLCachedControl snap_enabled(gSavedSettings, "SnapEnabled", true); - if (!snap_enabled) - { - return; - } - - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true); - - LLVector3 constraint_axis = getConstraintAxis(); - - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_at_axis.setVec(1.f, 0.f, 0.f); - } - else - { - cam_at_axis = center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - LLVector3 world_snap_axis; - LLVector3 test_axis = constraint_axis; - - BOOL constrain_to_ref_object = FALSE; - if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) - { - test_axis = test_axis * ~grid_rotation; - } - else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) - { - test_axis = test_axis * ~grid_rotation; - constrain_to_ref_object = TRUE; - } - - test_axis.abs(); - - // find closest global/reference axis to local constraint axis; - if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ]) - { - world_snap_axis = LLVector3::y_axis; - } - else if (test_axis.mV[VY] > test_axis.mV[VZ]) - { - world_snap_axis = LLVector3::z_axis; - } - else - { - world_snap_axis = LLVector3::x_axis; - } - - LLVector3 projected_snap_axis = world_snap_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) - { - projected_snap_axis = projected_snap_axis * grid_rotation; - } - else if (constrain_to_ref_object) - { - projected_snap_axis = projected_snap_axis * grid_rotation; - } - - // project world snap axis onto constraint plane - projected_snap_axis -= projected_vec(projected_snap_axis, constraint_axis); - projected_snap_axis.normVec(); - - S32 num_rings = mCamEdgeOn ? 2 : 1; - for (S32 ring_num = 0; ring_num < num_rings; ring_num++) - { - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - - if (mCamEdgeOn) - { - // draw two opposing rings - if (ring_num == 0) - { - center += constraint_axis * mRadiusMeters * 0.5f; - } - else - { - center -= constraint_axis * mRadiusMeters * 0.5f; - } - } - - LLGLDepthTest gls_depth(GL_FALSE); - for (S32 pass = 0; pass < 3; pass++) - { - // render snap guide ring - gGL.pushMatrix(); - - LLQuaternion snap_guide_rot; - F32 angle_radians, x, y, z; - snap_guide_rot.shortestArc(LLVector3::z_axis, getConstraintAxis()); - snap_guide_rot.getAngleAxis(&angle_radians, &x, &y, &z); - gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]); - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - LLColor4 line_color = setupSnapGuideRenderPass(pass); - - gGL.color4fv(line_color.mV); - - if (mCamEdgeOn) - { - // render an arc - LLVector3 edge_normal = cam_at_axis % constraint_axis; - edge_normal.normVec(); - LLVector3 x_axis_snap = LLVector3::x_axis * snap_guide_rot; - LLVector3 y_axis_snap = LLVector3::y_axis * snap_guide_rot; - - F32 end_angle = atan2(y_axis_snap * edge_normal, x_axis_snap * edge_normal); - //F32 start_angle = angle_between((-1.f * LLVector3::x_axis) * snap_guide_rot, edge_normal); - F32 start_angle = end_angle - F_PI; - gl_arc_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE, start_angle, end_angle); - } - else - { - gl_circle_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE); - } - gGL.popMatrix(); - - for (S32 i = 0; i < 64; i++) - { - BOOL render_text = TRUE; - F32 deg = 5.625f * (F32)i; - LLVector3 inner_point; - LLVector3 outer_point; - LLVector3 text_point; - LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis); - gGL.begin(LLRender::LINES); - { - inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center; - F32 tick_length = 0.f; - if (i % 16 == 0) - { - tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_1 - SNAP_GUIDE_INNER_RADIUS); - } - else if (i % 8 == 0) - { - tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_2 - SNAP_GUIDE_INNER_RADIUS); - } - else if (i % 4 == 0) - { - tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_3 - SNAP_GUIDE_INNER_RADIUS); - } - else if (i % 2 == 0) - { - tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_4 - SNAP_GUIDE_INNER_RADIUS); - } - else - { - tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_5 - SNAP_GUIDE_INNER_RADIUS); - } - - if (mCamEdgeOn) - { - // don't draw ticks that are on back side of circle - F32 dot = cam_at_axis * (projected_snap_axis * rot); - if (dot > 0.f) - { - outer_point = inner_point; - render_text = FALSE; - } - else - { - if (ring_num == 0) - { - outer_point = inner_point + (constraint_axis * tick_length) * rot; - } - else - { - outer_point = inner_point - (constraint_axis * tick_length) * rot; - } - } - } - else - { - outer_point = inner_point + (projected_snap_axis * tick_length) * rot; - } - - text_point = outer_point + (projected_snap_axis * mRadiusMeters * 0.1f) * rot; - - gGL.vertex3fv(inner_point.mV); - gGL.vertex3fv(outer_point.mV); - } - gGL.end(); - - //RN: text rendering does own shadow pass, so only render once - if (pass == 1 && render_text && i % 16 == 0) - { - if (world_snap_axis.mV[VX]) - { - if (i == 0) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); - } - else if (i == 16) - { - if (constraint_axis.mV[VZ] > 0.f) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); - } - else - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); - } - } - else if (i == 32) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); - } - else - { - if (constraint_axis.mV[VZ] > 0.f) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); - } - else - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); - } - } - } - else if (world_snap_axis.mV[VY]) - { - if (i == 0) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); - } - else if (i == 16) - { - if (constraint_axis.mV[VX] > 0.f) - { - renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); - } - else - { - renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); - } - } - else if (i == 32) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); - } - else - { - if (constraint_axis.mV[VX] > 0.f) - { - renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); - } - else - { - renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); - } - } - } - else if (world_snap_axis.mV[VZ]) - { - if (i == 0) - { - renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); - } - else if (i == 16) - { - if (constraint_axis.mV[VY] > 0.f) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); - } - else - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); - } - } - else if (i == 32) - { - renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); - } - else - { - if (constraint_axis.mV[VY] > 0.f) - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); - } - else - { - renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); - } - } - } - } - gGL.color4fv(line_color.mV); - } - - // now render projected object axis - if (mInSnapRegime) - { - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - - // project onto constraint plane - LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE); - object_axis = object_axis * first_node->getObject()->getRenderRotation(); - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center; - LLVector3 line_start = center; - - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv(line_start.mV); - gGL.vertex3fv(object_axis.mV); - } - gGL.end(); - - // draw snap guide arrow - gGL.begin(LLRender::TRIANGLES); - { - LLVector3 arrow_dir; - LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); - arrow_span.normVec(); - - arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start; - arrow_dir.normVec(); - if (ring_num == 1) - { - arrow_dir *= -1.f; - } - gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); - gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); - gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); - } - gGL.end(); - - { - LLGLDepthTest gls_depth(GL_TRUE); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv(line_start.mV); - gGL.vertex3fv(object_axis.mV); - } - gGL.end(); - - // draw snap guide arrow - gGL.begin(LLRender::TRIANGLES); - { - LLVector3 arrow_dir; - LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); - arrow_span.normVec(); - - arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start; - arrow_dir.normVec(); - if (ring_num == 1) - { - arrow_dir *= -1.f; - } - - gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); - gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); - gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); - } - gGL.end(); - } - } - } - } - - - // render help text - if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) - { - if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) - { - LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); - - LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis(); - - F32 line_alpha = gSavedSettings.getF32("GridOpacity"); - - LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir); - const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); - - std::string help_text = LLTrans::getString("manip_hint1"); - LLColor4 help_text_color = LLColor4::white; - help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); - help_text = LLTrans::getString("manip_hint2"); - help_text_pos -= offset_dir * mRadiusMeters * 0.4f; - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); - } - } -} + static LLCachedControl snap_enabled(gSavedSettings, "SnapEnabled", true); + if (!snap_enabled) + { + return; + } -// Returns TRUE if center of sphere is visible. Also sets a bunch of member variables that are used later (e.g. mCenterToCam) -BOOL LLManipRotate::updateVisiblity() -{ - // Don't want to recalculate the center of the selection during a drag. - // Due to packet delays, sometimes half the objects in the selection have their - // new position and half have their old one. This creates subtle errors in the - // computed center position for that frame. Unfortunately, these errors - // accumulate. The result is objects seem to "fly apart" during rotations. - // JC - 03.26.2002 - if (!hasMouseCapture()) - { - mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstance()->getSelectionCenterGlobal(); - } - - BOOL visible = FALSE; - - //Assume that UI scale factor is equivalent for X and Y axis - F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX]; - - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - mCenterToCam = LLVector3(-1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f); - mCenterToCamNorm = mCenterToCam; - mCenterToCamMag = mCenterToCamNorm.normVec(); - - mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - mRadiusMeters /= gAgentCamera.mHUDCurZoom; - mRadiusMeters *= ui_scale_factor; - - mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; - mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; - - // x axis range is (-aspect * 0.5f, +aspect * 0.5) - // y axis range is (-0.5, 0.5) - // so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates - mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()), - (S32)((center.mV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled())); - visible = TRUE; - } - else - { - visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen ); - if( visible ) - { - mCenterToCam = gAgentCamera.getCameraPositionAgent() - center; - mCenterToCamNorm = mCenterToCam; - mCenterToCamMag = mCenterToCamNorm.normVec(); - LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis(); - cameraAtAxis.normVec(); - - F32 z_dist = -1.f * (mCenterToCam * cameraAtAxis); - - // Don't drag manip if object too far away - if (gSavedSettings.getBOOL("LimitSelectDistance")) - { - F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance"); - if (dist_vec_squared(gAgent.getPositionAgent(), center) > (max_select_distance * max_select_distance)) - { - visible = FALSE; - } - } - - if (mCenterToCamMag > 0.001f) - { - F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians - mRadiusMeters = z_dist * tan(apparent_angle); - mRadiusMeters *= ui_scale_factor; - - mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; - mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; - } - else - { - visible = FALSE; - } - } - } - - mCamEdgeOn = FALSE; - F32 axis_onto_cam = mManipPart >= LL_ROT_X ? llabs( getConstraintAxis() * mCenterToCamNorm ) : 0.f; - if( axis_onto_cam < AXIS_ONTO_CAM_TOLERANCE ) - { - mCamEdgeOn = TRUE; - } - - return visible; -} + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; -LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y ) -{ - LLVector3 cam = gAgentCamera.getCameraPositionAgent(); - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - - mMouseCur = intersectMouseWithSphere( x, y, center, mRadiusMeters); - - F32 delta_x = (F32)(mCenterScreen.mX - x); - F32 delta_y = (F32)(mCenterScreen.mY - y); - - F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y); - - LLVector3 axis = mMouseDown % mMouseCur; - F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur); - axis.normVec(); - LLQuaternion sphere_rot( angle, axis ); - - if (is_approx_zero(1.f - mMouseDown * mMouseCur)) - { - return LLQuaternion::DEFAULT; - } - else if (dist_from_sphere_center < RADIUS_PIXELS) - { - return sphere_rot; - } - else - { - LLVector3 intersection; - getMousePointOnPlaneAgent( intersection, x, y, center + mCenterToProfilePlane, mCenterToCamNorm ); - - // amount dragging in sphere from center to periphery would rotate object - F32 in_sphere_angle = F_PI_BY_TWO; - F32 dist_to_tangent_point = mRadiusMeters; - if( !is_approx_zero( mCenterToProfilePlaneMag ) ) - { - dist_to_tangent_point = sqrt( mRadiusMeters * mRadiusMeters - mCenterToProfilePlaneMag * mCenterToProfilePlaneMag ); - in_sphere_angle = atan2( dist_to_tangent_point, mCenterToProfilePlaneMag ); - } - - LLVector3 profile_center_to_intersection = intersection - (center + mCenterToProfilePlane); - F32 dist_to_intersection = profile_center_to_intersection.normVec(); - F32 angle = (-1.f + dist_to_intersection / dist_to_tangent_point) * in_sphere_angle; - - LLVector3 axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - axis = LLVector3(-1.f, 0.f, 0.f) % profile_center_to_intersection; - } - else - { - axis = (cam - center) % profile_center_to_intersection; - axis.normVec(); - } - return sphere_rot * LLQuaternion( angle, axis ); - } -} + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true); -LLVector3 LLManipRotate::getConstraintAxis() -{ - LLVector3 axis; - if( LL_ROT_ROLL == mManipPart ) - { - axis = mCenterToCamNorm; - } - else - { - S32 axis_dir = mManipPart - LL_ROT_X; - if ((axis_dir >= LL_NO_PART) && (axis_dir < LL_Z_ARROW)) - { - axis.mV[axis_dir] = 1.f; - } - else - { -#ifndef LL_RELEASE_FOR_DOWNLOAD - LL_ERRS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL; -#else - LL_WARNS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL; -#endif - axis.mV[0] = 1.f; - } + LLVector3 constraint_axis = getConstraintAxis(); + + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; + LLVector3 world_snap_axis; + LLVector3 test_axis = constraint_axis; - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + BOOL constrain_to_ref_object = FALSE; + if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) + { + test_axis = test_axis * ~grid_rotation; + } + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) + { + test_axis = test_axis * ~grid_rotation; + constrain_to_ref_object = TRUE; + } - LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE); - if (first_node) - { - // *FIX: get agent local attachment grid working - // Put rotation into frame of first selected root object - axis = axis * grid_rotation; - } - } + test_axis.abs(); - return axis; -} + // find closest global/reference axis to local constraint axis; + if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ]) + { + world_snap_axis = LLVector3::y_axis; + } + else if (test_axis.mV[VY] > test_axis.mV[VZ]) + { + world_snap_axis = LLVector3::z_axis; + } + else + { + world_snap_axis = LLVector3::x_axis; + } -LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) -{ - LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE); - LLVector3 constraint_axis = getConstraintAxis(); - LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); - - F32 angle = 0.f; - - // build snap axes - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - LLVector3 axis1; - LLVector3 axis2; - - LLVector3 test_axis = constraint_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) - { - test_axis = test_axis * ~grid_rotation; - } - else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) - { - test_axis = test_axis * ~grid_rotation; - } - test_axis.abs(); - - // find closest global axis to constraint axis; - if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ]) - { - axis1 = LLVector3::y_axis; - } - else if (test_axis.mV[VY] > test_axis.mV[VZ]) - { - axis1 = LLVector3::z_axis; - } - else - { - axis1 = LLVector3::x_axis; - } - - if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) - { - axis1 = axis1 * grid_rotation; - } - else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) - { - axis1 = axis1 * grid_rotation; - } - - //project axis onto constraint plane - axis1 -= (axis1 * constraint_axis) * constraint_axis; - axis1.normVec(); - - // calculate third and final axis - axis2 = constraint_axis % axis1; - - //F32 axis_onto_cam = llabs( constraint_axis * mCenterToCamNorm ); - if( mCamEdgeOn ) - { - // We're looking at the ring edge-on. - LLVector3 snap_plane_center = (center + (constraint_axis * mRadiusMeters * 0.5f)); - LLVector3 cam_to_snap_plane; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - LLVector3 projected_mouse; - BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - if (gSavedSettings.getBOOL("SnapEnabled")) { - S32 snap_plane = 0; - - F32 dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis > 0) - { - snap_plane = 1; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot > 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 1; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 1; - } - } - - if (snap_plane == 0) - { - // try other plane - snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis < 0) - { - snap_plane = 2; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot < 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 2; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 2; - } - } - } - - if (snap_plane > 0) - { - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_at_axis.setVec(1.f, 0.f, 0.f); - } - else - { - cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - // first, project mouse onto screen plane at point tangent to rotation radius. - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); - // project that point onto rotation plane - projected_mouse -= snap_plane_center; - projected_mouse -= projected_vec(projected_mouse, constraint_axis); - - F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - if (llabs(mouse_lateral_dist) > 0.01f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - (mouse_lateral_dist * mouse_lateral_dist)); - } - LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); - projected_mouse -= mouse_depth * projected_camera_at; - - if (!mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - if (first_object_node) - { - object_axis = object_axis * first_object_node->mSavedRotation; - } - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) - { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); - } - else - { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); - } - return LLQuaternion( -angle, constraint_axis ); - } - else - { - if (mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = FALSE; - } - } - else { - if (mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = FALSE; - } - - if (!mInSnapRegime) - { - LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; - up_from_axis.normVec(); - LLVector3 cur_intersection; - getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam); - cur_intersection -= center; - mMouseCur = projected_vec(cur_intersection, up_from_axis); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - F32 mouse_dist_sqrd = mMouseCur.magVecSquared(); - if (mouse_dist_sqrd > 0.0001f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - mouse_dist_sqrd); - } - LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, constraint_axis); - mMouseCur += mouse_depth * projected_center_to_cam; - - F32 dist = (cur_intersection * up_from_axis) - (mMouseDown * up_from_axis); - angle = dist / (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * -F_PI_BY_TWO; - } - } - else - { - LLVector3 projected_mouse; - getMousePointOnPlaneAgent(projected_mouse, x, y, center, constraint_axis); - projected_mouse -= center; - mMouseCur = projected_mouse; - mMouseCur.normVec(); - - if (!first_object_node) - { - return LLQuaternion::DEFAULT; - } - - if (gSavedSettings.getBOOL("SnapEnabled") && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - { - if (!mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - object_axis = object_axis * first_object_node->mSavedRotation; - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) - { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); - } - else - { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); - } - return LLQuaternion( -angle, constraint_axis ); - } - else - { - if (mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = FALSE; - } - - LLVector3 cross_product = mMouseDown % mMouseCur; - angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown); - F32 dir = cross_product * constraint_axis; // cross product - if( dir < 0.f ) - { - angle *= -1.f; - } - } - - F32 rot_step = gSavedSettings.getF32("RotationStep"); - F32 step_size = DEG_TO_RAD * rot_step; - angle -= fmod(angle, step_size); - - return LLQuaternion( angle, constraint_axis ); -} + LLVector3 projected_snap_axis = world_snap_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) + { + projected_snap_axis = projected_snap_axis * grid_rotation; + } + else if (constrain_to_ref_object) + { + projected_snap_axis = projected_snap_axis * grid_rotation; + } + // project world snap axis onto constraint plane + projected_snap_axis -= projected_vec(projected_snap_axis, constraint_axis); + projected_snap_axis.normVec(); + S32 num_rings = mCamEdgeOn ? 2 : 1; + for (S32 ring_num = 0; ring_num < num_rings; ring_num++) + { + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); -LLVector3 LLManipRotate::intersectMouseWithSphere( S32 x, S32 y, const LLVector3& sphere_center, F32 sphere_radius) -{ - LLVector3 ray_pt; - LLVector3 ray_dir; - mouseToRay( x, y, &ray_pt, &ray_dir); - return intersectRayWithSphere( ray_pt, ray_dir, sphere_center, sphere_radius ); -} + if (mCamEdgeOn) + { + // draw two opposing rings + if (ring_num == 0) + { + center += constraint_axis * mRadiusMeters * 0.5f; + } + else + { + center -= constraint_axis * mRadiusMeters * 0.5f; + } + } -LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius) -{ - LLVector3 ray_pt_to_center = sphere_center - ray_pt; - F32 center_distance = ray_pt_to_center.normVec(); - - F32 dot = ray_dir * ray_pt_to_center; - - if (dot == 0.f) - { - return LLVector3::zero; - } - - // point which ray hits plane centered on sphere origin, facing ray origin - LLVector3 intersection_sphere_plane = ray_pt + (ray_dir * center_distance / dot); - // vector from sphere origin to the point, normalized to sphere radius - LLVector3 sphere_center_to_intersection = (intersection_sphere_plane - sphere_center) / sphere_radius; - - F32 dist_squared = sphere_center_to_intersection.magVecSquared(); - LLVector3 result; - - if (dist_squared > 1.f) - { - result = sphere_center_to_intersection; - result.normVec(); - } - else - { - result = sphere_center_to_intersection - ray_dir * sqrt(1.f - dist_squared); - } - - return result; -} + LLGLDepthTest gls_depth(GL_FALSE); + for (S32 pass = 0; pass < 3; pass++) + { + // render snap guide ring + gGL.pushMatrix(); -// Utility function. Should probably be moved to another class. -// x,y - mouse position in scaled window coordinates (NOT GL viewport coordinates) -//static -void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_dir ) -{ - if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) - { - F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom; - F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom; - - *ray_pt = LLVector3(-1.f, -mouse_x, mouse_y); - *ray_dir = LLVector3(1.f, 0.f, 0.f); - } - else - { - *ray_pt = gAgentCamera.getCameraPositionAgent(); - *ray_dir = gViewerWindow->mouseDirectionGlobal(x, y); - } -} + LLQuaternion snap_guide_rot; + F32 angle_radians, x, y, z; + snap_guide_rot.shortestArc(LLVector3::z_axis, getConstraintAxis()); + snap_guide_rot.getAngleAxis(&angle_radians, &x, &y, &z); + gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]); + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); -void LLManipRotate::highlightManipulators( S32 x, S32 y ) -{ - mHighlightedPart = LL_NO_PART; - - //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE); - - if (!first_object) - { - return; - } - - LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter); - LLVector3 mouse_dir_x; - LLVector3 mouse_dir_y; - LLVector3 mouse_dir_z; - LLVector3 intersection_roll; - - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - LLVector3 rot_x_axis = LLVector3::x_axis * grid_rotation; - LLVector3 rot_y_axis = LLVector3::y_axis * grid_rotation; - LLVector3 rot_z_axis = LLVector3::z_axis * grid_rotation; - - F32 proj_rot_x_axis = llabs(rot_x_axis * mCenterToCamNorm); - F32 proj_rot_y_axis = llabs(rot_y_axis * mCenterToCamNorm); - F32 proj_rot_z_axis = llabs(rot_z_axis * mCenterToCamNorm); - - F32 min_select_distance = 0.f; - F32 cur_select_distance = 0.f; - - // test x - getMousePointOnPlaneAgent(mouse_dir_x, x, y, rotation_center, rot_x_axis); - mouse_dir_x -= rotation_center; - // push intersection point out when working at obtuse angle to make ring easier to hit - mouse_dir_x *= 1.f + (1.f - llabs(rot_x_axis * mCenterToCamNorm)) * 0.1f; - - // test y - getMousePointOnPlaneAgent(mouse_dir_y, x, y, rotation_center, rot_y_axis); - mouse_dir_y -= rotation_center; - mouse_dir_y *= 1.f + (1.f - llabs(rot_y_axis * mCenterToCamNorm)) * 0.1f; - - // test z - getMousePointOnPlaneAgent(mouse_dir_z, x, y, rotation_center, rot_z_axis); - mouse_dir_z -= rotation_center; - mouse_dir_z *= 1.f + (1.f - llabs(rot_z_axis * mCenterToCamNorm)) * 0.1f; - - // test roll - getMousePointOnPlaneAgent(intersection_roll, x, y, rotation_center, mCenterToCamNorm); - intersection_roll -= rotation_center; - - F32 dist_x = mouse_dir_x.normVec(); - F32 dist_y = mouse_dir_y.normVec(); - F32 dist_z = mouse_dir_z.normVec(); - - F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightScaled(); - - if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold) - { - // selected x - cur_select_distance = dist_x * mouse_dir_x * mCenterToCamNorm; - if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) - { - min_select_distance = cur_select_distance; - mHighlightedPart = LL_ROT_X; - } - } - if (llabs(dist_y - mRadiusMeters) * llmax(0.05f, proj_rot_y_axis) < distance_threshold) - { - // selected y - cur_select_distance = dist_y * mouse_dir_y * mCenterToCamNorm; - if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) - { - min_select_distance = cur_select_distance; - mHighlightedPart = LL_ROT_Y; - } - } - if (llabs(dist_z - mRadiusMeters) * llmax(0.05f, proj_rot_z_axis) < distance_threshold) - { - // selected z - cur_select_distance = dist_z * mouse_dir_z * mCenterToCamNorm; - if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) - { - min_select_distance = cur_select_distance; - mHighlightedPart = LL_ROT_Z; - } - } - - // test for edge-on intersections - if (proj_rot_x_axis < 0.05f) - { - if ((proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_x_axis) < distance_threshold) && dist_y < mRadiusMeters) || - (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_x_axis) < distance_threshold) && dist_z < mRadiusMeters)) - { - mHighlightedPart = LL_ROT_X; - } - } - - if (proj_rot_y_axis < 0.05f) - { - if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_y_axis) < distance_threshold) && dist_x < mRadiusMeters) || - (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_y_axis) < distance_threshold) && dist_z < mRadiusMeters)) - { - mHighlightedPart = LL_ROT_Y; - } - } - - if (proj_rot_z_axis < 0.05f) - { - if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_z_axis) < distance_threshold) && dist_x < mRadiusMeters) || - (proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_z_axis) < distance_threshold) && dist_y < mRadiusMeters)) - { - mHighlightedPart = LL_ROT_Z; - } - } - - // test for roll - if (mHighlightedPart == LL_NO_PART) - { - F32 roll_distance = intersection_roll.magVec(); - F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS; - - // use larger distance threshold for roll as it is checked only if something else wasn't highlighted - if (llabs(roll_distance - (mRadiusMeters + (width_meters * 2.f))) < distance_threshold * 2.f) - { - mHighlightedPart = LL_ROT_ROLL; - } - else if (roll_distance < mRadiusMeters) - { - mHighlightedPart = LL_ROT_GENERAL; - } - } -} + LLColor4 line_color = setupSnapGuideRenderPass(pass); -S32 LLManipRotate::getObjectAxisClosestToMouse(LLVector3& object_axis) -{ - LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE); - - if (!first_object_node) - { - object_axis.clearVec(); - return -1; - } - - LLQuaternion obj_rotation = first_object_node->mSavedRotation; - LLVector3 mouse_down_object = mMouseDown * ~obj_rotation; - LLVector3 mouse_down_abs = mouse_down_object; - mouse_down_abs.abs(); - - S32 axis_index = 0; - if (mouse_down_abs.mV[VX] > mouse_down_abs.mV[VY] && mouse_down_abs.mV[VX] > mouse_down_abs.mV[VZ]) - { - if (mouse_down_object.mV[VX] > 0.f) - { - object_axis = LLVector3::x_axis; - } - else - { - object_axis = LLVector3::x_axis_neg; - } - axis_index = VX; - } - else if (mouse_down_abs.mV[VY] > mouse_down_abs.mV[VZ]) - { - if (mouse_down_object.mV[VY] > 0.f) - { - object_axis = LLVector3::y_axis; - } - else - { - object_axis = LLVector3::y_axis_neg; - } - axis_index = VY; - } - else - { - if (mouse_down_object.mV[VZ] > 0.f) - { - object_axis = LLVector3::z_axis; - } - else - { - object_axis = LLVector3::z_axis_neg; - } - axis_index = VZ; - } - - return axis_index; -} + gGL.color4fv(line_color.mV); -//virtual -BOOL LLManipRotate::canAffectSelection() -{ - BOOL can_rotate = mObjectSelection->getObjectCount() != 0; - if (can_rotate) - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* objectp) - { - LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); - return objectp->permMove() && !objectp->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - } - } func; - can_rotate = mObjectSelection->applyToObjects(&func); - } - return can_rotate; + if (mCamEdgeOn) + { + // render an arc + LLVector3 edge_normal = cam_at_axis % constraint_axis; + edge_normal.normVec(); + LLVector3 x_axis_snap = LLVector3::x_axis * snap_guide_rot; + LLVector3 y_axis_snap = LLVector3::y_axis * snap_guide_rot; + + F32 end_angle = atan2(y_axis_snap * edge_normal, x_axis_snap * edge_normal); + //F32 start_angle = angle_between((-1.f * LLVector3::x_axis) * snap_guide_rot, edge_normal); + F32 start_angle = end_angle - F_PI; + gl_arc_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE, start_angle, end_angle); + } + else + { + gl_circle_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE); + } + gGL.popMatrix(); + + for (S32 i = 0; i < 64; i++) + { + BOOL render_text = TRUE; + F32 deg = 5.625f * (F32)i; + LLVector3 inner_point; + LLVector3 outer_point; + LLVector3 text_point; + LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis); + gGL.begin(LLRender::LINES); + { + inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center; + F32 tick_length = 0.f; + if (i % 16 == 0) + { + tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_1 - SNAP_GUIDE_INNER_RADIUS); + } + else if (i % 8 == 0) + { + tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_2 - SNAP_GUIDE_INNER_RADIUS); + } + else if (i % 4 == 0) + { + tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_3 - SNAP_GUIDE_INNER_RADIUS); + } + else if (i % 2 == 0) + { + tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_4 - SNAP_GUIDE_INNER_RADIUS); + } + else + { + tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_5 - SNAP_GUIDE_INNER_RADIUS); + } + + if (mCamEdgeOn) + { + // don't draw ticks that are on back side of circle + F32 dot = cam_at_axis * (projected_snap_axis * rot); + if (dot > 0.f) + { + outer_point = inner_point; + render_text = FALSE; + } + else + { + if (ring_num == 0) + { + outer_point = inner_point + (constraint_axis * tick_length) * rot; + } + else + { + outer_point = inner_point - (constraint_axis * tick_length) * rot; + } + } + } + else + { + outer_point = inner_point + (projected_snap_axis * tick_length) * rot; + } + + text_point = outer_point + (projected_snap_axis * mRadiusMeters * 0.1f) * rot; + + gGL.vertex3fv(inner_point.mV); + gGL.vertex3fv(outer_point.mV); + } + gGL.end(); + + //RN: text rendering does own shadow pass, so only render once + if (pass == 1 && render_text && i % 16 == 0) + { + if (world_snap_axis.mV[VX]) + { + if (i == 0) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); + } + else if (i == 16) + { + if (constraint_axis.mV[VZ] > 0.f) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); + } + else + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); + } + } + else if (i == 32) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); + } + else + { + if (constraint_axis.mV[VZ] > 0.f) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); + } + else + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); + } + } + } + else if (world_snap_axis.mV[VY]) + { + if (i == 0) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); + } + else if (i == 16) + { + if (constraint_axis.mV[VX] > 0.f) + { + renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); + } + else + { + renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); + } + } + else if (i == 32) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); + } + else + { + if (constraint_axis.mV[VX] > 0.f) + { + renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); + } + else + { + renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); + } + } + } + else if (world_snap_axis.mV[VZ]) + { + if (i == 0) + { + renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white); + } + else if (i == 16) + { + if (constraint_axis.mV[VY] > 0.f) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); + } + else + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); + } + } + else if (i == 32) + { + renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white); + } + else + { + if (constraint_axis.mV[VY] > 0.f) + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); + } + else + { + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); + } + } + } + } + gGL.color4fv(line_color.mV); + } + + // now render projected object axis + if (mInSnapRegime) + { + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + + // project onto constraint plane + LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE); + object_axis = object_axis * first_node->getObject()->getRenderRotation(); + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center; + LLVector3 line_start = center; + + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(object_axis.mV); + } + gGL.end(); + + // draw snap guide arrow + gGL.begin(LLRender::TRIANGLES); + { + LLVector3 arrow_dir; + LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); + arrow_span.normVec(); + + arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start; + arrow_dir.normVec(); + if (ring_num == 1) + { + arrow_dir *= -1.f; + } + gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); + } + gGL.end(); + + { + LLGLDepthTest gls_depth(GL_TRUE); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(object_axis.mV); + } + gGL.end(); + + // draw snap guide arrow + gGL.begin(LLRender::TRIANGLES); + { + LLVector3 arrow_dir; + LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); + arrow_span.normVec(); + + arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start; + arrow_dir.normVec(); + if (ring_num == 1) + { + arrow_dir *= -1.f; + } + + gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); + } + gGL.end(); + } + } + } + } + + + // render help text + if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) + { + if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) + { + LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); + + LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis(); + + F32 line_alpha = gSavedSettings.getF32("GridOpacity"); + + LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir); + const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); + + std::string help_text = LLTrans::getString("manip_hint1"); + LLColor4 help_text_color = LLColor4::white; + help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); + help_text = LLTrans::getString("manip_hint2"); + help_text_pos -= offset_dir * mRadiusMeters * 0.4f; + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); + } + } +} + +// Returns TRUE if center of sphere is visible. Also sets a bunch of member variables that are used later (e.g. mCenterToCam) +BOOL LLManipRotate::updateVisiblity() +{ + // Don't want to recalculate the center of the selection during a drag. + // Due to packet delays, sometimes half the objects in the selection have their + // new position and half have their old one. This creates subtle errors in the + // computed center position for that frame. Unfortunately, these errors + // accumulate. The result is objects seem to "fly apart" during rotations. + // JC - 03.26.2002 + if (!hasMouseCapture()) + { + mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstance()->getSelectionCenterGlobal(); + } + + BOOL visible = FALSE; + + //Assume that UI scale factor is equivalent for X and Y axis + F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX]; + + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + mCenterToCam = LLVector3(-1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f); + mCenterToCamNorm = mCenterToCam; + mCenterToCamMag = mCenterToCamNorm.normVec(); + + mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + mRadiusMeters /= gAgentCamera.mHUDCurZoom; + mRadiusMeters *= ui_scale_factor; + + mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; + mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; + + // x axis range is (-aspect * 0.5f, +aspect * 0.5) + // y axis range is (-0.5, 0.5) + // so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates + mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()), + (S32)((center.mV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled())); + visible = TRUE; + } + else + { + visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen ); + if( visible ) + { + mCenterToCam = gAgentCamera.getCameraPositionAgent() - center; + mCenterToCamNorm = mCenterToCam; + mCenterToCamMag = mCenterToCamNorm.normVec(); + LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis(); + cameraAtAxis.normVec(); + + F32 z_dist = -1.f * (mCenterToCam * cameraAtAxis); + + // Don't drag manip if object too far away + if (gSavedSettings.getBOOL("LimitSelectDistance")) + { + F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance"); + if (dist_vec_squared(gAgent.getPositionAgent(), center) > (max_select_distance * max_select_distance)) + { + visible = FALSE; + } + } + + if (mCenterToCamMag > 0.001f) + { + F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians + mRadiusMeters = z_dist * tan(apparent_angle); + mRadiusMeters *= ui_scale_factor; + + mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; + mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; + } + else + { + visible = FALSE; + } + } + } + + mCamEdgeOn = FALSE; + F32 axis_onto_cam = mManipPart >= LL_ROT_X ? llabs( getConstraintAxis() * mCenterToCamNorm ) : 0.f; + if( axis_onto_cam < AXIS_ONTO_CAM_TOLERANCE ) + { + mCamEdgeOn = TRUE; + } + + return visible; +} + +LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y ) +{ + LLVector3 cam = gAgentCamera.getCameraPositionAgent(); + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + + mMouseCur = intersectMouseWithSphere( x, y, center, mRadiusMeters); + + F32 delta_x = (F32)(mCenterScreen.mX - x); + F32 delta_y = (F32)(mCenterScreen.mY - y); + + F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y); + + LLVector3 axis = mMouseDown % mMouseCur; + F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur); + axis.normVec(); + LLQuaternion sphere_rot( angle, axis ); + + if (is_approx_zero(1.f - mMouseDown * mMouseCur)) + { + return LLQuaternion::DEFAULT; + } + else if (dist_from_sphere_center < RADIUS_PIXELS) + { + return sphere_rot; + } + else + { + LLVector3 intersection; + getMousePointOnPlaneAgent( intersection, x, y, center + mCenterToProfilePlane, mCenterToCamNorm ); + + // amount dragging in sphere from center to periphery would rotate object + F32 in_sphere_angle = F_PI_BY_TWO; + F32 dist_to_tangent_point = mRadiusMeters; + if( !is_approx_zero( mCenterToProfilePlaneMag ) ) + { + dist_to_tangent_point = sqrt( mRadiusMeters * mRadiusMeters - mCenterToProfilePlaneMag * mCenterToProfilePlaneMag ); + in_sphere_angle = atan2( dist_to_tangent_point, mCenterToProfilePlaneMag ); + } + + LLVector3 profile_center_to_intersection = intersection - (center + mCenterToProfilePlane); + F32 dist_to_intersection = profile_center_to_intersection.normVec(); + F32 angle = (-1.f + dist_to_intersection / dist_to_tangent_point) * in_sphere_angle; + + LLVector3 axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + axis = LLVector3(-1.f, 0.f, 0.f) % profile_center_to_intersection; + } + else + { + axis = (cam - center) % profile_center_to_intersection; + axis.normVec(); + } + return sphere_rot * LLQuaternion( angle, axis ); + } +} + +LLVector3 LLManipRotate::getConstraintAxis() +{ + LLVector3 axis; + if( LL_ROT_ROLL == mManipPart ) + { + axis = mCenterToCamNorm; + } + else + { + S32 axis_dir = mManipPart - LL_ROT_X; + if ((axis_dir >= LL_NO_PART) && (axis_dir < LL_Z_ARROW)) + { + axis.mV[axis_dir] = 1.f; + } + else + { +#ifndef LL_RELEASE_FOR_DOWNLOAD + LL_ERRS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL; +#else + LL_WARNS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL; +#endif + axis.mV[0] = 1.f; + } + + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE); + if (first_node) + { + // *FIX: get agent local attachment grid working + // Put rotation into frame of first selected root object + axis = axis * grid_rotation; + } + } + + return axis; +} + +LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) +{ + LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE); + LLVector3 constraint_axis = getConstraintAxis(); + LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); + + F32 angle = 0.f; + + // build snap axes + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + LLVector3 axis1; + LLVector3 axis2; + + LLVector3 test_axis = constraint_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) + { + test_axis = test_axis * ~grid_rotation; + } + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) + { + test_axis = test_axis * ~grid_rotation; + } + test_axis.abs(); + + // find closest global axis to constraint axis; + if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ]) + { + axis1 = LLVector3::y_axis; + } + else if (test_axis.mV[VY] > test_axis.mV[VZ]) + { + axis1 = LLVector3::z_axis; + } + else + { + axis1 = LLVector3::x_axis; + } + + if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) + { + axis1 = axis1 * grid_rotation; + } + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) + { + axis1 = axis1 * grid_rotation; + } + + //project axis onto constraint plane + axis1 -= (axis1 * constraint_axis) * constraint_axis; + axis1.normVec(); + + // calculate third and final axis + axis2 = constraint_axis % axis1; + + //F32 axis_onto_cam = llabs( constraint_axis * mCenterToCamNorm ); + if( mCamEdgeOn ) + { + // We're looking at the ring edge-on. + LLVector3 snap_plane_center = (center + (constraint_axis * mRadiusMeters * 0.5f)); + LLVector3 cam_to_snap_plane; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + LLVector3 projected_mouse; + BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + if (gSavedSettings.getBOOL("SnapEnabled")) { + S32 snap_plane = 0; + + F32 dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis > 0) + { + snap_plane = 1; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot > 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 1; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 1; + } + } + + if (snap_plane == 0) + { + // try other plane + snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis < 0) + { + snap_plane = 2; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot < 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 2; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 2; + } + } + } + + if (snap_plane > 0) + { + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } + + // first, project mouse onto screen plane at point tangent to rotation radius. + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); + // project that point onto rotation plane + projected_mouse -= snap_plane_center; + projected_mouse -= projected_vec(projected_mouse, constraint_axis); + + F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + if (llabs(mouse_lateral_dist) > 0.01f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + (mouse_lateral_dist * mouse_lateral_dist)); + } + LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); + projected_mouse -= mouse_depth * projected_camera_at; + + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + if (first_object_node) + { + object_axis = object_axis * first_object_node->mSavedRotation; + } + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); + } + else + { + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; + } + } + else { + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; + } + + if (!mInSnapRegime) + { + LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; + up_from_axis.normVec(); + LLVector3 cur_intersection; + getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam); + cur_intersection -= center; + mMouseCur = projected_vec(cur_intersection, up_from_axis); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + F32 mouse_dist_sqrd = mMouseCur.magVecSquared(); + if (mouse_dist_sqrd > 0.0001f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + mouse_dist_sqrd); + } + LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, constraint_axis); + mMouseCur += mouse_depth * projected_center_to_cam; + + F32 dist = (cur_intersection * up_from_axis) - (mMouseDown * up_from_axis); + angle = dist / (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * -F_PI_BY_TWO; + } + } + else + { + LLVector3 projected_mouse; + getMousePointOnPlaneAgent(projected_mouse, x, y, center, constraint_axis); + projected_mouse -= center; + mMouseCur = projected_mouse; + mMouseCur.normVec(); + + if (!first_object_node) + { + return LLQuaternion::DEFAULT; + } + + if (gSavedSettings.getBOOL("SnapEnabled") && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) + { + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + object_axis = object_axis * first_object_node->mSavedRotation; + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); + } + else + { + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; + } + + LLVector3 cross_product = mMouseDown % mMouseCur; + angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown); + F32 dir = cross_product * constraint_axis; // cross product + if( dir < 0.f ) + { + angle *= -1.f; + } + } + + F32 rot_step = gSavedSettings.getF32("RotationStep"); + F32 step_size = DEG_TO_RAD * rot_step; + angle -= fmod(angle, step_size); + + return LLQuaternion( angle, constraint_axis ); +} + + + +LLVector3 LLManipRotate::intersectMouseWithSphere( S32 x, S32 y, const LLVector3& sphere_center, F32 sphere_radius) +{ + LLVector3 ray_pt; + LLVector3 ray_dir; + mouseToRay( x, y, &ray_pt, &ray_dir); + return intersectRayWithSphere( ray_pt, ray_dir, sphere_center, sphere_radius ); +} + +LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius) +{ + LLVector3 ray_pt_to_center = sphere_center - ray_pt; + F32 center_distance = ray_pt_to_center.normVec(); + + F32 dot = ray_dir * ray_pt_to_center; + + if (dot == 0.f) + { + return LLVector3::zero; + } + + // point which ray hits plane centered on sphere origin, facing ray origin + LLVector3 intersection_sphere_plane = ray_pt + (ray_dir * center_distance / dot); + // vector from sphere origin to the point, normalized to sphere radius + LLVector3 sphere_center_to_intersection = (intersection_sphere_plane - sphere_center) / sphere_radius; + + F32 dist_squared = sphere_center_to_intersection.magVecSquared(); + LLVector3 result; + + if (dist_squared > 1.f) + { + result = sphere_center_to_intersection; + result.normVec(); + } + else + { + result = sphere_center_to_intersection - ray_dir * sqrt(1.f - dist_squared); + } + + return result; +} + +// Utility function. Should probably be moved to another class. +// x,y - mouse position in scaled window coordinates (NOT GL viewport coordinates) +//static +void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_dir ) +{ + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + { + F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom; + F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom; + + *ray_pt = LLVector3(-1.f, -mouse_x, mouse_y); + *ray_dir = LLVector3(1.f, 0.f, 0.f); + } + else + { + *ray_pt = gAgentCamera.getCameraPositionAgent(); + *ray_dir = gViewerWindow->mouseDirectionGlobal(x, y); + } +} + +void LLManipRotate::highlightManipulators( S32 x, S32 y ) +{ + mHighlightedPart = LL_NO_PART; + + //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE); + + if (!first_object) + { + return; + } + + LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter); + LLVector3 mouse_dir_x; + LLVector3 mouse_dir_y; + LLVector3 mouse_dir_z; + LLVector3 intersection_roll; + + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + + LLVector3 rot_x_axis = LLVector3::x_axis * grid_rotation; + LLVector3 rot_y_axis = LLVector3::y_axis * grid_rotation; + LLVector3 rot_z_axis = LLVector3::z_axis * grid_rotation; + + F32 proj_rot_x_axis = llabs(rot_x_axis * mCenterToCamNorm); + F32 proj_rot_y_axis = llabs(rot_y_axis * mCenterToCamNorm); + F32 proj_rot_z_axis = llabs(rot_z_axis * mCenterToCamNorm); + + F32 min_select_distance = 0.f; + F32 cur_select_distance = 0.f; + + // test x + getMousePointOnPlaneAgent(mouse_dir_x, x, y, rotation_center, rot_x_axis); + mouse_dir_x -= rotation_center; + // push intersection point out when working at obtuse angle to make ring easier to hit + mouse_dir_x *= 1.f + (1.f - llabs(rot_x_axis * mCenterToCamNorm)) * 0.1f; + + // test y + getMousePointOnPlaneAgent(mouse_dir_y, x, y, rotation_center, rot_y_axis); + mouse_dir_y -= rotation_center; + mouse_dir_y *= 1.f + (1.f - llabs(rot_y_axis * mCenterToCamNorm)) * 0.1f; + + // test z + getMousePointOnPlaneAgent(mouse_dir_z, x, y, rotation_center, rot_z_axis); + mouse_dir_z -= rotation_center; + mouse_dir_z *= 1.f + (1.f - llabs(rot_z_axis * mCenterToCamNorm)) * 0.1f; + + // test roll + getMousePointOnPlaneAgent(intersection_roll, x, y, rotation_center, mCenterToCamNorm); + intersection_roll -= rotation_center; + + F32 dist_x = mouse_dir_x.normVec(); + F32 dist_y = mouse_dir_y.normVec(); + F32 dist_z = mouse_dir_z.normVec(); + + F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightScaled(); + + if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold) + { + // selected x + cur_select_distance = dist_x * mouse_dir_x * mCenterToCamNorm; + if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) + { + min_select_distance = cur_select_distance; + mHighlightedPart = LL_ROT_X; + } + } + if (llabs(dist_y - mRadiusMeters) * llmax(0.05f, proj_rot_y_axis) < distance_threshold) + { + // selected y + cur_select_distance = dist_y * mouse_dir_y * mCenterToCamNorm; + if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) + { + min_select_distance = cur_select_distance; + mHighlightedPart = LL_ROT_Y; + } + } + if (llabs(dist_z - mRadiusMeters) * llmax(0.05f, proj_rot_z_axis) < distance_threshold) + { + // selected z + cur_select_distance = dist_z * mouse_dir_z * mCenterToCamNorm; + if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance)) + { + min_select_distance = cur_select_distance; + mHighlightedPart = LL_ROT_Z; + } + } + + // test for edge-on intersections + if (proj_rot_x_axis < 0.05f) + { + if ((proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_x_axis) < distance_threshold) && dist_y < mRadiusMeters) || + (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_x_axis) < distance_threshold) && dist_z < mRadiusMeters)) + { + mHighlightedPart = LL_ROT_X; + } + } + + if (proj_rot_y_axis < 0.05f) + { + if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_y_axis) < distance_threshold) && dist_x < mRadiusMeters) || + (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_y_axis) < distance_threshold) && dist_z < mRadiusMeters)) + { + mHighlightedPart = LL_ROT_Y; + } + } + + if (proj_rot_z_axis < 0.05f) + { + if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_z_axis) < distance_threshold) && dist_x < mRadiusMeters) || + (proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_z_axis) < distance_threshold) && dist_y < mRadiusMeters)) + { + mHighlightedPart = LL_ROT_Z; + } + } + + // test for roll + if (mHighlightedPart == LL_NO_PART) + { + F32 roll_distance = intersection_roll.magVec(); + F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS; + + // use larger distance threshold for roll as it is checked only if something else wasn't highlighted + if (llabs(roll_distance - (mRadiusMeters + (width_meters * 2.f))) < distance_threshold * 2.f) + { + mHighlightedPart = LL_ROT_ROLL; + } + else if (roll_distance < mRadiusMeters) + { + mHighlightedPart = LL_ROT_GENERAL; + } + } +} + +S32 LLManipRotate::getObjectAxisClosestToMouse(LLVector3& object_axis) +{ + LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE); + + if (!first_object_node) + { + object_axis.clearVec(); + return -1; + } + + LLQuaternion obj_rotation = first_object_node->mSavedRotation; + LLVector3 mouse_down_object = mMouseDown * ~obj_rotation; + LLVector3 mouse_down_abs = mouse_down_object; + mouse_down_abs.abs(); + + S32 axis_index = 0; + if (mouse_down_abs.mV[VX] > mouse_down_abs.mV[VY] && mouse_down_abs.mV[VX] > mouse_down_abs.mV[VZ]) + { + if (mouse_down_object.mV[VX] > 0.f) + { + object_axis = LLVector3::x_axis; + } + else + { + object_axis = LLVector3::x_axis_neg; + } + axis_index = VX; + } + else if (mouse_down_abs.mV[VY] > mouse_down_abs.mV[VZ]) + { + if (mouse_down_object.mV[VY] > 0.f) + { + object_axis = LLVector3::y_axis; + } + else + { + object_axis = LLVector3::y_axis_neg; + } + axis_index = VY; + } + else + { + if (mouse_down_object.mV[VZ] > 0.f) + { + object_axis = LLVector3::z_axis; + } + else + { + object_axis = LLVector3::z_axis_neg; + } + axis_index = VZ; + } + + return axis_index; +} + +//virtual +BOOL LLManipRotate::canAffectSelection() +{ + BOOL can_rotate = mObjectSelection->getObjectCount() != 0; + if (can_rotate) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* objectp) + { + LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); + return objectp->permMove() && !objectp->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + } + } func; + can_rotate = mObjectSelection->applyToObjects(&func); + } + return can_rotate; } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 9fc5ad502c..b3ecb6403b 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmaniptranslate.cpp * @brief LLManipTranslate class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -76,202 +76,202 @@ const F32 SNAP_ARROW_SCALE = 0.7f; static LLPointer sGridTex = NULL ; -const LLManip::EManipPart MANIPULATOR_IDS[9] = +const LLManip::EManipPart MANIPULATOR_IDS[9] = { - LLManip::LL_X_ARROW, - LLManip::LL_Y_ARROW, - LLManip::LL_Z_ARROW, - LLManip::LL_X_ARROW, - LLManip::LL_Y_ARROW, - LLManip::LL_Z_ARROW, - LLManip::LL_YZ_PLANE, - LLManip::LL_XZ_PLANE, - LLManip::LL_XY_PLANE + LLManip::LL_X_ARROW, + LLManip::LL_Y_ARROW, + LLManip::LL_Z_ARROW, + LLManip::LL_X_ARROW, + LLManip::LL_Y_ARROW, + LLManip::LL_Z_ARROW, + LLManip::LL_YZ_PLANE, + LLManip::LL_XZ_PLANE, + LLManip::LL_XY_PLANE }; -const U32 ARROW_TO_AXIS[4] = +const U32 ARROW_TO_AXIS[4] = { - VX, - VX, - VY, - VZ + VX, + VX, + VY, + VZ }; // Sort manipulator handles by their screen-space projection struct ClosestToCamera { - bool operator()(const LLManipTranslate::ManipulatorHandle& a, - const LLManipTranslate::ManipulatorHandle& b) const - { - return a.mEndPosition.mV[VZ] < b.mEndPosition.mV[VZ]; - } + bool operator()(const LLManipTranslate::ManipulatorHandle& a, + const LLManipTranslate::ManipulatorHandle& b) const + { + return a.mEndPosition.mV[VZ] < b.mEndPosition.mV[VZ]; + } }; LLManipTranslate::LLManipTranslate( LLToolComposite* composite ) -: LLManip( std::string("Move"), composite ), - mLastHoverMouseX(-1), - mLastHoverMouseY(-1), - mMouseOutsideSlop(FALSE), - mCopyMadeThisDrag(FALSE), - mMouseDownX(-1), - mMouseDownY(-1), - mAxisArrowLength(50), - mConeSize(0), - mArrowLengthMeters(0.f), - mGridSizeMeters(1.f), - mPlaneManipOffsetMeters(0.f), - mUpdateTimer(), - mSnapOffsetMeters(0.f), - mSubdivisions(10.f), - mInSnapRegime(FALSE), - mArrowScales(1.f, 1.f, 1.f), - mPlaneScales(1.f, 1.f, 1.f), - mPlaneManipPositions(1.f, 1.f, 1.f, 1.f) -{ - if (sGridTex.isNull()) - { - restoreGL(); - } +: LLManip( std::string("Move"), composite ), + mLastHoverMouseX(-1), + mLastHoverMouseY(-1), + mMouseOutsideSlop(FALSE), + mCopyMadeThisDrag(FALSE), + mMouseDownX(-1), + mMouseDownY(-1), + mAxisArrowLength(50), + mConeSize(0), + mArrowLengthMeters(0.f), + mGridSizeMeters(1.f), + mPlaneManipOffsetMeters(0.f), + mUpdateTimer(), + mSnapOffsetMeters(0.f), + mSubdivisions(10.f), + mInSnapRegime(FALSE), + mArrowScales(1.f, 1.f, 1.f), + mPlaneScales(1.f, 1.f, 1.f), + mPlaneManipPositions(1.f, 1.f, 1.f, 1.f) +{ + if (sGridTex.isNull()) + { + restoreGL(); + } } //static U32 LLManipTranslate::getGridTexName() { - if(sGridTex.isNull()) - { - restoreGL() ; - } + if(sGridTex.isNull()) + { + restoreGL() ; + } - return sGridTex.isNull() ? 0 : sGridTex->getTexName() ; + return sGridTex.isNull() ? 0 : sGridTex->getTexName() ; } //static void LLManipTranslate::destroyGL() { - if (sGridTex) - { - sGridTex = NULL ; - } + if (sGridTex) + { + sGridTex = NULL ; + } } //static void LLManipTranslate::restoreGL() { - //generate grid texture - U32 rez = 512; - U32 mip = 0; - - destroyGL() ; - sGridTex = LLViewerTextureManager::getLocalTexture() ; - if(!sGridTex->createGLTexture()) - { - sGridTex = NULL ; - return ; - } - - GLuint* d = new GLuint[rez*rez]; - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex->getTexName(), true); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - - while (rez >= 1) - { - for (U32 i = 0; i < rez*rez; i++) - { - d[i] = 0x00FFFFFF; - } - - U32 subcol = 0xFFFFFFFF; - if (rez >= 4) - { //large grain grid - for (U32 i = 0; i < rez; i++) - { - if (rez <= 16) - { - if (rez == 16) - { - subcol = 0xA0FFFFFF; - } - else if (rez == 8) - { - subcol = 0x80FFFFFF; - } - else - { - subcol = 0x40FFFFFF; - } - } - else - { - subcol = 0xFFFFFFFF; - } - d[i *rez+ 0 ] = subcol; - d[0 *rez+ i ] = subcol; - if (rez >= 32) - { - d[i *rez+ (rez-1)] = subcol; - d[(rez-1) *rez+ i ] = subcol; - } - - if (rez >= 64) - { - subcol = 0xFFFFFFFF; - - if (i > 0 && i < (rez-1)) - { - d[i *rez+ 1 ] = subcol; - d[i *rez+ (rez-2)] = subcol; - d[1 *rez+ i ] = subcol; - d[(rez-2) *rez+ i ] = subcol; - } - } - } - } - - subcol = 0x50A0A0A0; - if (rez >= 128) - { //small grain grid - for (U32 i = 8; i < rez; i+=8) - { - for (U32 j = 2; j < rez-2; j++) - { - d[i *rez+ j] = subcol; - d[j *rez+ i] = subcol; - } - } - } - if (rez >= 64) - { //medium grain grid - if (rez == 64) - { - subcol = 0x50A0A0A0; - } - else - { - subcol = 0xA0D0D0D0; - } - - for (U32 i = 32; i < rez; i+=32) - { - U32 pi = i-1; - for (U32 j = 2; j < rez-2; j++) - { - d[i *rez+ j] = subcol; - d[j *rez+ i] = subcol; - - if (rez > 128) - { - d[pi *rez+ j] = subcol; - d[j *rez+ pi] = subcol; - } - } - } - } - LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_BYTE, d); - rez = rez >> 1; - mip++; - } - delete [] d; + //generate grid texture + U32 rez = 512; + U32 mip = 0; + + destroyGL() ; + sGridTex = LLViewerTextureManager::getLocalTexture() ; + if(!sGridTex->createGLTexture()) + { + sGridTex = NULL ; + return ; + } + + GLuint* d = new GLuint[rez*rez]; + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex->getTexName(), true); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + + while (rez >= 1) + { + for (U32 i = 0; i < rez*rez; i++) + { + d[i] = 0x00FFFFFF; + } + + U32 subcol = 0xFFFFFFFF; + if (rez >= 4) + { //large grain grid + for (U32 i = 0; i < rez; i++) + { + if (rez <= 16) + { + if (rez == 16) + { + subcol = 0xA0FFFFFF; + } + else if (rez == 8) + { + subcol = 0x80FFFFFF; + } + else + { + subcol = 0x40FFFFFF; + } + } + else + { + subcol = 0xFFFFFFFF; + } + d[i *rez+ 0 ] = subcol; + d[0 *rez+ i ] = subcol; + if (rez >= 32) + { + d[i *rez+ (rez-1)] = subcol; + d[(rez-1) *rez+ i ] = subcol; + } + + if (rez >= 64) + { + subcol = 0xFFFFFFFF; + + if (i > 0 && i < (rez-1)) + { + d[i *rez+ 1 ] = subcol; + d[i *rez+ (rez-2)] = subcol; + d[1 *rez+ i ] = subcol; + d[(rez-2) *rez+ i ] = subcol; + } + } + } + } + + subcol = 0x50A0A0A0; + if (rez >= 128) + { //small grain grid + for (U32 i = 8; i < rez; i+=8) + { + for (U32 j = 2; j < rez-2; j++) + { + d[i *rez+ j] = subcol; + d[j *rez+ i] = subcol; + } + } + } + if (rez >= 64) + { //medium grain grid + if (rez == 64) + { + subcol = 0x50A0A0A0; + } + else + { + subcol = 0xA0D0D0D0; + } + + for (U32 i = 32; i < rez; i+=32) + { + U32 pi = i-1; + for (U32 j = 2; j < rez-2; j++) + { + d[i *rez+ j] = subcol; + d[j *rez+ i] = subcol; + + if (rez > 128) + { + d[pi *rez+ j] = subcol; + d[j *rez+ pi] = subcol; + } + } + } + } + LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_BYTE, d); + rez = rez >> 1; + mip++; + } + delete [] d; } @@ -282,379 +282,379 @@ LLManipTranslate::~LLManipTranslate() void LLManipTranslate::handleSelect() { - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); if (gFloaterTools) { gFloaterTools->setStatusText("move"); } - LLManip::handleSelect(); + LLManip::handleSelect(); } BOOL LLManipTranslate::handleMouseDown(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; - - // didn't click in any UI object, so must have clicked in the world - if( (mHighlightedPart == LL_X_ARROW || - mHighlightedPart == LL_Y_ARROW || - mHighlightedPart == LL_Z_ARROW || - mHighlightedPart == LL_YZ_PLANE || - mHighlightedPart == LL_XZ_PLANE || - mHighlightedPart == LL_XY_PLANE ) ) - { - handled = handleMouseDownOnPart( x, y, mask ); - } - - return handled; + BOOL handled = FALSE; + + // didn't click in any UI object, so must have clicked in the world + if( (mHighlightedPart == LL_X_ARROW || + mHighlightedPart == LL_Y_ARROW || + mHighlightedPart == LL_Z_ARROW || + mHighlightedPart == LL_YZ_PLANE || + mHighlightedPart == LL_XZ_PLANE || + mHighlightedPart == LL_XY_PLANE ) ) + { + handled = handleMouseDownOnPart( x, y, mask ); + } + + return handled; } // Assumes that one of the arrows on an object was hit. BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) { - BOOL can_move = canAffectSelection(); - if (!can_move) - { - return FALSE; - } - - highlightManipulators(x, y); - S32 hit_part = mHighlightedPart; - - if( (hit_part != LL_X_ARROW) && - (hit_part != LL_Y_ARROW) && - (hit_part != LL_Z_ARROW) && - (hit_part != LL_YZ_PLANE) && - (hit_part != LL_XZ_PLANE) && - (hit_part != LL_XY_PLANE) ) - { - return TRUE; - } - - mHelpTextTimer.reset(); - sNumTimesHelpTextShown++; - - LLSelectMgr::getInstance()->getGrid(mGridOrigin, mGridRotation, mGridScale); - - LLSelectMgr::getInstance()->enableSilhouette(FALSE); - - // we just started a drag, so save initial object positions - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE); - - mManipPart = (EManipPart)hit_part; - mMouseDownX = x; - mMouseDownY = y; - mMouseOutsideSlop = FALSE; - - LLVector3 axis; - - LLSelectNode *selectNode = mObjectSelection->getFirstMoveableNode(TRUE); - - if (!selectNode) - { - // didn't find the object in our selection...oh well - LL_WARNS() << "Trying to translate an unselected object" << LL_ENDL; - return TRUE; - } - - LLViewerObject *selected_object = selectNode->getObject(); - if (!selected_object) - { - // somehow we lost the object! - LL_WARNS() << "Translate manip lost the object, no selected object" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; - } - - // Compute unit vectors for arrow hit and a plane through that vector - BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis); - getManipNormal(selected_object, mManipPart, mManipNormal); - - //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal()); - // TomY: The above should (?) be identical to the below - LLVector3 select_center_agent = getPivotPoint(); - mSubdivisions = getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale()); - - // if we clicked on a planar manipulator, recenter mouse cursor - if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE) - { - LLCoordGL mouse_pos; - if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(select_center_agent, mouse_pos)) - { - // mouse_pos may be nonsense - LL_WARNS() << "Failed to project object center to screen" << LL_ENDL; - } - else if (gSavedSettings.getBOOL("SnapToMouseCursor")) - { - LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY); - x = mouse_pos.mX; - y = mouse_pos.mY; - } - } - - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); - getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal); - mDragSelectionStartGlobal = object_start_global; - mCopyMadeThisDrag = FALSE; - - // Route future Mouse messages here preemptively. (Release on mouse up.) - setMouseCapture( TRUE ); - - return TRUE; + BOOL can_move = canAffectSelection(); + if (!can_move) + { + return FALSE; + } + + highlightManipulators(x, y); + S32 hit_part = mHighlightedPart; + + if( (hit_part != LL_X_ARROW) && + (hit_part != LL_Y_ARROW) && + (hit_part != LL_Z_ARROW) && + (hit_part != LL_YZ_PLANE) && + (hit_part != LL_XZ_PLANE) && + (hit_part != LL_XY_PLANE) ) + { + return TRUE; + } + + mHelpTextTimer.reset(); + sNumTimesHelpTextShown++; + + LLSelectMgr::getInstance()->getGrid(mGridOrigin, mGridRotation, mGridScale); + + LLSelectMgr::getInstance()->enableSilhouette(FALSE); + + // we just started a drag, so save initial object positions + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE); + + mManipPart = (EManipPart)hit_part; + mMouseDownX = x; + mMouseDownY = y; + mMouseOutsideSlop = FALSE; + + LLVector3 axis; + + LLSelectNode *selectNode = mObjectSelection->getFirstMoveableNode(TRUE); + + if (!selectNode) + { + // didn't find the object in our selection...oh well + LL_WARNS() << "Trying to translate an unselected object" << LL_ENDL; + return TRUE; + } + + LLViewerObject *selected_object = selectNode->getObject(); + if (!selected_object) + { + // somehow we lost the object! + LL_WARNS() << "Translate manip lost the object, no selected object" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; + } + + // Compute unit vectors for arrow hit and a plane through that vector + BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis); + getManipNormal(selected_object, mManipPart, mManipNormal); + + //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal()); + // TomY: The above should (?) be identical to the below + LLVector3 select_center_agent = getPivotPoint(); + mSubdivisions = getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale()); + + // if we clicked on a planar manipulator, recenter mouse cursor + if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE) + { + LLCoordGL mouse_pos; + if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(select_center_agent, mouse_pos)) + { + // mouse_pos may be nonsense + LL_WARNS() << "Failed to project object center to screen" << LL_ENDL; + } + else if (gSavedSettings.getBOOL("SnapToMouseCursor")) + { + LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY); + x = mouse_pos.mX; + y = mouse_pos.mY; + } + } + + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); + getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal); + mDragSelectionStartGlobal = object_start_global; + mCopyMadeThisDrag = FALSE; + + // Route future Mouse messages here preemptively. (Release on mouse up.) + setMouseCapture( TRUE ); + + return TRUE; } BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) { - // Translation tool only works if mouse button is down. - // Bail out if mouse not down. - if( !hasMouseCapture() ) - { - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (inactive)" << LL_ENDL; - // Always show cursor - // gViewerWindow->setCursor(UI_CURSOR_ARROW); - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - - highlightManipulators(x, y); - return TRUE; - } - - // Handle auto-rotation if necessary. - LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD; - const S32 ROTATE_H_MARGIN = world_rect.getWidth() / 20; - const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped; - BOOL rotated = FALSE; - - // ...build mode moves camera about focus point - if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) - { - if (x < ROTATE_H_MARGIN) - { - gAgentCamera.cameraOrbitAround(rotate_angle); - rotated = TRUE; - } - else if (x > world_rect.getWidth() - ROTATE_H_MARGIN) - { - gAgentCamera.cameraOrbitAround(-rotate_angle); - rotated = TRUE; - } - } - - // Suppress processing if mouse hasn't actually moved. - // This may cause problems if the camera moves outside of the - // rotation above. - if( x == mLastHoverMouseX && y == mLastHoverMouseY && !rotated) - { - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse unmoved)" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; - } - mLastHoverMouseX = x; - mLastHoverMouseY = y; - - // Suppress if mouse hasn't moved past the initial slop region - // Reset once we start moving - if( !mMouseOutsideSlop ) - { - if (abs(mMouseDownX - x) < MOUSE_DRAG_SLOP && abs(mMouseDownY - y) < MOUSE_DRAG_SLOP ) - { - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse inside slop)" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; - } - else - { - // ...just went outside the slop region - mMouseOutsideSlop = TRUE; - // If holding down shift, leave behind a copy. - if (mask == MASK_COPY) - { - // ...we're trying to make a copy - LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); - mCopyMadeThisDrag = TRUE; - - // When we make the copy, we don't want to do any other processing. - // If so, the object will also be moved, and the copy will be offset. - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (made copy)" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - } - } - } - - // Throttle updates to 10 per second. - - LLVector3 axis_f; - LLVector3d axis_d; - - // pick the first object to constrain to grid w/ common origin - // this is so we don't screw up groups - LLSelectNode* selectNode = mObjectSelection->getFirstMoveableNode(TRUE); - if (!selectNode) - { - // somehow we lost the object! - LL_WARNS() << "Translate manip lost the object, no selectNode" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; - } - - LLViewerObject* object = selectNode->getObject(); - if (!object) - { - // somehow we lost the object! - LL_WARNS() << "Translate manip lost the object, no object in selectNode" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; - } - - // Compute unit vectors for arrow hit and a plane through that vector - BOOL axis_exists = getManipAxis(object, mManipPart, axis_f); // TODO: move this - - axis_d.setVec(axis_f); - - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); - - mSubdivisions = getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale()); - - // Project the cursor onto that plane - LLVector3d relative_move; - getMousePointOnPlaneGlobal(relative_move, x, y, current_pos_global, mManipNormal);\ - relative_move -= mDragCursorStartGlobal; - - // You can't move more than some distance from your original mousedown point. - if (gSavedSettings.getBOOL("LimitDragDistance")) - { - F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); - - if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) - { - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (too far)" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); - return TRUE; - } - } - - F64 axis_magnitude = relative_move * axis_d; // dot product - LLVector3d cursor_point_snap_line; - - F64 off_axis_magnitude; - - getMousePointOnPlaneGlobal(cursor_point_snap_line, x, y, current_pos_global, mSnapOffsetAxis % axis_f); - off_axis_magnitude = axis_exists ? llabs((cursor_point_snap_line - current_pos_global) * LLVector3d(mSnapOffsetAxis)) : 0.f; - - if (gSavedSettings.getBOOL("SnapEnabled")) - { - if (off_axis_magnitude > mSnapOffsetMeters) - { - mInSnapRegime = TRUE; - LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line); - - F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f; - - F32 snap_dist = getMinGridScale() / (2.f * mSubdivisions); - F32 relative_snap_dist = fmodf(llabs(cursor_grid_dist) + snap_dist, getMinGridScale() / mSubdivisions); - if (relative_snap_dist < snap_dist * 2.f) - { - if (cursor_grid_dist > 0.f) - { - cursor_grid_dist -= relative_snap_dist - snap_dist; - } - else - { - cursor_grid_dist += relative_snap_dist - snap_dist; - } - } - - F32 object_start_on_axis = (gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal) - mGridOrigin) * axis_f; - axis_magnitude = cursor_grid_dist - object_start_on_axis; - } - else if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE) - { - // subtract offset from object center - LLVector3d cursor_point_global; - getMousePointOnPlaneGlobal( cursor_point_global, x, y, current_pos_global, mManipNormal ); - cursor_point_global -= (mDragCursorStartGlobal - mDragSelectionStartGlobal); - - // snap to planar grid - LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global); - LLVector3 camera_plane_projection = LLViewerCamera::getInstance()->getAtAxis(); - camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal); - camera_plane_projection.normVec(); - LLVector3 camera_projected_dir = camera_plane_projection; - camera_plane_projection.rotVec(~mGridRotation); - camera_plane_projection.scaleVec(mGridScale); - camera_plane_projection.abs(); - F32 max_grid_scale; - if (camera_plane_projection.mV[VX] > camera_plane_projection.mV[VY] && - camera_plane_projection.mV[VX] > camera_plane_projection.mV[VZ]) - { - max_grid_scale = mGridScale.mV[VX]; - } - else if (camera_plane_projection.mV[VY] > camera_plane_projection.mV[VZ]) - { - max_grid_scale = mGridScale.mV[VY]; - } - else - { - max_grid_scale = mGridScale.mV[VZ]; - } - - F32 num_subdivisions = getSubdivisionLevel(getPivotPoint(), camera_projected_dir, max_grid_scale); - - F32 grid_scale_a; - F32 grid_scale_b; - LLVector3 cursor_point_grid = (cursor_point_agent - mGridOrigin) * ~mGridRotation; - - switch (mManipPart) - { - case LL_YZ_PLANE: - grid_scale_a = mGridScale.mV[VY] / num_subdivisions; - grid_scale_b = mGridScale.mV[VZ] / num_subdivisions; - cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; - cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; - break; - case LL_XZ_PLANE: - grid_scale_a = mGridScale.mV[VX] / num_subdivisions; - grid_scale_b = mGridScale.mV[VZ] / num_subdivisions; - cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; - cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; - break; - case LL_XY_PLANE: - grid_scale_a = mGridScale.mV[VX] / num_subdivisions; - grid_scale_b = mGridScale.mV[VY] / num_subdivisions; - cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; - cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; - break; - default: - break; - } - cursor_point_agent = (cursor_point_grid * mGridRotation) + mGridOrigin; - relative_move.setVec(cursor_point_agent - gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal)); - mInSnapRegime = TRUE; - } - else - { - mInSnapRegime = FALSE; - } - } - else - { - mInSnapRegime = FALSE; - } - - // Clamp to arrow direction - // *FIX: does this apply anymore? - if (!axis_exists) - { - axis_magnitude = relative_move.normVec(); - axis_d.setVec(relative_move); - axis_d.normVec(); - axis_f.setVec(axis_d); - } - - LLVector3d clamped_relative_move = axis_magnitude * axis_d; // scalar multiply - LLVector3 clamped_relative_move_f = (F32)axis_magnitude * axis_f; // scalar multiply - + // Translation tool only works if mouse button is down. + // Bail out if mouse not down. + if( !hasMouseCapture() ) + { + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (inactive)" << LL_ENDL; + // Always show cursor + // gViewerWindow->setCursor(UI_CURSOR_ARROW); + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + + highlightManipulators(x, y); + return TRUE; + } + + // Handle auto-rotation if necessary. + LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); + const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD; + const S32 ROTATE_H_MARGIN = world_rect.getWidth() / 20; + const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped; + BOOL rotated = FALSE; + + // ...build mode moves camera about focus point + if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) + { + if (x < ROTATE_H_MARGIN) + { + gAgentCamera.cameraOrbitAround(rotate_angle); + rotated = TRUE; + } + else if (x > world_rect.getWidth() - ROTATE_H_MARGIN) + { + gAgentCamera.cameraOrbitAround(-rotate_angle); + rotated = TRUE; + } + } + + // Suppress processing if mouse hasn't actually moved. + // This may cause problems if the camera moves outside of the + // rotation above. + if( x == mLastHoverMouseX && y == mLastHoverMouseY && !rotated) + { + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse unmoved)" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; + } + mLastHoverMouseX = x; + mLastHoverMouseY = y; + + // Suppress if mouse hasn't moved past the initial slop region + // Reset once we start moving + if( !mMouseOutsideSlop ) + { + if (abs(mMouseDownX - x) < MOUSE_DRAG_SLOP && abs(mMouseDownY - y) < MOUSE_DRAG_SLOP ) + { + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse inside slop)" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; + } + else + { + // ...just went outside the slop region + mMouseOutsideSlop = TRUE; + // If holding down shift, leave behind a copy. + if (mask == MASK_COPY) + { + // ...we're trying to make a copy + LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); + mCopyMadeThisDrag = TRUE; + + // When we make the copy, we don't want to do any other processing. + // If so, the object will also be moved, and the copy will be offset. + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (made copy)" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + } + } + } + + // Throttle updates to 10 per second. + + LLVector3 axis_f; + LLVector3d axis_d; + + // pick the first object to constrain to grid w/ common origin + // this is so we don't screw up groups + LLSelectNode* selectNode = mObjectSelection->getFirstMoveableNode(TRUE); + if (!selectNode) + { + // somehow we lost the object! + LL_WARNS() << "Translate manip lost the object, no selectNode" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; + } + + LLViewerObject* object = selectNode->getObject(); + if (!object) + { + // somehow we lost the object! + LL_WARNS() << "Translate manip lost the object, no object in selectNode" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; + } + + // Compute unit vectors for arrow hit and a plane through that vector + BOOL axis_exists = getManipAxis(object, mManipPart, axis_f); // TODO: move this + + axis_d.setVec(axis_f); + + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); + + mSubdivisions = getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale()); + + // Project the cursor onto that plane + LLVector3d relative_move; + getMousePointOnPlaneGlobal(relative_move, x, y, current_pos_global, mManipNormal);\ + relative_move -= mDragCursorStartGlobal; + + // You can't move more than some distance from your original mousedown point. + if (gSavedSettings.getBOOL("LimitDragDistance")) + { + F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); + + if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) + { + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (too far)" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); + return TRUE; + } + } + + F64 axis_magnitude = relative_move * axis_d; // dot product + LLVector3d cursor_point_snap_line; + + F64 off_axis_magnitude; + + getMousePointOnPlaneGlobal(cursor_point_snap_line, x, y, current_pos_global, mSnapOffsetAxis % axis_f); + off_axis_magnitude = axis_exists ? llabs((cursor_point_snap_line - current_pos_global) * LLVector3d(mSnapOffsetAxis)) : 0.f; + + if (gSavedSettings.getBOOL("SnapEnabled")) + { + if (off_axis_magnitude > mSnapOffsetMeters) + { + mInSnapRegime = TRUE; + LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line); + + F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f; + + F32 snap_dist = getMinGridScale() / (2.f * mSubdivisions); + F32 relative_snap_dist = fmodf(llabs(cursor_grid_dist) + snap_dist, getMinGridScale() / mSubdivisions); + if (relative_snap_dist < snap_dist * 2.f) + { + if (cursor_grid_dist > 0.f) + { + cursor_grid_dist -= relative_snap_dist - snap_dist; + } + else + { + cursor_grid_dist += relative_snap_dist - snap_dist; + } + } + + F32 object_start_on_axis = (gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal) - mGridOrigin) * axis_f; + axis_magnitude = cursor_grid_dist - object_start_on_axis; + } + else if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE) + { + // subtract offset from object center + LLVector3d cursor_point_global; + getMousePointOnPlaneGlobal( cursor_point_global, x, y, current_pos_global, mManipNormal ); + cursor_point_global -= (mDragCursorStartGlobal - mDragSelectionStartGlobal); + + // snap to planar grid + LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global); + LLVector3 camera_plane_projection = LLViewerCamera::getInstance()->getAtAxis(); + camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal); + camera_plane_projection.normVec(); + LLVector3 camera_projected_dir = camera_plane_projection; + camera_plane_projection.rotVec(~mGridRotation); + camera_plane_projection.scaleVec(mGridScale); + camera_plane_projection.abs(); + F32 max_grid_scale; + if (camera_plane_projection.mV[VX] > camera_plane_projection.mV[VY] && + camera_plane_projection.mV[VX] > camera_plane_projection.mV[VZ]) + { + max_grid_scale = mGridScale.mV[VX]; + } + else if (camera_plane_projection.mV[VY] > camera_plane_projection.mV[VZ]) + { + max_grid_scale = mGridScale.mV[VY]; + } + else + { + max_grid_scale = mGridScale.mV[VZ]; + } + + F32 num_subdivisions = getSubdivisionLevel(getPivotPoint(), camera_projected_dir, max_grid_scale); + + F32 grid_scale_a; + F32 grid_scale_b; + LLVector3 cursor_point_grid = (cursor_point_agent - mGridOrigin) * ~mGridRotation; + + switch (mManipPart) + { + case LL_YZ_PLANE: + grid_scale_a = mGridScale.mV[VY] / num_subdivisions; + grid_scale_b = mGridScale.mV[VZ] / num_subdivisions; + cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; + cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; + break; + case LL_XZ_PLANE: + grid_scale_a = mGridScale.mV[VX] / num_subdivisions; + grid_scale_b = mGridScale.mV[VZ] / num_subdivisions; + cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; + cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; + break; + case LL_XY_PLANE: + grid_scale_a = mGridScale.mV[VX] / num_subdivisions; + grid_scale_b = mGridScale.mV[VY] / num_subdivisions; + cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f; + cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f; + break; + default: + break; + } + cursor_point_agent = (cursor_point_grid * mGridRotation) + mGridOrigin; + relative_move.setVec(cursor_point_agent - gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal)); + mInSnapRegime = TRUE; + } + else + { + mInSnapRegime = FALSE; + } + } + else + { + mInSnapRegime = FALSE; + } + + // Clamp to arrow direction + // *FIX: does this apply anymore? + if (!axis_exists) + { + axis_magnitude = relative_move.normVec(); + axis_d.setVec(relative_move); + axis_d.normVec(); + axis_f.setVec(axis_d); + } + + LLVector3d clamped_relative_move = axis_magnitude * axis_d; // scalar multiply + LLVector3 clamped_relative_move_f = (F32)axis_magnitude * axis_f; // scalar multiply + for (LLObjectSelection::iterator iter = mObjectSelection->begin(); iter != mObjectSelection->end(); iter++) { @@ -775,1536 +775,1536 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } - LLSelectMgr::getInstance()->updateSelectionCenter(); - gAgentCamera.clearFocusObject(); - dialog_refresh_all(); // ??? is this necessary? + LLSelectMgr::getInstance()->updateSelectionCenter(); + gAgentCamera.clearFocusObject(); + dialog_refresh_all(); // ??? is this necessary? - LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (active)" << LL_ENDL; - gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); - return TRUE; + LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (active)" << LL_ENDL; + gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE); + return TRUE; } void LLManipTranslate::highlightManipulators(S32 x, S32 y) { - mHighlightedPart = LL_NO_PART; - - if (!mObjectSelection->getObjectCount()) - { - return; - } - - //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection(); - LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview(); - - LLVector3 object_position = getPivotPoint(); - - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - - LLVector3 relative_camera_dir; - - LLMatrix4 transform; - - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation; - LLVector4 translation(object_position); - transform.initRotTrans(grid_rotation, translation); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - transform *= cfr; - LLMatrix4 window_scale; - F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; - window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f), - LLQuaternion::DEFAULT, - LLVector3::zero); - transform *= window_scale; - } - else - { - relative_camera_dir = (object_position - LLViewerCamera::getInstance()->getOrigin()) * ~grid_rotation; - relative_camera_dir.normVec(); - - transform.initRotTrans(grid_rotation, LLVector4(object_position)); - transform *= modelView; - transform *= projMatrix; - } - - S32 numManips = 0; - - // edges - mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f); - mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f); - - mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 1.f); - mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 1.f); - - mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 1.f); - mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 1.f); - - mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f); - mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f); - - mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 1.f); - mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 1.f); - - mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 1.f); - mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 1.f); - - S32 num_arrow_manips = numManips; - - // planar manipulators - BOOL planar_manip_yz_visible = FALSE; - BOOL planar_manip_xz_visible = FALSE; - BOOL planar_manip_xy_visible = FALSE; - - mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - if (llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - planar_manip_yz_visible = TRUE; - } - - mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - if (llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - planar_manip_xz_visible = TRUE; - } - - mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, 1.f); - mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); - if (llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - planar_manip_xy_visible = TRUE; - } - - // Project up to 9 manipulators to screen space 2*X, 2*Y, 2*Z, 3*planes - std::vector projected_manipulators; - projected_manipulators.reserve(9); - - for (S32 i = 0; i < num_arrow_manips; i+= 2) - { - LLVector4 projected_start = mManipulatorVertices[i] * transform; - projected_start = projected_start * (1.f / projected_start.mV[VW]); - - LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; - projected_end = projected_end * (1.f / projected_end.mV[VW]); - - ManipulatorHandle projected_manip( - LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), - LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), - MANIPULATOR_IDS[i / 2], - 10.f); // 10 pixel hotspot for arrows - projected_manipulators.push_back(projected_manip); - } - - if (planar_manip_yz_visible) - { - S32 i = num_arrow_manips; - LLVector4 projected_start = mManipulatorVertices[i] * transform; - projected_start = projected_start * (1.f / projected_start.mV[VW]); - - LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; - projected_end = projected_end * (1.f / projected_end.mV[VW]); - - ManipulatorHandle projected_manip( - LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), - LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), - MANIPULATOR_IDS[i / 2], - 20.f); // 20 pixels for planar manipulators - projected_manipulators.push_back(projected_manip); - } - - if (planar_manip_xz_visible) - { - S32 i = num_arrow_manips + 2; - LLVector4 projected_start = mManipulatorVertices[i] * transform; - projected_start = projected_start * (1.f / projected_start.mV[VW]); - - LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; - projected_end = projected_end * (1.f / projected_end.mV[VW]); - - ManipulatorHandle projected_manip( - LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), - LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), - MANIPULATOR_IDS[i / 2], - 20.f); // 20 pixels for planar manipulators - projected_manipulators.push_back(projected_manip); - } - - if (planar_manip_xy_visible) - { - S32 i = num_arrow_manips + 4; - LLVector4 projected_start = mManipulatorVertices[i] * transform; - projected_start = projected_start * (1.f / projected_start.mV[VW]); - - LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; - projected_end = projected_end * (1.f / projected_end.mV[VW]); - - ManipulatorHandle projected_manip( - LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), - LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), - MANIPULATOR_IDS[i / 2], - 20.f); // 20 pixels for planar manipulators - projected_manipulators.push_back(projected_manip); - } - - LLVector2 manip_start_2d; - LLVector2 manip_end_2d; - LLVector2 manip_dir; - LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled(); - F32 half_width = (F32)world_view_rect.getWidth() / 2.f; - F32 half_height = (F32)world_view_rect.getHeight() / 2.f; - LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); - LLVector2 mouse_delta; - - // Keep order consistent with insertion via stable_sort - std::stable_sort( projected_manipulators.begin(), - projected_manipulators.end(), - ClosestToCamera() ); - - std::vector::iterator it = projected_manipulators.begin(); - for ( ; it != projected_manipulators.end(); ++it) - { - ManipulatorHandle& manipulator = *it; - { - manip_start_2d.setVec(manipulator.mStartPosition.mV[VX] * half_width, manipulator.mStartPosition.mV[VY] * half_height); - manip_end_2d.setVec(manipulator.mEndPosition.mV[VX] * half_width, manipulator.mEndPosition.mV[VY] * half_height); - manip_dir = manip_end_2d - manip_start_2d; - - mouse_delta = mousePos - manip_start_2d; - - F32 manip_length = manip_dir.normVec(); - - F32 mouse_pos_manip = mouse_delta * manip_dir; - F32 mouse_dist_manip_squared = mouse_delta.magVecSquared() - (mouse_pos_manip * mouse_pos_manip); - - if (mouse_pos_manip > 0.f && - mouse_pos_manip < manip_length && - mouse_dist_manip_squared < manipulator.mHotSpotRadius * manipulator.mHotSpotRadius) - { - mHighlightedPart = manipulator.mManipID; - break; - } - } - } -} + mHighlightedPart = LL_NO_PART; -F32 LLManipTranslate::getMinGridScale() -{ - F32 scale; - switch (mManipPart) - { - case LL_NO_PART: - default: - scale = 1.f; - break; - case LL_X_ARROW: - scale = mGridScale.mV[VX]; - break; - case LL_Y_ARROW: - scale = mGridScale.mV[VY]; - break; - case LL_Z_ARROW: - scale = mGridScale.mV[VZ]; - break; - case LL_YZ_PLANE: - scale = llmin(mGridScale.mV[VY], mGridScale.mV[VZ]); - break; - case LL_XZ_PLANE: - scale = llmin(mGridScale.mV[VX], mGridScale.mV[VZ]); - break; - case LL_XY_PLANE: - scale = llmin(mGridScale.mV[VX], mGridScale.mV[VY]); - break; - } - - return scale; -} + if (!mObjectSelection->getObjectCount()) + { + return; + } + //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection(); + LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview(); -BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask) -{ - // first, perform normal processing in case this was a quick-click - handleHover(x, y, mask); - - if(hasMouseCapture()) - { - // make sure arrow colors go back to normal - mManipPart = LL_NO_PART; - LLSelectMgr::getInstance()->enableSilhouette(TRUE); - - // Might have missed last update due to UPDATE_DELAY timing. - LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_POSITION ); - - mInSnapRegime = FALSE; - LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); - } - - return LLManip::handleMouseUp(x, y, mask); -} + LLVector3 object_position = getPivotPoint(); + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; -void LLManipTranslate::render() -{ - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - F32 zoom = gAgentCamera.mHUDCurZoom; - gGL.scalef(zoom, zoom, zoom); - } - { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - renderGuidelines(); - } - { - //LLGLDisable gls_stencil(GL_STENCIL_TEST); - renderTranslationHandles(); - renderSnapGuides(); - } - gGL.popMatrix(); - - renderText(); -} + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); -void LLManipTranslate::renderSnapGuides() -{ - if (!gSavedSettings.getBOOL("SnapEnabled")) - { - return; - } - - F32 max_subdivisions = sGridMaxSubdivisionLevel;//(F32)gSavedSettings.getS32("GridSubdivision"); - F32 line_alpha = gSavedSettings.getF32("GridOpacity"); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest gls_depth(GL_TRUE); - LLGLDisable gls_cull(GL_CULL_FACE); - LLVector3 translate_axis; - - if (mManipPart == LL_NO_PART) - { - return; - } - - LLSelectNode *first_node = mObjectSelection->getFirstMoveableNode(TRUE); - if (!first_node) - { - return; - } - - updateGridSettings(); - - F32 smallest_grid_unit_scale = getMinGridScale() / max_subdivisions; - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); - LLVector3 selection_center = getPivotPoint(); - - LLViewerObject *first_object = first_node->getObject(); - - //pick appropriate projection plane for snap rulers according to relative camera position - if (mManipPart >= LL_X_ARROW && mManipPart <= LL_Z_ARROW) - { - LLVector3 normal; - LLColor4 inner_color; - LLManip::EManipPart temp_manip = mManipPart; - switch (mManipPart) - { - case LL_X_ARROW: - normal.setVec(1,0,0); - inner_color.setVec(0,1,1,line_alpha); - mManipPart = LL_YZ_PLANE; - break; - case LL_Y_ARROW: - normal.setVec(0,1,0); - inner_color.setVec(1,0,1,line_alpha); - mManipPart = LL_XZ_PLANE; - break; - case LL_Z_ARROW: - normal.setVec(0,0,1); - inner_color.setVec(1,1,0,line_alpha); - mManipPart = LL_XY_PLANE; - break; - default: - break; - } - - highlightIntersection(normal, selection_center, grid_rotation, inner_color); - mManipPart = temp_manip; - getManipAxis(first_object, mManipPart, translate_axis); - - LLVector3 at_axis_abs; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - at_axis_abs = LLVector3::x_axis * ~grid_rotation; - } - else - { - at_axis_abs = saved_selection_center - LLViewerCamera::getInstance()->getOrigin(); - at_axis_abs.normVec(); - - at_axis_abs = at_axis_abs * ~grid_rotation; - } - at_axis_abs.abs(); - - if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY] && at_axis_abs.mV[VX] > at_axis_abs.mV[VZ]) - { - if (mManipPart == LL_Y_ARROW) - { - mSnapOffsetAxis = LLVector3::z_axis; - } - else if (mManipPart == LL_Z_ARROW) - { - mSnapOffsetAxis = LLVector3::y_axis; - } - else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ]) - { - mSnapOffsetAxis = LLVector3::z_axis; - } - else - { - mSnapOffsetAxis = LLVector3::y_axis; - } - } - else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ]) - { - if (mManipPart == LL_X_ARROW) - { - mSnapOffsetAxis = LLVector3::z_axis; - } - else if (mManipPart == LL_Z_ARROW) - { - mSnapOffsetAxis = LLVector3::x_axis; - } - else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VZ]) - { - mSnapOffsetAxis = LLVector3::z_axis; - } - else - { - mSnapOffsetAxis = LLVector3::x_axis; - } - } - else - { - if (mManipPart == LL_X_ARROW) - { - mSnapOffsetAxis = LLVector3::y_axis; - } - else if (mManipPart == LL_Y_ARROW) - { - mSnapOffsetAxis = LLVector3::x_axis; - } - else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY]) - { - mSnapOffsetAxis = LLVector3::y_axis; - } - else - { - mSnapOffsetAxis = LLVector3::x_axis; - } - } - - mSnapOffsetAxis = mSnapOffsetAxis * grid_rotation; - - F32 guide_size_meters; - - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - guide_size_meters = 1.f / gAgentCamera.mHUDCurZoom; - mSnapOffsetMeters = mArrowLengthMeters * 1.5f; - } - else - { - LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin(); - F32 current_range = cam_to_selection.normVec(); - guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio(); - - F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians - F32 offset_at_camera = tan(apparent_angle) * 1.5f; - F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstance()->getOrigin()); - mSnapOffsetMeters = range * offset_at_camera; - } - - LLVector3 tick_start; - LLVector3 tick_end; - - // how far away from grid origin is the selection along the axis of translation? - F32 dist_grid_axis = (selection_center - mGridOrigin) * translate_axis; - // find distance to nearest smallest grid unit - F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale); - // how many smallest grid units are we away from largest grid scale? - S32 sub_div_offset = ll_round(fmodf(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale); - S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale)); - - LLGLDepthTest gls_depth(GL_FALSE); - - for (S32 pass = 0; pass < 3; pass++) - { - LLColor4 line_color = setupSnapGuideRenderPass(pass); - LLGLDepthTest gls_depth(pass != 1); - - gGL.begin(LLRender::LINES); - { - LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); - LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); - LLVector3 line_mid = (line_start + line_end) * 0.5f; - - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - gGL.vertex3fv(line_start.mV); - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - gGL.vertex3fv(line_mid.mV); - gGL.vertex3fv(line_mid.mV); - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - gGL.vertex3fv(line_end.mV); - - line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f)); - line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f)); - line_mid = (line_start + line_end) * 0.5f; - - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - gGL.vertex3fv(line_start.mV); - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - gGL.vertex3fv(line_mid.mV); - gGL.vertex3fv(line_mid.mV); - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - gGL.vertex3fv(line_end.mV); - - for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++) - { - tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit)); - - //No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208) - //F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale()); - /*if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f) - { - continue; - }*/ - - // add in off-axis offset - tick_start += (mSnapOffsetAxis * mSnapOffsetMeters); - - F32 tick_scale = 1.f; - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) - { - if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f) - { - break; - } - tick_scale *= 0.7f; - } - -// S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side; -// F32 alpha = line_alpha * (1.f - (0.8f * ((F32)llabs(i) / (F32)num_ticks_to_fade))); - - tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); - - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - gGL.vertex3fv(tick_start.mV); - gGL.vertex3fv(tick_end.mV); - - tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + - (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit)); - tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); - - gGL.vertex3fv(tick_start.mV); - gGL.vertex3fv(tick_end.mV); - } - } - gGL.end(); - - if (mInSnapRegime) - { - LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters; - LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters; - - gGL.begin(LLRender::LINES); - { - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - - gGL.vertex3fv(line_start.mV); - gGL.vertex3fv(line_end.mV); - } - gGL.end(); - - // draw snap guide arrow - gGL.begin(LLRender::TRIANGLES); - { - gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - - LLVector3 arrow_dir; - LLVector3 arrow_span = translate_axis; - - arrow_dir = -mSnapOffsetAxis; - gGL.vertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); - gGL.vertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - gGL.vertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - - arrow_dir = mSnapOffsetAxis; - gGL.vertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); - gGL.vertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - gGL.vertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - } - gGL.end(); - } - } - - sub_div_offset = ll_round(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale); - - LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstance()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstance()->getUpAxis())); - screen_translate_axis.normVec(); - - S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing); - - // render tickmark values - for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++) - { - LLVector3 tick_pos = selection_center + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)); - F32 alpha = line_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side))); - - F32 tick_scale = 1.f; - for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) - { - if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f) - { - break; - } - tick_scale *= 0.7f; - } - - if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / getSubdivisionLevel(tick_pos, translate_axis, getMinGridScale(), tick_label_spacing))) == 0.f) - { - F32 snap_offset_meters; - - if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) - { - snap_offset_meters = mSnapOffsetMeters; - } - else - { - snap_offset_meters = -mSnapOffsetMeters; - } - LLVector3 text_origin = selection_center + - (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)) + - (mSnapOffsetAxis * snap_offset_meters * (1.f + tick_scale)); - - LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation; - F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale(); - EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); - F32 text_highlight = 0.8f; - if(i - ll_round(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime) - { - text_highlight = 1.f; - } - - if (grid_mode == GRID_MODE_WORLD) - { - // rescale units to meters from multiple of grid scale - offset_val *= 2.f * grid_scale[ARROW_TO_AXIS[mManipPart]]; - renderTickValue(text_origin, offset_val, std::string("m"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); - } - else - { - renderTickValue(text_origin, offset_val, std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); - } - } - } - if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) - { - // render helpful text - if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) - { - F32 snap_offset_meters_up; - if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) - { - snap_offset_meters_up = mSnapOffsetMeters; - } - else - { - snap_offset_meters_up = -mSnapOffsetMeters; - } - - LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); - - LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis); - const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); - - std::string help_text = LLTrans::getString("manip_hint1"); - LLColor4 help_text_color = LLColor4::white; - help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); - help_text = LLTrans::getString("manip_hint2"); - help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f; - hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); - } - } - } - else - { - // render gridlines for planar snapping - - F32 u = 0, v = 0; - LLColor4 inner_color; - LLVector3 normal; - LLVector3 grid_center = selection_center - grid_origin; - F32 usc = 1; - F32 vsc = 1; - - grid_center *= ~grid_rotation; - - switch (mManipPart) - { - case LL_YZ_PLANE: - u = grid_center.mV[VY]; - v = grid_center.mV[VZ]; - usc = grid_scale.mV[VY]; - vsc = grid_scale.mV[VZ]; - inner_color.setVec(0,1,1,line_alpha); - normal.setVec(1,0,0); - break; - case LL_XZ_PLANE: - u = grid_center.mV[VX]; - v = grid_center.mV[VZ]; - usc = grid_scale.mV[VX]; - vsc = grid_scale.mV[VZ]; - inner_color.setVec(1,0,1,line_alpha); - normal.setVec(0,1,0); - break; - case LL_XY_PLANE: - u = grid_center.mV[VX]; - v = grid_center.mV[VY]; - usc = grid_scale.mV[VX]; - vsc = grid_scale.mV[VY]; - inner_color.setVec(1,1,0,line_alpha); - normal.setVec(0,0,1); - break; - default: - break; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - highlightIntersection(normal, selection_center, grid_rotation, inner_color); - - gGL.pushMatrix(); - - F32 x,y,z,angle_radians; - grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - F32 sz = mGridSizeMeters; - F32 tiles = sz; - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.pushMatrix(); - usc = 1.0f/usc; - vsc = 1.0f/vsc; - - while (usc > vsc*4.0f) - { - usc *= 0.5f; - } - while (vsc > usc * 4.0f) - { - vsc *= 0.5f; - } - - gGL.scalef(usc, vsc, 1.0f); - gGL.translatef(u, v, 0); - - float a = line_alpha; - - { - //draw grid behind objects - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - { - //LLGLDisable stencil(GL_STENCIL_TEST); - { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName()); - gGL.flush(); - gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f); - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - { - //draw black overlay - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f); - - //draw grid top - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName()); - renderGrid(u,v,tiles,1,1,1,a); - - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } - - { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - renderGuidelines(); - } - - { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); - gGL.flush(); - - switch (mManipPart) - { - case LL_YZ_PLANE: - renderGuidelines(FALSE, TRUE, TRUE); - break; - case LL_XZ_PLANE: - renderGuidelines(TRUE, FALSE, TRUE); - break; - case LL_XY_PLANE: - renderGuidelines(TRUE, TRUE, FALSE); - break; - default: - break; - } - gGL.flush(); - } - } - } - } -} + LLVector3 relative_camera_dir; -void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F32 a) -{ - F32 d = size*0.5f; - - for (F32 xx = -size-d; xx < size+d; xx += d) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - for (F32 yy = -size-d; yy < size+d; yy += d) - { - float dx, dy, da; - - dx = xx; dy = yy; - da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - gGL.texCoord2f(dx, dy); - renderGridVert(dx,dy,r,g,b,da); - - dx = xx+d; dy = yy; - da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - gGL.texCoord2f(dx, dy); - renderGridVert(dx,dy,r,g,b,da); - - dx = xx; dy = yy+d; - da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - gGL.texCoord2f(dx, dy); - renderGridVert(dx,dy,r,g,b,da); - - dx = xx+d; dy = yy+d; - da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - gGL.texCoord2f(dx, dy); - renderGridVert(dx,dy,r,g,b,da); - } - gGL.end(); - } - - -} + LLMatrix4 transform; -void LLManipTranslate::highlightIntersection(LLVector3 normal, - LLVector3 selection_center, - LLQuaternion grid_rotation, - LLColor4 inner_color) -{ -#if 0 // DEPRECATED - if (!gSavedSettings.getBOOL("GridCrossSections")) - { - return; - } - - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - - static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; - static const U32 num_types = LL_ARRAY_SIZE(types); - - GLuint stencil_mask = 0xFFFFFFFF; - //stencil in volumes - - gGL.flush(); - - if (shader) - { - gClipProgram.bind(); - } - - { - //glStencilMask(stencil_mask); //deprecated - //glClearStencil(1); - //glClear(GL_STENCIL_BUFFER_BIT); - LLGLEnable cull_face(GL_CULL_FACE); - //LLGLEnable stencil(GL_STENCIL_TEST); - LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS); - //glStencilFunc(GL_ALWAYS, 0, stencil_mask); - gGL.setColorMask(false, false); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.diffuseColor4f(1,1,1,1); - - //setup clip plane - normal = normal * grid_rotation; - if (normal * (LLViewerCamera::getInstance()->getOrigin()-selection_center) < 0) - { - normal = -normal; - } - F32 d = -(selection_center * normal); - glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); - - gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); - - static LLStaticHashedString sClipPlane("clip_plane"); - gClipProgram.uniform4fv(sClipPlane, 1, plane.v); - - BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS); - - if (particles) - { - LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - } - if (clouds) - { - LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS); - } - - //stencil in volumes - //glStencilOp(GL_INCR, GL_INCR, GL_INCR); - glCullFace(GL_FRONT); - for (U32 i = 0; i < num_types; i++) - { - gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - - //glStencilOp(GL_DECR, GL_DECR, GL_DECR); - glCullFace(GL_BACK); - for (U32 i = 0; i < num_types; i++) - { - gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - - if (particles) - { - LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - } - if (clouds) - { - LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS); - } - - gGL.setColorMask(true, false); - } - gGL.color4f(1,1,1,1); - - gGL.pushMatrix(); - - F32 x,y,z,angle_radians; - grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - F32 sz = mGridSizeMeters; - F32 tiles = sz; - - if (shader) - { - shader->bind(); - } - - if (shader) - { - shader->bind(); - } - - //draw volume/plane intersections - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_FALSE); - //LLGLEnable stencil(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 0, stencil_mask); - renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f); - } - - glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); - glStencilMask(0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - gGL.popMatrix(); -#endif -} + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation; + LLVector4 translation(object_position); + transform.initRotTrans(grid_rotation, translation); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + transform *= cfr; + LLMatrix4 window_scale; + F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; + window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f), + LLQuaternion::DEFAULT, + LLVector3::zero); + transform *= window_scale; + } + else + { + relative_camera_dir = (object_position - LLViewerCamera::getInstance()->getOrigin()) * ~grid_rotation; + relative_camera_dir.normVec(); -void LLManipTranslate::renderText() -{ - if (mObjectSelection->getRootObjectCount() && !mObjectSelection->isAttachment()) - { - LLVector3 pos = getPivotPoint(); - renderXYZ(pos); - } - else - { - const BOOL children_ok = TRUE; - LLViewerObject* objectp = mObjectSelection->getFirstRootObject(children_ok); - if (objectp) - { - renderXYZ(objectp->getPositionEdit()); - } - } -} + transform.initRotTrans(grid_rotation, LLVector4(object_position)); + transform *= modelView; + transform *= projMatrix; + } -void LLManipTranslate::renderTranslationHandles() -{ - LLVector3 grid_origin; - LLVector3 grid_scale; - LLQuaternion grid_rotation; - LLGLDepthTest gls_depth(GL_FALSE); - - LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); - LLVector3 at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - at_axis = LLVector3::x_axis * ~grid_rotation; - } - else - { - at_axis = LLViewerCamera::getInstance()->getAtAxis() * ~grid_rotation; - } - - if (at_axis.mV[VX] > 0.f) - { - mPlaneManipPositions.mV[VX] = 1.f; - } - else - { - mPlaneManipPositions.mV[VX] = -1.f; - } - - if (at_axis.mV[VY] > 0.f) - { - mPlaneManipPositions.mV[VY] = 1.f; - } - else - { - mPlaneManipPositions.mV[VY] = -1.f; - } - - if (at_axis.mV[VZ] > 0.f) - { - mPlaneManipPositions.mV[VZ] = 1.f; - } - else - { - mPlaneManipPositions.mV[VZ] = -1.f; - } - - LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE); - if (!first_object) return; - - LLVector3 selection_center = getPivotPoint(); - - // Drag handles - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeightRaw(); - mArrowLengthMeters /= gAgentCamera.mHUDCurZoom; - } - else - { - LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent(); - F32 range = dist_vec(camera_pos_agent, selection_center); - F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center); - - // Don't draw handles if you're too far away - if (gSavedSettings.getBOOL("LimitSelectDistance")) - { - if (range_from_agent > gSavedSettings.getF32("MaxSelectDistance")) - { - return; - } - } - - if (range > 0.001f) - { - // range != zero - F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians - mArrowLengthMeters = range * tan(apparent_angle); - } - else - { - // range == zero - mArrowLengthMeters = 1.0f; - } - } - //Assume that UI scale factor is equivalent for X and Y axis - F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX]; - mArrowLengthMeters *= ui_scale_factor; - - mPlaneManipOffsetMeters = mArrowLengthMeters * 1.8f; - mGridSizeMeters = gSavedSettings.getF32("GridDrawSize"); - mConeSize = mArrowLengthMeters / 4.f; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - { - gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); - - F32 angle_radians, x, y, z; - grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - - gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - - LLQuaternion invRotation = grid_rotation; - invRotation.conjQuat(); - - LLVector3 relative_camera_dir; - - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - relative_camera_dir = LLVector3::x_axis * invRotation; - } - else - { - relative_camera_dir = (selection_center - LLViewerCamera::getInstance()->getOrigin()) * invRotation; - } - relative_camera_dir.normVec(); - - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDisable cull_face(GL_CULL_FACE); - - LLColor4 color1; - LLColor4 color2; - - // update manipulator sizes - for (S32 index = 0; index < 3; index++) - { - if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW) - { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - } - else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE) - { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - } - else - { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - } - } - - if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - // render YZ plane manipulator - gGL.pushMatrix(); - gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); - gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters); - gGL.scalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]); - if (mHighlightedPart == LL_YZ_PLANE) - { - color1.setVec(0.f, 1.f, 0.f, 1.f); - color2.setVec(0.f, 0.f, 1.f, 1.f); - } - else - { - color1.setVec(0.f, 1.f, 0.f, 0.6f); - color2.setVec(0.f, 0.f, 1.f, 0.6f); - } - gGL.begin(LLRender::TRIANGLES); - { - gGL.color4fv(color1.mV); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - - gGL.color4fv(color2.mV); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - } - gGL.end(); - - LLUI::setLineWidth(3.0f); - gGL.begin(LLRender::LINES); - { - gGL.color4f(0.f, 0.f, 0.f, 0.3f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); - - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - } - gGL.end(); - LLUI::setLineWidth(1.0f); - gGL.popMatrix(); - } - - if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - // render XZ plane manipulator - gGL.pushMatrix(); - gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); - gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters); - gGL.scalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]); - if (mHighlightedPart == LL_XZ_PLANE) - { - color1.setVec(0.f, 0.f, 1.f, 1.f); - color2.setVec(1.f, 0.f, 0.f, 1.f); - } - else - { - color1.setVec(0.f, 0.f, 1.f, 0.6f); - color2.setVec(1.f, 0.f, 0.f, 0.6f); - } - - gGL.begin(LLRender::TRIANGLES); - { - gGL.color4fv(color1.mV); - gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - - gGL.color4fv(color2.mV); - gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); - gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - } - gGL.end(); - - LLUI::setLineWidth(3.0f); - gGL.begin(LLRender::LINES); - { - gGL.color4f(0.f, 0.f, 0.f, 0.3f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); - gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); - - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - } - gGL.end(); - LLUI::setLineWidth(1.0f); - - gGL.popMatrix(); - } - - if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT) - { - // render XY plane manipulator - gGL.pushMatrix(); - gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); - -/* Y - ^ - v1 - | \ - |<- v0 - | /| \ - v2__v__v3 > X -*/ - LLVector3 v0,v1,v2,v3; -#if 0 - // This should theoretically work but looks off; could be tuned later -SJB - gGL.translatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f); - v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); - v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f); - v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); - v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); -#else - gGL.translatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f); - v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); - v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f); - v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); - v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); -#endif - gGL.scalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]); - if (mHighlightedPart == LL_XY_PLANE) - { - color1.setVec(1.f, 0.f, 0.f, 1.f); - color2.setVec(0.f, 1.f, 0.f, 1.f); - } - else - { - color1.setVec(0.8f, 0.f, 0.f, 0.6f); - color2.setVec(0.f, 0.8f, 0.f, 0.6f); - } - - gGL.begin(LLRender::TRIANGLES); - { - gGL.color4fv(color1.mV); - gGL.vertex3fv(v0.mV); - gGL.vertex3fv(v1.mV); - gGL.vertex3fv(v2.mV); - - gGL.color4fv(color2.mV); - gGL.vertex3fv(v2.mV); - gGL.vertex3fv(v3.mV); - gGL.vertex3fv(v0.mV); - } - gGL.end(); - - LLUI::setLineWidth(3.0f); - gGL.begin(LLRender::LINES); - { - gGL.color4f(0.f, 0.f, 0.f, 0.3f); - LLVector3 v12 = (v1 + v2) * .5f; - gGL.vertex3fv(v0.mV); - gGL.vertex3fv(v12.mV); - gGL.vertex3fv(v12.mV); - gGL.vertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV); - gGL.vertex3fv(v12.mV); - gGL.vertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV); - - LLVector3 v23 = (v2 + v3) * .5f; - gGL.vertex3fv(v0.mV); - gGL.vertex3fv(v23.mV); - gGL.vertex3fv(v23.mV); - gGL.vertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV); - gGL.vertex3fv(v23.mV); - gGL.vertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV); - } - gGL.end(); - LLUI::setLineWidth(1.0f); - - gGL.popMatrix(); - } - } - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Since we draw handles with depth testing off, we need to draw them in the - // proper depth order. - - // Copied from LLDrawable::updateGeometry - LLVector3 pos_agent = first_object->getPositionAgent(); - LLVector3 camera_agent = gAgentCamera.getCameraPositionAgent(); - LLVector3 headPos = pos_agent - camera_agent; - - LLVector3 orientWRTHead = headPos * invRotation; - - // Find nearest vertex - U32 nearest = (orientWRTHead.mV[0] < 0.0f ? 1 : 0) + - (orientWRTHead.mV[1] < 0.0f ? 2 : 0) + - (orientWRTHead.mV[2] < 0.0f ? 4 : 0); - - // opposite faces on Linden cubes: - // 0 & 5 - // 1 & 3 - // 2 & 4 - - // Table of order to draw faces, based on nearest vertex - static U32 face_list[8][NUM_AXES*2] = { - { 2,0,1, 4,5,3 }, // v6 F201 F453 - { 2,0,3, 4,5,1 }, // v7 F203 F451 - { 4,0,1, 2,5,3 }, // v5 F401 F253 - { 4,0,3, 2,5,1 }, // v4 F403 F251 - { 2,5,1, 4,0,3 }, // v2 F251 F403 - { 2,5,3, 4,0,1 }, // v3 F253 F401 - { 4,5,1, 2,0,3 }, // v1 F451 F203 - { 4,5,3, 2,0,1 }, // v0 F453 F201 - }; - static const EManipPart which_arrow[6] = { - LL_Z_ARROW, - LL_X_ARROW, - LL_Y_ARROW, - LL_X_ARROW, - LL_Y_ARROW, - LL_Z_ARROW}; - - // draw arrows for deeper faces first, closer faces last - LLVector3 camera_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - camera_axis = LLVector3::x_axis; - } - else - { - camera_axis.setVec(gAgentCamera.getCameraPositionAgent() - first_object->getPositionAgent()); - } - - for (U32 i = 0; i < NUM_AXES*2; i++) - { - U32 face = face_list[nearest][i]; - - LLVector3 arrow_axis; - getManipAxis(first_object, which_arrow[face], arrow_axis); - - renderArrow(which_arrow[face], - mManipPart, - (face >= 3) ? -mConeSize : mConeSize, - (face >= 3) ? -mArrowLengthMeters : mArrowLengthMeters, - mConeSize, - FALSE); - } - } - } - gGL.popMatrix(); -} + S32 numManips = 0; + // edges + mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f); + mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f); -void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_size, F32 arrow_size, F32 handle_size, BOOL reverse_direction) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLEnable gls_blend(GL_BLEND); - - for (S32 pass = 1; pass <= 2; pass++) - { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER); - gGL.pushMatrix(); - - S32 index = 0; - - index = ARROW_TO_AXIS[which_arrow]; - - // assign a color for this arrow - LLColor4 color; // black - if (which_arrow == selected_arrow || which_arrow == mHighlightedPart) - { - color.mV[index] = (pass == 1) ? 1.f : 0.5f; - } - else if (selected_arrow != LL_NO_PART) - { - color.mV[VALPHA] = 0.f; - } - else - { - color.mV[index] = pass == 1 ? .8f : .35f ; // red, green, or blue - color.mV[VALPHA] = 0.6f; - } - gGL.color4fv( color.mV ); - - LLVector3 vec; - - { - LLUI::setLineWidth(2.0f); - gGL.begin(LLRender::LINES); - vec.mV[index] = box_size; - gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); - - vec.mV[index] = arrow_size; - gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); - gGL.end(); - LLUI::setLineWidth(1.0f); - } - - gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]); - gGL.scalef(handle_size, handle_size, handle_size); - - F32 rot = 0.0f; - LLVector3 axis; - - switch(which_arrow) - { - case LL_X_ARROW: - rot = reverse_direction ? -90.0f : 90.0f; - axis.mV[1] = 1.0f; - break; - case LL_Y_ARROW: - rot = reverse_direction ? 90.0f : -90.0f; - axis.mV[0] = 1.0f; - break; - case LL_Z_ARROW: - rot = reverse_direction ? 180.0f : 0.0f; - axis.mV[0] = 1.0f; - break; - default: - LL_ERRS() << "renderArrow called with bad arrow " << which_arrow << LL_ENDL; - break; - } - - gGL.diffuseColor4fv(color.mV); - gGL.rotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]); - gGL.scalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f); - - gCone.render(); - - gGL.popMatrix(); - } -} + mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 1.f); + mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 1.f); -void LLManipTranslate::renderGridVert(F32 x_trans, F32 y_trans, F32 r, F32 g, F32 b, F32 alpha) -{ - gGL.color4f(r, g, b, alpha); - switch (mManipPart) - { - case LL_YZ_PLANE: - gGL.vertex3f(0, x_trans, y_trans); - break; - case LL_XZ_PLANE: - gGL.vertex3f(x_trans, 0, y_trans); - break; - case LL_XY_PLANE: - gGL.vertex3f(x_trans, y_trans, 0); - break; - default: - gGL.vertex3f(0,0,0); - break; - } + mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 1.f); + mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 1.f); -} + mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f); + mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f); -// virtual -BOOL LLManipTranslate::canAffectSelection() -{ - BOOL can_move = mObjectSelection->getObjectCount() != 0; - if (can_move) - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* objectp) - { - LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); - return objectp->permMove() && !objectp->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - } - } func; - can_move = mObjectSelection->applyToObjects(&func); - } - return can_move; + mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 1.f); + mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 1.f); + + mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 1.f); + mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 1.f); + + S32 num_arrow_manips = numManips; + + // planar manipulators + BOOL planar_manip_yz_visible = FALSE; + BOOL planar_manip_xz_visible = FALSE; + BOOL planar_manip_xy_visible = FALSE; + + mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + if (llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + planar_manip_yz_visible = TRUE; + } + + mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + if (llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + planar_manip_xz_visible = TRUE; + } + + mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, 1.f); + mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions); + if (llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + planar_manip_xy_visible = TRUE; + } + + // Project up to 9 manipulators to screen space 2*X, 2*Y, 2*Z, 3*planes + std::vector projected_manipulators; + projected_manipulators.reserve(9); + + for (S32 i = 0; i < num_arrow_manips; i+= 2) + { + LLVector4 projected_start = mManipulatorVertices[i] * transform; + projected_start = projected_start * (1.f / projected_start.mV[VW]); + + LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; + projected_end = projected_end * (1.f / projected_end.mV[VW]); + + ManipulatorHandle projected_manip( + LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), + LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), + MANIPULATOR_IDS[i / 2], + 10.f); // 10 pixel hotspot for arrows + projected_manipulators.push_back(projected_manip); + } + + if (planar_manip_yz_visible) + { + S32 i = num_arrow_manips; + LLVector4 projected_start = mManipulatorVertices[i] * transform; + projected_start = projected_start * (1.f / projected_start.mV[VW]); + + LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; + projected_end = projected_end * (1.f / projected_end.mV[VW]); + + ManipulatorHandle projected_manip( + LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), + LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), + MANIPULATOR_IDS[i / 2], + 20.f); // 20 pixels for planar manipulators + projected_manipulators.push_back(projected_manip); + } + + if (planar_manip_xz_visible) + { + S32 i = num_arrow_manips + 2; + LLVector4 projected_start = mManipulatorVertices[i] * transform; + projected_start = projected_start * (1.f / projected_start.mV[VW]); + + LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; + projected_end = projected_end * (1.f / projected_end.mV[VW]); + + ManipulatorHandle projected_manip( + LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), + LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), + MANIPULATOR_IDS[i / 2], + 20.f); // 20 pixels for planar manipulators + projected_manipulators.push_back(projected_manip); + } + + if (planar_manip_xy_visible) + { + S32 i = num_arrow_manips + 4; + LLVector4 projected_start = mManipulatorVertices[i] * transform; + projected_start = projected_start * (1.f / projected_start.mV[VW]); + + LLVector4 projected_end = mManipulatorVertices[i + 1] * transform; + projected_end = projected_end * (1.f / projected_end.mV[VW]); + + ManipulatorHandle projected_manip( + LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]), + LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), + MANIPULATOR_IDS[i / 2], + 20.f); // 20 pixels for planar manipulators + projected_manipulators.push_back(projected_manip); + } + + LLVector2 manip_start_2d; + LLVector2 manip_end_2d; + LLVector2 manip_dir; + LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled(); + F32 half_width = (F32)world_view_rect.getWidth() / 2.f; + F32 half_height = (F32)world_view_rect.getHeight() / 2.f; + LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); + LLVector2 mouse_delta; + + // Keep order consistent with insertion via stable_sort + std::stable_sort( projected_manipulators.begin(), + projected_manipulators.end(), + ClosestToCamera() ); + + std::vector::iterator it = projected_manipulators.begin(); + for ( ; it != projected_manipulators.end(); ++it) + { + ManipulatorHandle& manipulator = *it; + { + manip_start_2d.setVec(manipulator.mStartPosition.mV[VX] * half_width, manipulator.mStartPosition.mV[VY] * half_height); + manip_end_2d.setVec(manipulator.mEndPosition.mV[VX] * half_width, manipulator.mEndPosition.mV[VY] * half_height); + manip_dir = manip_end_2d - manip_start_2d; + + mouse_delta = mousePos - manip_start_2d; + + F32 manip_length = manip_dir.normVec(); + + F32 mouse_pos_manip = mouse_delta * manip_dir; + F32 mouse_dist_manip_squared = mouse_delta.magVecSquared() - (mouse_pos_manip * mouse_pos_manip); + + if (mouse_pos_manip > 0.f && + mouse_pos_manip < manip_length && + mouse_dist_manip_squared < manipulator.mHotSpotRadius * manipulator.mHotSpotRadius) + { + mHighlightedPart = manipulator.mManipID; + break; + } + } + } +} + +F32 LLManipTranslate::getMinGridScale() +{ + F32 scale; + switch (mManipPart) + { + case LL_NO_PART: + default: + scale = 1.f; + break; + case LL_X_ARROW: + scale = mGridScale.mV[VX]; + break; + case LL_Y_ARROW: + scale = mGridScale.mV[VY]; + break; + case LL_Z_ARROW: + scale = mGridScale.mV[VZ]; + break; + case LL_YZ_PLANE: + scale = llmin(mGridScale.mV[VY], mGridScale.mV[VZ]); + break; + case LL_XZ_PLANE: + scale = llmin(mGridScale.mV[VX], mGridScale.mV[VZ]); + break; + case LL_XY_PLANE: + scale = llmin(mGridScale.mV[VX], mGridScale.mV[VY]); + break; + } + + return scale; +} + + +BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask) +{ + // first, perform normal processing in case this was a quick-click + handleHover(x, y, mask); + + if(hasMouseCapture()) + { + // make sure arrow colors go back to normal + mManipPart = LL_NO_PART; + LLSelectMgr::getInstance()->enableSilhouette(TRUE); + + // Might have missed last update due to UPDATE_DELAY timing. + LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_POSITION ); + + mInSnapRegime = FALSE; + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); + } + + return LLManip::handleMouseUp(x, y, mask); +} + + +void LLManipTranslate::render() +{ + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + F32 zoom = gAgentCamera.mHUDCurZoom; + gGL.scalef(zoom, zoom, zoom); + } + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + renderGuidelines(); + } + { + //LLGLDisable gls_stencil(GL_STENCIL_TEST); + renderTranslationHandles(); + renderSnapGuides(); + } + gGL.popMatrix(); + + renderText(); +} + +void LLManipTranslate::renderSnapGuides() +{ + if (!gSavedSettings.getBOOL("SnapEnabled")) + { + return; + } + + F32 max_subdivisions = sGridMaxSubdivisionLevel;//(F32)gSavedSettings.getS32("GridSubdivision"); + F32 line_alpha = gSavedSettings.getF32("GridOpacity"); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest gls_depth(GL_TRUE); + LLGLDisable gls_cull(GL_CULL_FACE); + LLVector3 translate_axis; + + if (mManipPart == LL_NO_PART) + { + return; + } + + LLSelectNode *first_node = mObjectSelection->getFirstMoveableNode(TRUE); + if (!first_node) + { + return; + } + + updateGridSettings(); + + F32 smallest_grid_unit_scale = getMinGridScale() / max_subdivisions; + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); + LLVector3 selection_center = getPivotPoint(); + + LLViewerObject *first_object = first_node->getObject(); + + //pick appropriate projection plane for snap rulers according to relative camera position + if (mManipPart >= LL_X_ARROW && mManipPart <= LL_Z_ARROW) + { + LLVector3 normal; + LLColor4 inner_color; + LLManip::EManipPart temp_manip = mManipPart; + switch (mManipPart) + { + case LL_X_ARROW: + normal.setVec(1,0,0); + inner_color.setVec(0,1,1,line_alpha); + mManipPart = LL_YZ_PLANE; + break; + case LL_Y_ARROW: + normal.setVec(0,1,0); + inner_color.setVec(1,0,1,line_alpha); + mManipPart = LL_XZ_PLANE; + break; + case LL_Z_ARROW: + normal.setVec(0,0,1); + inner_color.setVec(1,1,0,line_alpha); + mManipPart = LL_XY_PLANE; + break; + default: + break; + } + + highlightIntersection(normal, selection_center, grid_rotation, inner_color); + mManipPart = temp_manip; + getManipAxis(first_object, mManipPart, translate_axis); + + LLVector3 at_axis_abs; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + at_axis_abs = LLVector3::x_axis * ~grid_rotation; + } + else + { + at_axis_abs = saved_selection_center - LLViewerCamera::getInstance()->getOrigin(); + at_axis_abs.normVec(); + + at_axis_abs = at_axis_abs * ~grid_rotation; + } + at_axis_abs.abs(); + + if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY] && at_axis_abs.mV[VX] > at_axis_abs.mV[VZ]) + { + if (mManipPart == LL_Y_ARROW) + { + mSnapOffsetAxis = LLVector3::z_axis; + } + else if (mManipPart == LL_Z_ARROW) + { + mSnapOffsetAxis = LLVector3::y_axis; + } + else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ]) + { + mSnapOffsetAxis = LLVector3::z_axis; + } + else + { + mSnapOffsetAxis = LLVector3::y_axis; + } + } + else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ]) + { + if (mManipPart == LL_X_ARROW) + { + mSnapOffsetAxis = LLVector3::z_axis; + } + else if (mManipPart == LL_Z_ARROW) + { + mSnapOffsetAxis = LLVector3::x_axis; + } + else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VZ]) + { + mSnapOffsetAxis = LLVector3::z_axis; + } + else + { + mSnapOffsetAxis = LLVector3::x_axis; + } + } + else + { + if (mManipPart == LL_X_ARROW) + { + mSnapOffsetAxis = LLVector3::y_axis; + } + else if (mManipPart == LL_Y_ARROW) + { + mSnapOffsetAxis = LLVector3::x_axis; + } + else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY]) + { + mSnapOffsetAxis = LLVector3::y_axis; + } + else + { + mSnapOffsetAxis = LLVector3::x_axis; + } + } + + mSnapOffsetAxis = mSnapOffsetAxis * grid_rotation; + + F32 guide_size_meters; + + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + guide_size_meters = 1.f / gAgentCamera.mHUDCurZoom; + mSnapOffsetMeters = mArrowLengthMeters * 1.5f; + } + else + { + LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin(); + F32 current_range = cam_to_selection.normVec(); + guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio(); + + F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians + F32 offset_at_camera = tan(apparent_angle) * 1.5f; + F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstance()->getOrigin()); + mSnapOffsetMeters = range * offset_at_camera; + } + + LLVector3 tick_start; + LLVector3 tick_end; + + // how far away from grid origin is the selection along the axis of translation? + F32 dist_grid_axis = (selection_center - mGridOrigin) * translate_axis; + // find distance to nearest smallest grid unit + F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale); + // how many smallest grid units are we away from largest grid scale? + S32 sub_div_offset = ll_round(fmodf(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale); + S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale)); + + LLGLDepthTest gls_depth(GL_FALSE); + + for (S32 pass = 0; pass < 3; pass++) + { + LLColor4 line_color = setupSnapGuideRenderPass(pass); + LLGLDepthTest gls_depth(pass != 1); + + gGL.begin(LLRender::LINES); + { + LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); + LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); + LLVector3 line_mid = (line_start + line_end) * 0.5f; + + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_start.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_end.mV); + + line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f)); + line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f)); + line_mid = (line_start + line_end) * 0.5f; + + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_start.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_end.mV); + + for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++) + { + tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit)); + + //No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208) + //F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale()); + /*if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f) + { + continue; + }*/ + + // add in off-axis offset + tick_start += (mSnapOffsetAxis * mSnapOffsetMeters); + + F32 tick_scale = 1.f; + for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + { + if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f) + { + break; + } + tick_scale *= 0.7f; + } + +// S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side; +// F32 alpha = line_alpha * (1.f - (0.8f * ((F32)llabs(i) / (F32)num_ticks_to_fade))); + + tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); + + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); + + tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + + (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit)); + tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); + + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); + } + } + gGL.end(); + + if (mInSnapRegime) + { + LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters; + LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters; + + gGL.begin(LLRender::LINES); + { + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(line_end.mV); + } + gGL.end(); + + // draw snap guide arrow + gGL.begin(LLRender::TRIANGLES); + { + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + + LLVector3 arrow_dir; + LLVector3 arrow_span = translate_axis; + + arrow_dir = -mSnapOffsetAxis; + gGL.vertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + + arrow_dir = mSnapOffsetAxis; + gGL.vertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + } + gGL.end(); + } + } + + sub_div_offset = ll_round(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale); + + LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstance()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstance()->getUpAxis())); + screen_translate_axis.normVec(); + + S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing); + + // render tickmark values + for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++) + { + LLVector3 tick_pos = selection_center + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)); + F32 alpha = line_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side))); + + F32 tick_scale = 1.f; + for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) + { + if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f) + { + break; + } + tick_scale *= 0.7f; + } + + if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / getSubdivisionLevel(tick_pos, translate_axis, getMinGridScale(), tick_label_spacing))) == 0.f) + { + F32 snap_offset_meters; + + if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) + { + snap_offset_meters = mSnapOffsetMeters; + } + else + { + snap_offset_meters = -mSnapOffsetMeters; + } + LLVector3 text_origin = selection_center + + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)) + + (mSnapOffsetAxis * snap_offset_meters * (1.f + tick_scale)); + + LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation; + F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale(); + EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); + F32 text_highlight = 0.8f; + if(i - ll_round(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime) + { + text_highlight = 1.f; + } + + if (grid_mode == GRID_MODE_WORLD) + { + // rescale units to meters from multiple of grid scale + offset_val *= 2.f * grid_scale[ARROW_TO_AXIS[mManipPart]]; + renderTickValue(text_origin, offset_val, std::string("m"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); + } + else + { + renderTickValue(text_origin, offset_val, std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha)); + } + } + } + if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD) + { + // render helpful text + if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) + { + F32 snap_offset_meters_up; + if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) + { + snap_offset_meters_up = mSnapOffsetMeters; + } + else + { + snap_offset_meters_up = -mSnapOffsetMeters; + } + + LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); + + LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis); + const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); + + std::string help_text = LLTrans::getString("manip_hint1"); + LLColor4 help_text_color = LLColor4::white; + help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); + help_text = LLTrans::getString("manip_hint2"); + help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f; + hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); + } + } + } + else + { + // render gridlines for planar snapping + + F32 u = 0, v = 0; + LLColor4 inner_color; + LLVector3 normal; + LLVector3 grid_center = selection_center - grid_origin; + F32 usc = 1; + F32 vsc = 1; + + grid_center *= ~grid_rotation; + + switch (mManipPart) + { + case LL_YZ_PLANE: + u = grid_center.mV[VY]; + v = grid_center.mV[VZ]; + usc = grid_scale.mV[VY]; + vsc = grid_scale.mV[VZ]; + inner_color.setVec(0,1,1,line_alpha); + normal.setVec(1,0,0); + break; + case LL_XZ_PLANE: + u = grid_center.mV[VX]; + v = grid_center.mV[VZ]; + usc = grid_scale.mV[VX]; + vsc = grid_scale.mV[VZ]; + inner_color.setVec(1,0,1,line_alpha); + normal.setVec(0,1,0); + break; + case LL_XY_PLANE: + u = grid_center.mV[VX]; + v = grid_center.mV[VY]; + usc = grid_scale.mV[VX]; + vsc = grid_scale.mV[VY]; + inner_color.setVec(1,1,0,line_alpha); + normal.setVec(0,0,1); + break; + default: + break; + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + highlightIntersection(normal, selection_center, grid_rotation, inner_color); + + gGL.pushMatrix(); + + F32 x,y,z,angle_radians; + grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); + + F32 sz = mGridSizeMeters; + F32 tiles = sz; + + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.pushMatrix(); + usc = 1.0f/usc; + vsc = 1.0f/vsc; + + while (usc > vsc*4.0f) + { + usc *= 0.5f; + } + while (vsc > usc * 4.0f) + { + vsc *= 0.5f; + } + + gGL.scalef(usc, vsc, 1.0f); + gGL.translatef(u, v, 0); + + float a = line_alpha; + + { + //draw grid behind objects + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + + { + //LLGLDisable stencil(GL_STENCIL_TEST); + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName()); + gGL.flush(); + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f); + gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + { + //draw black overlay + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f); + + //draw grid top + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName()); + renderGrid(u,v,tiles,1,1,1,a); + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } + + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + renderGuidelines(); + } + + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); + gGL.flush(); + + switch (mManipPart) + { + case LL_YZ_PLANE: + renderGuidelines(FALSE, TRUE, TRUE); + break; + case LL_XZ_PLANE: + renderGuidelines(TRUE, FALSE, TRUE); + break; + case LL_XY_PLANE: + renderGuidelines(TRUE, TRUE, FALSE); + break; + default: + break; + } + gGL.flush(); + } + } + } + } +} + +void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F32 a) +{ + F32 d = size*0.5f; + + for (F32 xx = -size-d; xx < size+d; xx += d) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + for (F32 yy = -size-d; yy < size+d; yy += d) + { + float dx, dy, da; + + dx = xx; dy = yy; + da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; + gGL.texCoord2f(dx, dy); + renderGridVert(dx,dy,r,g,b,da); + + dx = xx+d; dy = yy; + da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; + gGL.texCoord2f(dx, dy); + renderGridVert(dx,dy,r,g,b,da); + + dx = xx; dy = yy+d; + da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; + gGL.texCoord2f(dx, dy); + renderGridVert(dx,dy,r,g,b,da); + + dx = xx+d; dy = yy+d; + da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; + gGL.texCoord2f(dx, dy); + renderGridVert(dx,dy,r,g,b,da); + } + gGL.end(); + } + + +} + +void LLManipTranslate::highlightIntersection(LLVector3 normal, + LLVector3 selection_center, + LLQuaternion grid_rotation, + LLColor4 inner_color) +{ +#if 0 // DEPRECATED + if (!gSavedSettings.getBOOL("GridCrossSections")) + { + return; + } + + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + + static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; + static const U32 num_types = LL_ARRAY_SIZE(types); + + GLuint stencil_mask = 0xFFFFFFFF; + //stencil in volumes + + gGL.flush(); + + if (shader) + { + gClipProgram.bind(); + } + + { + //glStencilMask(stencil_mask); //deprecated + //glClearStencil(1); + //glClear(GL_STENCIL_BUFFER_BIT); + LLGLEnable cull_face(GL_CULL_FACE); + //LLGLEnable stencil(GL_STENCIL_TEST); + LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS); + //glStencilFunc(GL_ALWAYS, 0, stencil_mask); + gGL.setColorMask(false, false); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.diffuseColor4f(1,1,1,1); + + //setup clip plane + normal = normal * grid_rotation; + if (normal * (LLViewerCamera::getInstance()->getOrigin()-selection_center) < 0) + { + normal = -normal; + } + F32 d = -(selection_center * normal); + glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); + + gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); + + static LLStaticHashedString sClipPlane("clip_plane"); + gClipProgram.uniform4fv(sClipPlane, 1, plane.v); + + BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); + BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS); + + if (particles) + { + LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); + } + if (clouds) + { + LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS); + } + + //stencil in volumes + //glStencilOp(GL_INCR, GL_INCR, GL_INCR); + glCullFace(GL_FRONT); + for (U32 i = 0; i < num_types; i++) + { + gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + + //glStencilOp(GL_DECR, GL_DECR, GL_DECR); + glCullFace(GL_BACK); + for (U32 i = 0; i < num_types; i++) + { + gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + + if (particles) + { + LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); + } + if (clouds) + { + LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS); + } + + gGL.setColorMask(true, false); + } + gGL.color4f(1,1,1,1); + + gGL.pushMatrix(); + + F32 x,y,z,angle_radians; + grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); + + F32 sz = mGridSizeMeters; + F32 tiles = sz; + + if (shader) + { + shader->bind(); + } + + if (shader) + { + shader->bind(); + } + + //draw volume/plane intersections + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_FALSE); + //LLGLEnable stencil(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 0, stencil_mask); + renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f); + } + + glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); + glStencilMask(0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + gGL.popMatrix(); +#endif +} + +void LLManipTranslate::renderText() +{ + if (mObjectSelection->getRootObjectCount() && !mObjectSelection->isAttachment()) + { + LLVector3 pos = getPivotPoint(); + renderXYZ(pos); + } + else + { + const BOOL children_ok = TRUE; + LLViewerObject* objectp = mObjectSelection->getFirstRootObject(children_ok); + if (objectp) + { + renderXYZ(objectp->getPositionEdit()); + } + } +} + +void LLManipTranslate::renderTranslationHandles() +{ + LLVector3 grid_origin; + LLVector3 grid_scale; + LLQuaternion grid_rotation; + LLGLDepthTest gls_depth(GL_FALSE); + + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + LLVector3 at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + at_axis = LLVector3::x_axis * ~grid_rotation; + } + else + { + at_axis = LLViewerCamera::getInstance()->getAtAxis() * ~grid_rotation; + } + + if (at_axis.mV[VX] > 0.f) + { + mPlaneManipPositions.mV[VX] = 1.f; + } + else + { + mPlaneManipPositions.mV[VX] = -1.f; + } + + if (at_axis.mV[VY] > 0.f) + { + mPlaneManipPositions.mV[VY] = 1.f; + } + else + { + mPlaneManipPositions.mV[VY] = -1.f; + } + + if (at_axis.mV[VZ] > 0.f) + { + mPlaneManipPositions.mV[VZ] = 1.f; + } + else + { + mPlaneManipPositions.mV[VZ] = -1.f; + } + + LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE); + if (!first_object) return; + + LLVector3 selection_center = getPivotPoint(); + + // Drag handles + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeightRaw(); + mArrowLengthMeters /= gAgentCamera.mHUDCurZoom; + } + else + { + LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent(); + F32 range = dist_vec(camera_pos_agent, selection_center); + F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center); + + // Don't draw handles if you're too far away + if (gSavedSettings.getBOOL("LimitSelectDistance")) + { + if (range_from_agent > gSavedSettings.getF32("MaxSelectDistance")) + { + return; + } + } + + if (range > 0.001f) + { + // range != zero + F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians + mArrowLengthMeters = range * tan(apparent_angle); + } + else + { + // range == zero + mArrowLengthMeters = 1.0f; + } + } + //Assume that UI scale factor is equivalent for X and Y axis + F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX]; + mArrowLengthMeters *= ui_scale_factor; + + mPlaneManipOffsetMeters = mArrowLengthMeters * 1.8f; + mGridSizeMeters = gSavedSettings.getF32("GridDrawSize"); + mConeSize = mArrowLengthMeters / 4.f; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + { + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + + F32 angle_radians, x, y, z; + grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); + + gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); + + LLQuaternion invRotation = grid_rotation; + invRotation.conjQuat(); + + LLVector3 relative_camera_dir; + + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + relative_camera_dir = LLVector3::x_axis * invRotation; + } + else + { + relative_camera_dir = (selection_center - LLViewerCamera::getInstance()->getOrigin()) * invRotation; + } + relative_camera_dir.normVec(); + + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDisable cull_face(GL_CULL_FACE); + + LLColor4 color1; + LLColor4 color2; + + // update manipulator sizes + for (S32 index = 0; index < 3; index++) + { + if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW) + { + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + } + else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE) + { + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + } + else + { + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + } + } + + if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + // render YZ plane manipulator + gGL.pushMatrix(); + gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); + gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters); + gGL.scalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]); + if (mHighlightedPart == LL_YZ_PLANE) + { + color1.setVec(0.f, 1.f, 0.f, 1.f); + color2.setVec(0.f, 0.f, 1.f, 1.f); + } + else + { + color1.setVec(0.f, 1.f, 0.f, 0.6f); + color2.setVec(0.f, 0.f, 1.f, 0.6f); + } + gGL.begin(LLRender::TRIANGLES); + { + gGL.color4fv(color1.mV); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + + gGL.color4fv(color2.mV); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + } + gGL.end(); + + LLUI::setLineWidth(3.0f); + gGL.begin(LLRender::LINES); + { + gGL.color4f(0.f, 0.f, 0.f, 0.3f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); + + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + } + gGL.end(); + LLUI::setLineWidth(1.0f); + gGL.popMatrix(); + } + + if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + // render XZ plane manipulator + gGL.pushMatrix(); + gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); + gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters); + gGL.scalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]); + if (mHighlightedPart == LL_XZ_PLANE) + { + color1.setVec(0.f, 0.f, 1.f, 1.f); + color2.setVec(1.f, 0.f, 0.f, 1.f); + } + else + { + color1.setVec(0.f, 0.f, 1.f, 0.6f); + color2.setVec(1.f, 0.f, 0.f, 0.6f); + } + + gGL.begin(LLRender::TRIANGLES); + { + gGL.color4fv(color1.mV); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + + gGL.color4fv(color2.mV); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + } + gGL.end(); + + LLUI::setLineWidth(3.0f); + gGL.begin(LLRender::LINES); + { + gGL.color4f(0.f, 0.f, 0.f, 0.3f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); + + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + } + gGL.end(); + LLUI::setLineWidth(1.0f); + + gGL.popMatrix(); + } + + if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT) + { + // render XY plane manipulator + gGL.pushMatrix(); + gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); + +/* Y + ^ + v1 + | \ + |<- v0 + | /| \ + v2__v__v3 > X +*/ + LLVector3 v0,v1,v2,v3; +#if 0 + // This should theoretically work but looks off; could be tuned later -SJB + gGL.translatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f); + v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); + v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f); + v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); + v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); +#else + gGL.translatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f); + v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); + v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f); + v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); + v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); +#endif + gGL.scalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]); + if (mHighlightedPart == LL_XY_PLANE) + { + color1.setVec(1.f, 0.f, 0.f, 1.f); + color2.setVec(0.f, 1.f, 0.f, 1.f); + } + else + { + color1.setVec(0.8f, 0.f, 0.f, 0.6f); + color2.setVec(0.f, 0.8f, 0.f, 0.6f); + } + + gGL.begin(LLRender::TRIANGLES); + { + gGL.color4fv(color1.mV); + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v1.mV); + gGL.vertex3fv(v2.mV); + + gGL.color4fv(color2.mV); + gGL.vertex3fv(v2.mV); + gGL.vertex3fv(v3.mV); + gGL.vertex3fv(v0.mV); + } + gGL.end(); + + LLUI::setLineWidth(3.0f); + gGL.begin(LLRender::LINES); + { + gGL.color4f(0.f, 0.f, 0.f, 0.3f); + LLVector3 v12 = (v1 + v2) * .5f; + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV); + + LLVector3 v23 = (v2 + v3) * .5f; + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV); + } + gGL.end(); + LLUI::setLineWidth(1.0f); + + gGL.popMatrix(); + } + } + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // Since we draw handles with depth testing off, we need to draw them in the + // proper depth order. + + // Copied from LLDrawable::updateGeometry + LLVector3 pos_agent = first_object->getPositionAgent(); + LLVector3 camera_agent = gAgentCamera.getCameraPositionAgent(); + LLVector3 headPos = pos_agent - camera_agent; + + LLVector3 orientWRTHead = headPos * invRotation; + + // Find nearest vertex + U32 nearest = (orientWRTHead.mV[0] < 0.0f ? 1 : 0) + + (orientWRTHead.mV[1] < 0.0f ? 2 : 0) + + (orientWRTHead.mV[2] < 0.0f ? 4 : 0); + + // opposite faces on Linden cubes: + // 0 & 5 + // 1 & 3 + // 2 & 4 + + // Table of order to draw faces, based on nearest vertex + static U32 face_list[8][NUM_AXES*2] = { + { 2,0,1, 4,5,3 }, // v6 F201 F453 + { 2,0,3, 4,5,1 }, // v7 F203 F451 + { 4,0,1, 2,5,3 }, // v5 F401 F253 + { 4,0,3, 2,5,1 }, // v4 F403 F251 + { 2,5,1, 4,0,3 }, // v2 F251 F403 + { 2,5,3, 4,0,1 }, // v3 F253 F401 + { 4,5,1, 2,0,3 }, // v1 F451 F203 + { 4,5,3, 2,0,1 }, // v0 F453 F201 + }; + static const EManipPart which_arrow[6] = { + LL_Z_ARROW, + LL_X_ARROW, + LL_Y_ARROW, + LL_X_ARROW, + LL_Y_ARROW, + LL_Z_ARROW}; + + // draw arrows for deeper faces first, closer faces last + LLVector3 camera_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + camera_axis = LLVector3::x_axis; + } + else + { + camera_axis.setVec(gAgentCamera.getCameraPositionAgent() - first_object->getPositionAgent()); + } + + for (U32 i = 0; i < NUM_AXES*2; i++) + { + U32 face = face_list[nearest][i]; + + LLVector3 arrow_axis; + getManipAxis(first_object, which_arrow[face], arrow_axis); + + renderArrow(which_arrow[face], + mManipPart, + (face >= 3) ? -mConeSize : mConeSize, + (face >= 3) ? -mArrowLengthMeters : mArrowLengthMeters, + mConeSize, + FALSE); + } + } + } + gGL.popMatrix(); +} + + +void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_size, F32 arrow_size, F32 handle_size, BOOL reverse_direction) +{ + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLEnable gls_blend(GL_BLEND); + + for (S32 pass = 1; pass <= 2; pass++) + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER); + gGL.pushMatrix(); + + S32 index = 0; + + index = ARROW_TO_AXIS[which_arrow]; + + // assign a color for this arrow + LLColor4 color; // black + if (which_arrow == selected_arrow || which_arrow == mHighlightedPart) + { + color.mV[index] = (pass == 1) ? 1.f : 0.5f; + } + else if (selected_arrow != LL_NO_PART) + { + color.mV[VALPHA] = 0.f; + } + else + { + color.mV[index] = pass == 1 ? .8f : .35f ; // red, green, or blue + color.mV[VALPHA] = 0.6f; + } + gGL.color4fv( color.mV ); + + LLVector3 vec; + + { + LLUI::setLineWidth(2.0f); + gGL.begin(LLRender::LINES); + vec.mV[index] = box_size; + gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); + + vec.mV[index] = arrow_size; + gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); + gGL.end(); + LLUI::setLineWidth(1.0f); + } + + gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]); + gGL.scalef(handle_size, handle_size, handle_size); + + F32 rot = 0.0f; + LLVector3 axis; + + switch(which_arrow) + { + case LL_X_ARROW: + rot = reverse_direction ? -90.0f : 90.0f; + axis.mV[1] = 1.0f; + break; + case LL_Y_ARROW: + rot = reverse_direction ? 90.0f : -90.0f; + axis.mV[0] = 1.0f; + break; + case LL_Z_ARROW: + rot = reverse_direction ? 180.0f : 0.0f; + axis.mV[0] = 1.0f; + break; + default: + LL_ERRS() << "renderArrow called with bad arrow " << which_arrow << LL_ENDL; + break; + } + + gGL.diffuseColor4fv(color.mV); + gGL.rotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]); + gGL.scalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f); + + gCone.render(); + + gGL.popMatrix(); + } +} + +void LLManipTranslate::renderGridVert(F32 x_trans, F32 y_trans, F32 r, F32 g, F32 b, F32 alpha) +{ + gGL.color4f(r, g, b, alpha); + switch (mManipPart) + { + case LL_YZ_PLANE: + gGL.vertex3f(0, x_trans, y_trans); + break; + case LL_XZ_PLANE: + gGL.vertex3f(x_trans, 0, y_trans); + break; + case LL_XY_PLANE: + gGL.vertex3f(x_trans, y_trans, 0); + break; + default: + gGL.vertex3f(0,0,0); + break; + } + +} + +// virtual +BOOL LLManipTranslate::canAffectSelection() +{ + BOOL can_move = mObjectSelection->getObjectCount() != 0; + if (can_move) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* objectp) + { + LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit(); + return objectp->permMove() && !objectp->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + } + } func; + can_move = mObjectSelection->applyToObjects(&func); + } + return can_move; } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 84446b626a..208b289ca9 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmaterialeditor.cpp * @brief Implementation of the gltf material editor * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,7 +48,7 @@ #include "llviewertexture.h" #include "llsdutil.h" #include "llselectmgr.h" -#include "llstatusbar.h" // can_afford_transaction() +#include "llstatusbar.h" // can_afford_transaction() #include "lltoolpie.h" #include "llviewerinventory.h" #include "llinventory.h" @@ -502,7 +502,7 @@ BOOL LLMaterialEditor::postBuild() // Apply changes to object live applyToSelection(); }; - + childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor @@ -550,7 +550,7 @@ BOOL LLMaterialEditor::postBuild() // Disable/enable setCanApplyImmediately() based on // working from inventory, upload or editing inworld - return LLPreview::postBuild(); + return LLPreview::postBuild(); } void LLMaterialEditor::onClickCloseBtn(bool app_quitting) @@ -1226,7 +1226,7 @@ std::string LLMaterialEditor::getEncodedAsset() bool LLMaterialEditor::decodeAsset(const std::vector& buffer) { LLSD asset; - + std::istrstream str(&buffer[0], buffer.size()); if (LLSDSerialize::deserialize(asset, str, buffer.size())) { @@ -1290,7 +1290,7 @@ const std::string LLMaterialEditor::buildMaterialDescription() desc << LLTrans::getString("Material Texture Name Header"); // add the texture names for each just so long as the material - // we loaded has an entry for it (i think testing the texture + // we loaded has an entry for it (i think testing the texture // control UUI for NULL is a valid metric for if it was loaded // or not but I suspect this code will change a lot so may need // to revisit @@ -1372,7 +1372,7 @@ bool LLMaterialEditor::saveIfNeeded() } } else - { + { // Make a new inventory item and set upload permissions LLPermissions local_permissions; local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); @@ -1401,7 +1401,7 @@ bool LLMaterialEditor::saveIfNeeded() // We do not update floater with uploaded asset yet, so just close it. closeFloater(); } - + return true; } @@ -1816,7 +1816,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& } else { - LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response) + LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response) { LLNotificationsUtil::add("SaveMaterialAs", LLSD().with("DESC", mMaterialName), LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2)); @@ -1976,7 +1976,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind std::list material_list; std::vector::const_iterator mat_iter = model_in.materials.begin(); std::vector::const_iterator mat_end = model_in.materials.end(); - + for (; mat_iter != mat_end; mat_iter++) { std::string mat_name = mat_iter->name; @@ -2615,28 +2615,28 @@ bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, } /** - * Build a texture name from the contents of the (in tinyGLFT parlance) + * Build a texture name from the contents of the (in tinyGLFT parlance) * Image URI. This often is filepath to the original image on the users' * local file system. */ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type) { - // getBaseFileName() works differently on each platform and file patchs - // can contain both types of delimiter so unify them then extract the + // getBaseFileName() works differently on each platform and file patchs + // can contain both types of delimiter so unify them then extract the // base name (no path or extension) std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]); std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]); const bool strip_extension = true; std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension); - // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :) + // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :) const int max_texture_name_length = 64; if (stripped_uri.length() > max_texture_name_length) { stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1); } - // We intend to append the type of texture (base color, emissive etc.) to the + // We intend to append the type of texture (base color, emissive etc.) to the // name of the texture but sometimes the creator already did that. To try // to avoid repeats (not perfect), we look for the texture type in the name // and if we find it, do not append the type, later on. One way this fails @@ -2702,15 +2702,15 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c /** * Update the metadata for the material based on what we find in the loaded * file (along with some assumptions and interpretations...). Fields include - * the name of the material, a material description and the names of the + * the name of the material, a material description and the names of the * composite textures. */ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index) { - // Use the name (without any path/extension) of the file that was - // uploaded as the base of the material name. Then if the name of the + // Use the name (without any path/extension) of the file that was + // uploaded as the base of the material name. Then if the name of the // scene is present and not blank, append that and use the result as - // the name of the material. This is a first pass at creating a + // the name of the material. This is a first pass at creating a // naming scheme that is useful to real content creators and hopefully // avoid 500 materials in your inventory called "scene" or "Default" const bool strip_extension = true; @@ -2741,10 +2741,10 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti // scene name isn't present so no point using it } - // If we have a valid material or scene name, use it to build the short and - // long versions of the material name. The long version is used + // If we have a valid material or scene name, use it to build the short and + // long versions of the material name. The long version is used // as you might expect, for the material name. The short version is - // used as part of the image/texture name - the theory is that will + // used as part of the image/texture name - the theory is that will // allow content creators to track the material and the corresponding // textures if (material_name.length()) @@ -2752,9 +2752,9 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti mMaterialNameShort = base_filename; mMaterialName = STRINGIZE( - base_filename << - " " << - "(" << + base_filename << + " " << + "(" << material_name << ")" ); @@ -2770,14 +2770,14 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti LLInventoryObject::correctInventoryName(mMaterialName); LLInventoryObject::correctInventoryName(mMaterialNameShort); - // We also set the title of the floater to match the + // We also set the title of the floater to match the // name of the material setTitle(mMaterialName); /** - * Extract / derive the names of each composite texture. For each, the + * Extract / derive the names of each composite texture. For each, the * index is used to to determine which of the "Images" is used. If the index - * is -1 then that texture type is not present in the material (Seems to be + * is -1 then that texture type is not present in the material (Seems to be * quite common that a material is missing 1 or more types of texture) */ if (model.materials.size() > index) @@ -2785,8 +2785,8 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti const tinygltf::Material& first_material = model.materials[index]; mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; - // note: unlike the other textures, base color doesn't have its own entry - // in the tinyGLTF Material struct. Rather, it is taken from a + // note: unlike the other textures, base color doesn't have its own entry + // in the tinyGLTF Material struct. Rather, it is taken from a // sub-texture in the pbrMetallicRoughness member int index = first_material.pbrMetallicRoughness.baseColorTexture.index; if (index > -1 && index < model.images.size()) @@ -2940,7 +2940,7 @@ public: else { // mSavedGLTFOverrideMaterials[te] being present but null - // means we need to use a default value + // means we need to use a default value revert_mat = new LLGLTFMaterial(); } } @@ -3281,7 +3281,7 @@ bool LLMaterialEditor::setFromSelection() // Ovverdired might have been updated, // refresh state of local textures in overrides - // + // // Todo: this probably shouldn't be here, but in localbitmap, // subscried to all material overrides if we want copied // objects to get properly updated as well @@ -3304,7 +3304,7 @@ void LLMaterialEditor::loadAsset() { item = getItem(); } - + bool fail = false; if (item) @@ -3508,16 +3508,16 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( buffer, asset_id, - name, - name, + name, + name, 0, - LLFolderType::FT_TEXTURE, + LLFolderType::FT_TEXTURE, LLInventoryType::IT_TEXTURE, LLAssetType::AT_TEXTURE, LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost, + expected_upload_cost, false, cb, failed_upload)); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 5ee25b76a2..38af68bfff 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpanelface.cpp * @brief Panel in the tools floater for editing face textures, colors, etc. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,7 +28,7 @@ // file include #include "llpanelface.h" - + // library includes #include "llcalc.h" #include "llerror.h" @@ -102,15 +102,15 @@ LLPanelFace::Selection LLPanelFace::sMaterialOverrideSelection; // Constant definitions for comboboxes // Must match the commbobox definitions in panel_tools_texture.xml // -const S32 MATMEDIA_MATERIAL = 0; // Material -const S32 MATMEDIA_PBR = 1; // PBR -const S32 MATMEDIA_MEDIA = 2; // Media -const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture -const S32 MATTYPE_NORMAL = 1; // Normal map -const S32 MATTYPE_SPECULAR = 2; // Specular map -const S32 ALPHAMODE_MASK = 2; // Alpha masking mode -const S32 BUMPY_TEXTURE = 18; // use supplied normal map -const S32 SHINY_TEXTURE = 4; // use supplied specular map +const S32 MATMEDIA_MATERIAL = 0; // Material +const S32 MATMEDIA_PBR = 1; // PBR +const S32 MATMEDIA_MEDIA = 2; // Media +const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture +const S32 MATTYPE_NORMAL = 1; // Normal map +const S32 MATTYPE_SPECULAR = 2; // Specular map +const S32 ALPHAMODE_MASK = 2; // Alpha masking mode +const S32 BUMPY_TEXTURE = 18; // use supplied normal map +const S32 SHINY_TEXTURE = 4; // use supplied specular map const S32 PBRTYPE_RENDER_MATERIAL_ID = 0; // Render Material ID const S32 PBRTYPE_BASE_COLOR = 1; // PBR Base Color const S32 PBRTYPE_METALLIC_ROUGHNESS = 2; // PBR Metallic @@ -159,7 +159,7 @@ void LLPanelFace::updateSelectedGLTFMaterials(std::function mFunc; + std::function mFunc; } select_func(func); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func); @@ -176,7 +176,7 @@ void readSelectedGLTFMaterial(std::function func, T& v { const LLTextureEntry* tep = object->getTE(face); const LLGLTFMaterial* render_material = tep->getGLTFRenderMaterial(); - + return mFunc(render_material); } @@ -211,9 +211,9 @@ LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() } } - channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; - channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; - return channel_to_edit; + channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + return channel_to_edit; } LLRender::eTexIndex LLPanelFace::getTextureDropChannel() @@ -240,55 +240,55 @@ LLGLTFMaterial::TextureInfo LLPanelFace::getPBRDropChannel() // Things the UI provides... // -LLUUID LLPanelFace::getCurrentNormalMap() { return getChild("bumpytexture control")->getImageAssetID(); } -LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild("shinytexture control")->getImageAssetID(); } -U32 LLPanelFace::getCurrentShininess() { return getChild("combobox shininess")->getCurrentIndex(); } -U32 LLPanelFace::getCurrentBumpiness() { return getChild("combobox bumpiness")->getCurrentIndex(); } -U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild("combobox alphamode")->getCurrentIndex(); } -U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild("maskcutoff")->getValue().asInteger(); } -U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild("environment")->getValue().asInteger(); } -U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild("glossiness")->getValue().asInteger(); } -F32 LLPanelFace::getCurrentBumpyRot() { return getChild("bumpyRot")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild("bumpyScaleU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild("bumpyScaleV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild("bumpyOffsetU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild("bumpyOffsetV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyRot() { return getChild("shinyRot")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyScaleU() { return getChild("shinyScaleU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyScaleV() { return getChild("shinyScaleV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild("shinyOffsetU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOffsetV")->getValue().asReal(); } +LLUUID LLPanelFace::getCurrentNormalMap() { return getChild("bumpytexture control")->getImageAssetID(); } +LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild("shinytexture control")->getImageAssetID(); } +U32 LLPanelFace::getCurrentShininess() { return getChild("combobox shininess")->getCurrentIndex(); } +U32 LLPanelFace::getCurrentBumpiness() { return getChild("combobox bumpiness")->getCurrentIndex(); } +U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild("combobox alphamode")->getCurrentIndex(); } +U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild("maskcutoff")->getValue().asInteger(); } +U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild("environment")->getValue().asInteger(); } +U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild("glossiness")->getValue().asInteger(); } +F32 LLPanelFace::getCurrentBumpyRot() { return getChild("bumpyRot")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild("bumpyScaleU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild("bumpyScaleV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild("bumpyOffsetU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild("bumpyOffsetV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyRot() { return getChild("shinyRot")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyScaleU() { return getChild("shinyScaleU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyScaleV() { return getChild("shinyScaleV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild("shinyOffsetU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOffsetV")->getValue().asReal(); } // // Methods // -BOOL LLPanelFace::postBuild() -{ - childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); - childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); - childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this); - childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this); - childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this); - childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this); - childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this); - childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); - childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this); - childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this); - - childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); - childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); - childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); - childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); - childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); - childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); - childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); - childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); - childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); - childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); - childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); - childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); - childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); +BOOL LLPanelFace::postBuild() +{ + childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); + childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); + childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this); + childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this); + childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this); + childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this); + childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this); + childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); + childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this); + childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this); + + childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); + childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); + childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); + childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); + childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); + childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); + childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); + childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); + childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); + childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); + childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); + childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); + childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this); childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this); @@ -301,30 +301,30 @@ BOOL LLPanelFace::postBuild() LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived); sMaterialOverrideSelection.connect(); - childSetAction("button align",&LLPanelFace::onClickAutoFix,this); - childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); + childSetAction("button align",&LLPanelFace::onClickAutoFix,this); + childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); childSetAction("pbr_from_inventory", &LLPanelFace::onClickBtnLoadInvPBR, this); childSetAction("edit_selected_pbr", &LLPanelFace::onClickBtnEditPBR, this); childSetAction("save_selected_pbr", &LLPanelFace::onClickBtnSavePBR, this); - LLTextureCtrl* mTextureCtrl; - LLTextureCtrl* mShinyTextureCtrl; - LLTextureCtrl* mBumpyTextureCtrl; - LLColorSwatchCtrl* mColorSwatch; - LLColorSwatchCtrl* mShinyColorSwatch; + LLTextureCtrl* mTextureCtrl; + LLTextureCtrl* mShinyTextureCtrl; + LLTextureCtrl* mBumpyTextureCtrl; + LLColorSwatchCtrl* mColorSwatch; + LLColorSwatchCtrl* mShinyColorSwatch; - LLComboBox* mComboTexGen; + LLComboBox* mComboTexGen; - LLCheckBoxCtrl *mCheckFullbright; - - LLTextBox* mLabelColorTransp; - LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha + LLCheckBoxCtrl *mCheckFullbright; - LLSpinCtrl* mCtrlGlow; + LLTextBox* mLabelColorTransp; + LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha - setMouseOpaque(FALSE); + LLSpinCtrl* mCtrlGlow; - LLTextureCtrl* pbr_ctrl = findChild("pbr_control"); + setMouseOpaque(FALSE); + + LLTextureCtrl* pbr_ctrl = findChild("pbr_control"); if (pbr_ctrl) { pbr_ctrl->setDefaultImageAssetID(LLUUID::null); @@ -344,117 +344,117 @@ BOOL LLPanelFace::postBuild() pbr_ctrl->setInventoryPickType(PICK_MATERIAL); } - mTextureCtrl = getChild("texture control"); - if(mTextureCtrl) - { - mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE); - mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) ); - mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) ); - mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); - mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); - mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); - mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); - - mTextureCtrl->setFollowsTop(); - mTextureCtrl->setFollowsLeft(); - mTextureCtrl->setImmediateFilterPermMask(PERM_NONE); - mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - - mShinyTextureCtrl = getChild("shinytexture control"); - if(mShinyTextureCtrl) - { - mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR); - mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); - mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); - mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); - mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); - - mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); - mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); - mShinyTextureCtrl->setFollowsTop(); - mShinyTextureCtrl->setFollowsLeft(); - mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); - mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - - mBumpyTextureCtrl = getChild("bumpytexture control"); - if(mBumpyTextureCtrl) - { - mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL); - mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL); - mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); - mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); - mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); - mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); - - mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); - mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); - mBumpyTextureCtrl->setFollowsTop(); - mBumpyTextureCtrl->setFollowsLeft(); - mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); - mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - - mColorSwatch = getChild("colorswatch"); - if(mColorSwatch) - { - mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2)); - mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2)); - mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2)); - mColorSwatch->setFollowsTop(); - mColorSwatch->setFollowsLeft(); - mColorSwatch->setCanApplyImmediately(TRUE); - } - - mShinyColorSwatch = getChild("shinycolorswatch"); - if(mShinyColorSwatch) - { - mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2)); - mShinyColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelShinyColor, this, _2)); - mShinyColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectShinyColor, this, _2)); - mShinyColorSwatch->setFollowsTop(); - mShinyColorSwatch->setFollowsLeft(); - mShinyColorSwatch->setCanApplyImmediately(TRUE); - } - - mLabelColorTransp = getChild("color trans"); - if(mLabelColorTransp) - { - mLabelColorTransp->setFollowsTop(); - mLabelColorTransp->setFollowsLeft(); - } - - mCtrlColorTransp = getChild("ColorTrans"); - if(mCtrlColorTransp) - { - mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2)); - mCtrlColorTransp->setPrecision(0); - mCtrlColorTransp->setFollowsTop(); - mCtrlColorTransp->setFollowsLeft(); - } - - mCheckFullbright = getChild("checkbox fullbright"); - if (mCheckFullbright) - { - mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this); - } - - mComboTexGen = getChild("combobox texgen"); - if(mComboTexGen) - { - mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this); - mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); - } + mTextureCtrl = getChild("texture control"); + if(mTextureCtrl) + { + mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE); + mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) ); + mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) ); + mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); + mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + + mTextureCtrl->setFollowsTop(); + mTextureCtrl->setFollowsLeft(); + mTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + + mShinyTextureCtrl = getChild("shinytexture control"); + if(mShinyTextureCtrl) + { + mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR); + mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + + mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mShinyTextureCtrl->setFollowsTop(); + mShinyTextureCtrl->setFollowsLeft(); + mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + + mBumpyTextureCtrl = getChild("bumpytexture control"); + if(mBumpyTextureCtrl) + { + mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL); + mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL); + mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + + mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mBumpyTextureCtrl->setFollowsTop(); + mBumpyTextureCtrl->setFollowsLeft(); + mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + + mColorSwatch = getChild("colorswatch"); + if(mColorSwatch) + { + mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2)); + mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2)); + mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2)); + mColorSwatch->setFollowsTop(); + mColorSwatch->setFollowsLeft(); + mColorSwatch->setCanApplyImmediately(TRUE); + } + + mShinyColorSwatch = getChild("shinycolorswatch"); + if(mShinyColorSwatch) + { + mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2)); + mShinyColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelShinyColor, this, _2)); + mShinyColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectShinyColor, this, _2)); + mShinyColorSwatch->setFollowsTop(); + mShinyColorSwatch->setFollowsLeft(); + mShinyColorSwatch->setCanApplyImmediately(TRUE); + } + + mLabelColorTransp = getChild("color trans"); + if(mLabelColorTransp) + { + mLabelColorTransp->setFollowsTop(); + mLabelColorTransp->setFollowsLeft(); + } + + mCtrlColorTransp = getChild("ColorTrans"); + if(mCtrlColorTransp) + { + mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2)); + mCtrlColorTransp->setPrecision(0); + mCtrlColorTransp->setFollowsTop(); + mCtrlColorTransp->setFollowsLeft(); + } + + mCheckFullbright = getChild("checkbox fullbright"); + if (mCheckFullbright) + { + mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this); + } + + mComboTexGen = getChild("combobox texgen"); + if(mComboTexGen) + { + mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this); + mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); + } mComboMatMedia = getChild("combobox matmedia"); - if(mComboMatMedia) - { + if(mComboMatMedia) + { mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); - } + } - LLRadioGroup* radio_mat_type = findChild("radio_material_type"); + LLRadioGroup* radio_mat_type = findChild("radio_material_type"); if(radio_mat_type) { radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this); @@ -468,25 +468,25 @@ BOOL LLPanelFace::postBuild() radio_pbr_type->selectNthItem(PBRTYPE_RENDER_MATERIAL_ID); } - mCtrlGlow = getChild("glow"); - if(mCtrlGlow) - { - mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); - } + mCtrlGlow = getChild("glow"); + if(mCtrlGlow) + { + mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); + } mMenuClipboardColor = getChild("clipboard_color_params_btn"); mMenuClipboardTexture = getChild("clipboard_texture_params_btn"); - + mTitleMedia = getChild("title_media"); mTitleMediaText = getChild("media_info"); - clearCtrls(); + clearCtrls(); - return TRUE; + return TRUE; } LLPanelFace::LLPanelFace() -: LLPanel(), +: LLPanel(), mIsAlpha(false), mComboMatMedia(NULL), mTitleMedia(NULL), @@ -532,131 +532,131 @@ void LLPanelFace::draw() void LLPanelFace::sendTexture() { - LLTextureCtrl* mTextureCtrl = getChild("texture control"); - if(!mTextureCtrl) return; - if( !mTextureCtrl->getTentative() ) - { - // we grab the item id first, because we want to do a - // permissions check in the selection manager. ARGH! - LLUUID id = mTextureCtrl->getImageItemID(); - if(id.isNull()) - { - id = mTextureCtrl->getImageAssetID(); - } + LLTextureCtrl* mTextureCtrl = getChild("texture control"); + if(!mTextureCtrl) return; + if( !mTextureCtrl->getTentative() ) + { + // we grab the item id first, because we want to do a + // permissions check in the selection manager. ARGH! + LLUUID id = mTextureCtrl->getImageItemID(); + if(id.isNull()) + { + id = mTextureCtrl->getImageAssetID(); + } if (!LLSelectMgr::getInstance()->selectionSetImage(id)) { // need to refresh value in texture ctrl refresh(); } - } + } } void LLPanelFace::sendBump(U32 bumpiness) -{ - LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); - if (bumpiness < BUMPY_TEXTURE) -{ - LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL; - bumpytexture_ctrl->clear(); - bumpytexture_ctrl->setImageAssetID(LLUUID()); - } +{ + LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); + if (bumpiness < BUMPY_TEXTURE) +{ + LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL; + bumpytexture_ctrl->clear(); + bumpytexture_ctrl->setImageAssetID(LLUUID()); + } - updateBumpyControls(bumpiness == BUMPY_TEXTURE, true); + updateBumpyControls(bumpiness == BUMPY_TEXTURE, true); - LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID(); + LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID(); - U8 bump = (U8) bumpiness & TEM_BUMP_MASK; + U8 bump = (U8) bumpiness & TEM_BUMP_MASK; - // Clear legacy bump to None when using an actual normal map - // - if (!current_normal_map.isNull()) - bump = 0; + // Clear legacy bump to None when using an actual normal map + // + if (!current_normal_map.isNull()) + bump = 0; - // Set the normal map or reset it to null as appropriate - // - LLSelectedTEMaterial::setNormalID(this, current_normal_map); + // Set the normal map or reset it to null as appropriate + // + LLSelectedTEMaterial::setNormalID(this, current_normal_map); - LLSelectMgr::getInstance()->selectionSetBumpmap( bump, bumpytexture_ctrl->getImageItemID() ); + LLSelectMgr::getInstance()->selectionSetBumpmap( bump, bumpytexture_ctrl->getImageItemID() ); } void LLPanelFace::sendTexGen() { - LLComboBox* mComboTexGen = getChild("combobox texgen"); - if(!mComboTexGen)return; - U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT; - LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen ); + LLComboBox* mComboTexGen = getChild("combobox texgen"); + if(!mComboTexGen)return; + U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT; + LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen ); } void LLPanelFace::sendShiny(U32 shininess) { - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); - if (shininess < SHINY_TEXTURE) + if (shininess < SHINY_TEXTURE) { - texture_ctrl->clear(); - texture_ctrl->setImageAssetID(LLUUID()); - } + texture_ctrl->clear(); + texture_ctrl->setImageAssetID(LLUUID()); + } + + LLUUID specmap = getCurrentSpecularMap(); - LLUUID specmap = getCurrentSpecularMap(); + U8 shiny = (U8) shininess & TEM_SHINY_MASK; + if (!specmap.isNull()) + shiny = 0; - U8 shiny = (U8) shininess & TEM_SHINY_MASK; - if (!specmap.isNull()) - shiny = 0; + LLSelectedTEMaterial::setSpecularID(this, specmap); - LLSelectedTEMaterial::setSpecularID(this, specmap); + LLSelectMgr::getInstance()->selectionSetShiny( shiny, texture_ctrl->getImageItemID() ); - LLSelectMgr::getInstance()->selectionSetShiny( shiny, texture_ctrl->getImageItemID() ); + updateShinyControls(!specmap.isNull(), true); - updateShinyControls(!specmap.isNull(), true); - } void LLPanelFace::sendFullbright() { - LLCheckBoxCtrl* mCheckFullbright = getChild("checkbox fullbright"); - if(!mCheckFullbright)return; - U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0; - LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); + LLCheckBoxCtrl* mCheckFullbright = getChild("checkbox fullbright"); + if(!mCheckFullbright)return; + U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0; + LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); } void LLPanelFace::sendColor() { - - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); - if(!mColorSwatch)return; - LLColor4 color = mColorSwatch->get(); - LLSelectMgr::getInstance()->selectionSetColorOnly( color ); + LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); + if(!mColorSwatch)return; + LLColor4 color = mColorSwatch->get(); + + LLSelectMgr::getInstance()->selectionSetColorOnly( color ); } void LLPanelFace::sendAlpha() -{ - LLSpinCtrl* mCtrlColorTransp = getChild("ColorTrans"); - if(!mCtrlColorTransp)return; - F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f; +{ + LLSpinCtrl* mCtrlColorTransp = getChild("ColorTrans"); + if(!mCtrlColorTransp)return; + F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f; - LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha ); + LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha ); } void LLPanelFace::sendGlow() { - LLSpinCtrl* mCtrlGlow = getChild("glow"); - llassert(mCtrlGlow); - if (mCtrlGlow) - { - F32 glow = mCtrlGlow->get(); - LLSelectMgr::getInstance()->selectionSetGlow( glow ); - } + LLSpinCtrl* mCtrlGlow = getChild("glow"); + llassert(mCtrlGlow); + if (mCtrlGlow) + { + F32 glow = mCtrlGlow->get(); + LLSelectMgr::getInstance()->selectionSetGlow( glow ); + } } struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor { - LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {} - virtual bool apply(LLViewerObject* object, S32 te) - { - BOOL valid; - F32 value; + LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {} + virtual bool apply(LLViewerObject* object, S32 te) + { + BOOL valid; + F32 value; std::string prefix; // Effectively the same as MATMEDIA_PBR sans using different radio, @@ -674,179 +674,179 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor prefix = "shiny"; break; } - + LLSpinCtrl * ctrlTexScaleS = mPanel->getChild(prefix + "ScaleU"); LLSpinCtrl * ctrlTexScaleT = mPanel->getChild(prefix + "ScaleV"); LLSpinCtrl * ctrlTexOffsetS = mPanel->getChild(prefix + "OffsetU"); LLSpinCtrl * ctrlTexOffsetT = mPanel->getChild(prefix + "OffsetV"); LLSpinCtrl * ctrlTexRotation = mPanel->getChild(prefix + "Rot"); - LLComboBox* comboTexGen = mPanel->getChild("combobox texgen"); - LLCheckBoxCtrl* cb_planar_align = mPanel->getChild("checkbox planar align"); - bool align_planar = (cb_planar_align && cb_planar_align->get()); - - llassert(comboTexGen); - llassert(object); - - if (ctrlTexScaleS) - { - valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative(); - if (valid || align_planar) - { - value = ctrlTexScaleS->get(); - if (comboTexGen && - comboTexGen->getCurrentIndex() == 1) - { - value *= 0.5f; - } - object->setTEScaleS( te, value ); - - if (align_planar) - { - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID()); - } - } - } - - if (ctrlTexScaleT) - { - valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative(); - if (valid || align_planar) - { - value = ctrlTexScaleT->get(); - //if( checkFlipScaleT->get() ) - //{ - // value = -value; - //} - if (comboTexGen && - comboTexGen->getCurrentIndex() == 1) - { - value *= 0.5f; - } - object->setTEScaleT( te, value ); - - if (align_planar) - { - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID()); - } - } - } - - if (ctrlTexOffsetS) - { - valid = !ctrlTexOffsetS->getTentative(); - if (valid || align_planar) - { - value = ctrlTexOffsetS->get(); - object->setTEOffsetS( te, value ); - - if (align_planar) - { - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID()); - } - } - } - - if (ctrlTexOffsetT) - { - valid = !ctrlTexOffsetT->getTentative(); - if (valid || align_planar) - { - value = ctrlTexOffsetT->get(); - object->setTEOffsetT( te, value ); - - if (align_planar) - { - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID()); - } - } - } - - if (ctrlTexRotation) - { - valid = !ctrlTexRotation->getTentative(); - if (valid || align_planar) - { - value = ctrlTexRotation->get() * DEG_TO_RAD; - object->setTERotation( te, value ); - - if (align_planar) - { - LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID()); - } - } - } - return true; - } + LLComboBox* comboTexGen = mPanel->getChild("combobox texgen"); + LLCheckBoxCtrl* cb_planar_align = mPanel->getChild("checkbox planar align"); + bool align_planar = (cb_planar_align && cb_planar_align->get()); + + llassert(comboTexGen); + llassert(object); + + if (ctrlTexScaleS) + { + valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative(); + if (valid || align_planar) + { + value = ctrlTexScaleS->get(); + if (comboTexGen && + comboTexGen->getCurrentIndex() == 1) + { + value *= 0.5f; + } + object->setTEScaleS( te, value ); + + if (align_planar) + { + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID()); + } + } + } + + if (ctrlTexScaleT) + { + valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative(); + if (valid || align_planar) + { + value = ctrlTexScaleT->get(); + //if( checkFlipScaleT->get() ) + //{ + // value = -value; + //} + if (comboTexGen && + comboTexGen->getCurrentIndex() == 1) + { + value *= 0.5f; + } + object->setTEScaleT( te, value ); + + if (align_planar) + { + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID()); + } + } + } + + if (ctrlTexOffsetS) + { + valid = !ctrlTexOffsetS->getTentative(); + if (valid || align_planar) + { + value = ctrlTexOffsetS->get(); + object->setTEOffsetS( te, value ); + + if (align_planar) + { + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID()); + } + } + } + + if (ctrlTexOffsetT) + { + valid = !ctrlTexOffsetT->getTentative(); + if (valid || align_planar) + { + value = ctrlTexOffsetT->get(); + object->setTEOffsetT( te, value ); + + if (align_planar) + { + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID()); + } + } + } + + if (ctrlTexRotation) + { + valid = !ctrlTexRotation->getTentative(); + if (valid || align_planar) + { + value = ctrlTexRotation->get() * DEG_TO_RAD; + object->setTERotation( te, value ); + + if (align_planar) + { + LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID()); + } + } + } + return true; + } private: - LLPanelFace* mPanel; + LLPanelFace* mPanel; }; // Functor that aligns a face to mCenterFace struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor { - LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) : - mPanel(panel), - mCenterFace(center_face) {} - - virtual bool apply(LLViewerObject* object, S32 te) - { - LLFace* facep = object->mDrawable->getFace(te); - if (!facep) - { - return true; - } - - if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) - { - return true; - } - - bool set_aligned = true; - if (facep == mCenterFace) - { - set_aligned = false; - } - if (set_aligned) - { - LLVector2 uv_offset, uv_scale; - F32 uv_rot; - set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot); - if (set_aligned) - { - object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]); - object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]); - object->setTERotation(te, uv_rot); - - LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID()); - - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); - - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); - } - } - if (!set_aligned) - { - LLPanelFaceSetTEFunctor setfunc(mPanel); - setfunc.apply(object, te); - } - return true; - } + LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) : + mPanel(panel), + mCenterFace(center_face) {} + + virtual bool apply(LLViewerObject* object, S32 te) + { + LLFace* facep = object->mDrawable->getFace(te); + if (!facep) + { + return true; + } + + if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) + { + return true; + } + + bool set_aligned = true; + if (facep == mCenterFace) + { + set_aligned = false; + } + if (set_aligned) + { + LLVector2 uv_offset, uv_scale; + F32 uv_rot; + set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot); + if (set_aligned) + { + object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]); + object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]); + object->setTERotation(te, uv_rot); + + LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID()); + + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); + + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); + } + } + if (!set_aligned) + { + LLPanelFaceSetTEFunctor setfunc(mPanel); + setfunc.apply(object, te); + } + return true; + } private: - LLPanelFace* mPanel; - LLFace* mCenterFace; + LLPanelFace* mPanel; + LLFace* mCenterFace; }; struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor @@ -902,7 +902,7 @@ struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor } } } - + return true; } private: @@ -914,36 +914,36 @@ private: // Functor that tests if a face is aligned to mCenterFace struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor { - LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) : - mCenterFace(center_face) {} - - virtual bool apply(LLViewerObject* object, S32 te) - { - LLFace* facep = object->mDrawable->getFace(te); - if (!facep) - { - return false; - } - - if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) - { //volume face does not exist, can't be aligned - return false; - } - - if (facep == mCenterFace) - { - return true; - } - - LLVector2 aligned_st_offset, aligned_st_scale; - F32 aligned_st_rot; - if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) ) - { - const LLTextureEntry* tep = facep->getTextureEntry(); - LLVector2 st_offset, st_scale; - tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]); - tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); - F32 st_rot = tep->getRotation(); + LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) : + mCenterFace(center_face) {} + + virtual bool apply(LLViewerObject* object, S32 te) + { + LLFace* facep = object->mDrawable->getFace(te); + if (!facep) + { + return false; + } + + if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) + { //volume face does not exist, can't be aligned + return false; + } + + if (facep == mCenterFace) + { + return true; + } + + LLVector2 aligned_st_offset, aligned_st_scale; + F32 aligned_st_rot; + if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) ) + { + const LLTextureEntry* tep = facep->getTextureEntry(); + LLVector2 st_offset, st_scale; + tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]); + tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); + F32 st_rot = tep->getRotation(); bool eq_offset_x = is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12); bool eq_offset_y = is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12); @@ -951,49 +951,49 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor bool eq_scale_y = is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12); bool eq_rot = is_approx_equal_fraction(st_rot, aligned_st_rot, 6); - // needs a fuzzy comparison, because of fp errors - if (eq_offset_x && - eq_offset_y && - eq_scale_x && - eq_scale_y && - eq_rot) - { - return true; - } - } - return false; - } + // needs a fuzzy comparison, because of fp errors + if (eq_offset_x && + eq_offset_y && + eq_scale_x && + eq_scale_y && + eq_rot) + { + return true; + } + } + return false; + } private: - LLFace* mCenterFace; + LLFace* mCenterFace; }; struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor { - virtual bool apply(LLViewerObject* object) - { - object->sendTEUpdate(); - return true; - } + virtual bool apply(LLViewerObject* object) + { + object->sendTEUpdate(); + return true; + } }; void LLPanelFace::sendTextureInfo() { - if ((bool)childGetValue("checkbox planar align").asBoolean()) - { - LLFace* last_face = NULL; - bool identical_face =false; - LLSelectedTE::getFace(last_face, identical_face); - LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); - } - else - { - LLPanelFaceSetTEFunctor setfunc(this); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); - } + if ((bool)childGetValue("checkbox planar align").asBoolean()) + { + LLFace* last_face = NULL; + bool identical_face =false; + LLSelectedTE::getFace(last_face, identical_face); + LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); + } + else + { + LLPanelFaceSetTEFunctor setfunc(this); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); + } - LLPanelFaceSendFunctor sendfunc; - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); + LLPanelFaceSendFunctor sendfunc; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } void LLPanelFace::alignTestureLayer() @@ -1009,19 +1009,19 @@ void LLPanelFace::alignTestureLayer() void LLPanelFace::getState() { - updateUI(); + updateUI(); } void LLPanelFace::updateUI(bool force_set_values /*false*/) { //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible) LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); - LLViewerObject* objectp = node ? node->getObject() : NULL; + LLViewerObject* objectp = node ? node->getObject() : NULL; - if (objectp - && objectp->getPCode() == LL_PCODE_VOLUME - && objectp->permModify()) - { - BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); + if (objectp + && objectp->getPCode() == LL_PCODE_VOLUME + && objectp->permModify()) + { + BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); BOOL attachment = objectp->isAttachment(); bool has_pbr_material; @@ -1030,9 +1030,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) const bool has_material = !has_pbr_material; - // only turn on auto-adjust button if there is a media renderer and the media is loaded + // only turn on auto-adjust button if there is a media renderer and the media is loaded childSetEnabled("button align", editable); - + if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL) { // When selecting an object with a pbr and UI combo is not set, @@ -1069,8 +1069,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) static S32 selected_te = -1; static LLUUID prev_obj_id; - if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) && - !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) + if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) && + !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) { S32 new_selection = -1; // Don't use getLastSelectedTE, it could have been deselected S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); @@ -1093,11 +1093,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { mComboMatMedia->selectNthItem(MATMEDIA_PBR); } - else if (te_has_media) + else if (te_has_media) { mComboMatMedia->selectNthItem(MATMEDIA_MEDIA); } - else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull()) + else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull()) { mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); } @@ -1105,11 +1105,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) prev_obj_id = objectp->getID(); } } - else + else { if (prev_obj_id != objectp->getID()) { - if (has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL)) + if (has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL)) { mComboMatMedia->selectNthItem(MATMEDIA_PBR); } @@ -1138,24 +1138,24 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR; const bool texture_info_selected = pbr_selected && radio_pbr_type->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID; - getChildView("checkbox_sync_settings")->setEnabled(editable); - childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings")); + getChildView("checkbox_sync_settings")->setEnabled(editable); + childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings")); - updateVisibility(objectp); + updateVisibility(objectp); - // Color swatch - { - getChildView("color label")->setEnabled(editable); - } - LLColorSwatchCtrl* color_swatch = findChild("colorswatch"); + // Color swatch + { + getChildView("color label")->setEnabled(editable); + } + LLColorSwatchCtrl* color_swatch = findChild("colorswatch"); - LLColor4 color = LLColor4::white; - bool identical_color = false; + LLColor4 color = LLColor4::white; + bool identical_color = false; - if (color_swatch) - { - LLSelectedTE::getColor(color, identical_color); - LLColor4 prev_color = color_swatch->get(); + if (color_swatch) + { + LLSelectedTE::getColor(color, identical_color); + LLColor4 prev_color = color_swatch->get(); color_swatch->setOriginal(color); color_swatch->set(color, force_set_values || (prev_color != color) || !editable); @@ -1163,179 +1163,179 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) color_swatch->setValid(editable && !has_pbr_material); color_swatch->setEnabled( editable && !has_pbr_material); color_swatch->setCanApplyImmediately( editable && !has_pbr_material); - } - - // Color transparency - getChildView("color trans")->setEnabled(editable); - - F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; - getChild("ColorTrans")->setValue(editable ? transparency : 0); - getChildView("ColorTrans")->setEnabled(editable && has_material); - - U8 shiny = 0; - bool identical_shiny = false; - - // Shiny - LLSelectedTE::getShiny(shiny, identical_shiny); - identical = identical && identical_shiny; - - shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; - - LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); - if (combobox_shininess) - { - combobox_shininess->selectNthItem((S32)shiny); - } - - getChildView("label shininess")->setEnabled(editable); - getChildView("combobox shininess")->setEnabled(editable); - - getChildView("label glossiness")->setEnabled(editable); - getChildView("glossiness")->setEnabled(editable); - - getChildView("label environment")->setEnabled(editable); - getChildView("environment")->setEnabled(editable); - getChildView("label shinycolor")->setEnabled(editable); - - getChild("combobox shininess")->setTentative(!identical_spec); - getChild("glossiness")->setTentative(!identical_spec); - getChild("environment")->setTentative(!identical_spec); - getChild("shinycolorswatch")->setTentative(!identical_spec); - - LLColorSwatchCtrl* mShinyColorSwatch = getChild("shinycolorswatch"); - if (mShinyColorSwatch) - { - mShinyColorSwatch->setValid(editable); - mShinyColorSwatch->setEnabled( editable ); - mShinyColorSwatch->setCanApplyImmediately( editable ); - } - - U8 bumpy = 0; - // Bumpy - { - bool identical_bumpy = false; - LLSelectedTE::getBumpmap(bumpy,identical_bumpy); - - LLUUID norm_map_id = getCurrentNormalMap(); - LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); - - bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; - - if (combobox_bumpiness) - { - combobox_bumpiness->selectNthItem((S32)bumpy); - } - else - { - LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL; - } - - getChildView("combobox bumpiness")->setEnabled(editable); - getChild("combobox bumpiness")->setTentative(!identical_bumpy); - getChildView("label bumpiness")->setEnabled(editable); - } - - // Texture - { - mIsAlpha = FALSE; - LLGLenum image_format = GL_RGB; - bool identical_image_format = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format); - - mIsAlpha = FALSE; - switch (image_format) - { - case GL_RGBA: - case GL_ALPHA: - { - mIsAlpha = TRUE; - } - break; - - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; - } - break; - } - - if (LLViewerMedia::getInstance()->textureHasMedia(id)) - { - getChildView("button align")->setEnabled(editable); - } - - // Diffuse Alpha Mode - - // Init to the default that is appropriate for the alpha content of the asset - // - U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - bool identical_alpha_mode = false; - - // See if that's been overridden by a material setting for same... - // - LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); - - LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); - if (combobox_alphamode) - { - //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... - // Want masking? Want emissive? Tough! You get BLEND! - alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; - - // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none - alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - combobox_alphamode->selectNthItem(alpha_mode); - } - else - { - LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; - } - - updateAlphaControls(); - - if (texture_ctrl) - { - if (identical_diffuse) - { - texture_ctrl->setTentative(FALSE); - texture_ctrl->setEnabled(editable && !has_pbr_material); - texture_ctrl->setImageAssetID(id); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); - - texture_ctrl->setBakeTextureEnabled(TRUE); - } - else if (id.isNull()) - { - // None selected - texture_ctrl->setTentative(FALSE); - texture_ctrl->setEnabled(FALSE); - texture_ctrl->setImageAssetID(LLUUID::null); - getChildView("combobox alphamode")->setEnabled(FALSE); - getChildView("label alphamode")->setEnabled(FALSE); - getChildView("maskcutoff")->setEnabled(FALSE); - getChildView("label maskcutoff")->setEnabled(FALSE); - - texture_ctrl->setBakeTextureEnabled(false); - } - else - { - // Tentative: multiple selected with different textures - texture_ctrl->setTentative(TRUE); - texture_ctrl->setEnabled(editable && !has_pbr_material); - texture_ctrl->setImageAssetID(id); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); - - texture_ctrl->setBakeTextureEnabled(TRUE); - } + } + + // Color transparency + getChildView("color trans")->setEnabled(editable); + + F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; + getChild("ColorTrans")->setValue(editable ? transparency : 0); + getChildView("ColorTrans")->setEnabled(editable && has_material); + + U8 shiny = 0; + bool identical_shiny = false; + + // Shiny + LLSelectedTE::getShiny(shiny, identical_shiny); + identical = identical && identical_shiny; + + shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; + + LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); + if (combobox_shininess) + { + combobox_shininess->selectNthItem((S32)shiny); + } + + getChildView("label shininess")->setEnabled(editable); + getChildView("combobox shininess")->setEnabled(editable); + + getChildView("label glossiness")->setEnabled(editable); + getChildView("glossiness")->setEnabled(editable); + + getChildView("label environment")->setEnabled(editable); + getChildView("environment")->setEnabled(editable); + getChildView("label shinycolor")->setEnabled(editable); + + getChild("combobox shininess")->setTentative(!identical_spec); + getChild("glossiness")->setTentative(!identical_spec); + getChild("environment")->setTentative(!identical_spec); + getChild("shinycolorswatch")->setTentative(!identical_spec); + + LLColorSwatchCtrl* mShinyColorSwatch = getChild("shinycolorswatch"); + if (mShinyColorSwatch) + { + mShinyColorSwatch->setValid(editable); + mShinyColorSwatch->setEnabled( editable ); + mShinyColorSwatch->setCanApplyImmediately( editable ); + } + + U8 bumpy = 0; + // Bumpy + { + bool identical_bumpy = false; + LLSelectedTE::getBumpmap(bumpy,identical_bumpy); + + LLUUID norm_map_id = getCurrentNormalMap(); + LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); + + bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; + + if (combobox_bumpiness) + { + combobox_bumpiness->selectNthItem((S32)bumpy); + } + else + { + LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL; + } + + getChildView("combobox bumpiness")->setEnabled(editable); + getChild("combobox bumpiness")->setTentative(!identical_bumpy); + getChildView("label bumpiness")->setEnabled(editable); + } + + // Texture + { + mIsAlpha = FALSE; + LLGLenum image_format = GL_RGB; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format); + + mIsAlpha = FALSE; + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + mIsAlpha = TRUE; + } + break; + + case GL_RGB: break; + default: + { + LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + } + break; + } + + if (LLViewerMedia::getInstance()->textureHasMedia(id)) + { + getChildView("button align")->setEnabled(editable); + } + + // Diffuse Alpha Mode + + // Init to the default that is appropriate for the alpha content of the asset + // + U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + bool identical_alpha_mode = false; + + // See if that's been overridden by a material setting for same... + // + LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + + LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); + if (combobox_alphamode) + { + //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + // Want masking? Want emissive? Tough! You get BLEND! + alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + + // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none + alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + combobox_alphamode->selectNthItem(alpha_mode); + } + else + { + LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; + } + + updateAlphaControls(); + + if (texture_ctrl) + { + if (identical_diffuse) + { + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(editable && !has_pbr_material); + texture_ctrl->setImageAssetID(id); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + + texture_ctrl->setBakeTextureEnabled(TRUE); + } + else if (id.isNull()) + { + // None selected + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(FALSE); + texture_ctrl->setImageAssetID(LLUUID::null); + getChildView("combobox alphamode")->setEnabled(FALSE); + getChildView("label alphamode")->setEnabled(FALSE); + getChildView("maskcutoff")->setEnabled(FALSE); + getChildView("label maskcutoff")->setEnabled(FALSE); + + texture_ctrl->setBakeTextureEnabled(false); + } + else + { + // Tentative: multiple selected with different textures + texture_ctrl->setTentative(TRUE); + texture_ctrl->setEnabled(editable && !has_pbr_material); + texture_ctrl->setImageAssetID(id); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + + texture_ctrl->setBakeTextureEnabled(TRUE); + } if (attachment) { @@ -1348,13 +1348,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { texture_ctrl->setImmediateFilterPermMask(PERM_NONE); } - } + } - if (shinytexture_ctrl) - { - shinytexture_ctrl->setTentative( !identical_spec ); - shinytexture_ctrl->setEnabled( editable && !has_pbr_material); - shinytexture_ctrl->setImageAssetID( specmap_id ); + if (shinytexture_ctrl) + { + shinytexture_ctrl->setTentative( !identical_spec ); + shinytexture_ctrl->setEnabled( editable && !has_pbr_material); + shinytexture_ctrl->setImageAssetID( specmap_id ); if (attachment) { @@ -1364,13 +1364,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { shinytexture_ctrl->setImmediateFilterPermMask(PERM_NONE); } - } + } - if (bumpytexture_ctrl) - { - bumpytexture_ctrl->setTentative( !identical_norm ); - bumpytexture_ctrl->setEnabled( editable && !has_pbr_material); - bumpytexture_ctrl->setImageAssetID( normmap_id ); + if (bumpytexture_ctrl) + { + bumpytexture_ctrl->setTentative( !identical_norm ); + bumpytexture_ctrl->setEnabled( editable && !has_pbr_material); + bumpytexture_ctrl->setImageAssetID( normmap_id ); if (attachment) { @@ -1380,292 +1380,292 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { bumpytexture_ctrl->setImmediateFilterPermMask(PERM_NONE); } - } - } - - // planar align - bool align_planar = false; - bool identical_planar_aligned = false; - { - LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); - align_planar = (cb_planar_align && cb_planar_align->get()); - - bool enabled = (editable && isIdenticalPlanarTexgen() && !texture_info_selected); - childSetValue("checkbox planar align", align_planar && enabled); + } + } + + // planar align + bool align_planar = false; + bool identical_planar_aligned = false; + { + LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); + align_planar = (cb_planar_align && cb_planar_align->get()); + + bool enabled = (editable && isIdenticalPlanarTexgen() && !texture_info_selected); + childSetValue("checkbox planar align", align_planar && enabled); childSetVisible("checkbox planar align", enabled); - childSetEnabled("checkbox planar align", enabled); - childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); - - if (align_planar && enabled) - { - LLFace* last_face = NULL; - bool identical_face = false; - LLSelectedTE::getFace(last_face, identical_face); - - LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); - // this will determine if the texture param controls are tentative: - identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); - } - } - - // Needs to be public and before tex scale settings below to properly reflect - // behavior when in planar vs default texgen modes in the - // NORSPEC-84 et al - // - LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; - bool identical_texgen = true; - bool identical_planar_texgen = false; - - { - LLSelectedTE::getTexGen(selected_texgen, identical_texgen); - identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); - } - - // Texture scale - { - bool identical_diff_scale_s = false; - bool identical_spec_scale_s = false; - bool identical_norm_scale_s = false; - - identical = align_planar ? identical_planar_aligned : identical; - - F32 diff_scale_s = 1.f; - F32 spec_scale_s = 1.f; - F32 norm_scale_s = 1.f; - - LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s); - LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s); - LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s); - - diff_scale_s = editable ? diff_scale_s : 1.0f; - diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - - norm_scale_s = editable ? norm_scale_s : 1.0f; - norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - - spec_scale_s = editable ? spec_scale_s : 1.0f; - spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - - getChild("TexScaleU")->setValue(diff_scale_s); - getChild("shinyScaleU")->setValue(spec_scale_s); - getChild("bumpyScaleU")->setValue(norm_scale_s); + childSetEnabled("checkbox planar align", enabled); + childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); + + if (align_planar && enabled) + { + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); + + LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); + // this will determine if the texture param controls are tentative: + identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); + } + } + + // Needs to be public and before tex scale settings below to properly reflect + // behavior when in planar vs default texgen modes in the + // NORSPEC-84 et al + // + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + bool identical_texgen = true; + bool identical_planar_texgen = false; + + { + LLSelectedTE::getTexGen(selected_texgen, identical_texgen); + identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + } + + // Texture scale + { + bool identical_diff_scale_s = false; + bool identical_spec_scale_s = false; + bool identical_norm_scale_s = false; + + identical = align_planar ? identical_planar_aligned : identical; + + F32 diff_scale_s = 1.f; + F32 spec_scale_s = 1.f; + F32 norm_scale_s = 1.f; + + LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s); + LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s); + LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s); + + diff_scale_s = editable ? diff_scale_s : 1.0f; + diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + norm_scale_s = editable ? norm_scale_s : 1.0f; + norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + spec_scale_s = editable ? spec_scale_s : 1.0f; + spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild("TexScaleU")->setValue(diff_scale_s); + getChild("shinyScaleU")->setValue(spec_scale_s); + getChild("bumpyScaleU")->setValue(norm_scale_s); getChildView("TexScaleU")->setEnabled(editable && has_material); getChildView("shinyScaleU")->setEnabled(editable && has_material && specmap_id.notNull()); getChildView("bumpyScaleU")->setEnabled(editable && has_material && normmap_id.notNull()); - BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); - BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); - BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); + BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); + BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); + BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); - getChild("TexScaleU")->setTentative( LLSD(diff_scale_tentative)); - getChild("shinyScaleU")->setTentative(LLSD(spec_scale_tentative)); - getChild("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative)); - } + getChild("TexScaleU")->setTentative( LLSD(diff_scale_tentative)); + getChild("shinyScaleU")->setTentative(LLSD(spec_scale_tentative)); + getChild("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative)); + } - { - bool identical_diff_scale_t = false; - bool identical_spec_scale_t = false; - bool identical_norm_scale_t = false; + { + bool identical_diff_scale_t = false; + bool identical_spec_scale_t = false; + bool identical_norm_scale_t = false; - F32 diff_scale_t = 1.f; - F32 spec_scale_t = 1.f; - F32 norm_scale_t = 1.f; + F32 diff_scale_t = 1.f; + F32 spec_scale_t = 1.f; + F32 norm_scale_t = 1.f; - LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t); - LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t); - LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t); + LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t); + LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t); + LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t); - diff_scale_t = editable ? diff_scale_t : 1.0f; - diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + diff_scale_t = editable ? diff_scale_t : 1.0f; + diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; - norm_scale_t = editable ? norm_scale_t : 1.0f; - norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + norm_scale_t = editable ? norm_scale_t : 1.0f; + norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; - spec_scale_t = editable ? spec_scale_t : 1.0f; - spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + spec_scale_t = editable ? spec_scale_t : 1.0f; + spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; - BOOL diff_scale_tentative = !identical_diff_scale_t; - BOOL norm_scale_tentative = !identical_norm_scale_t; - BOOL spec_scale_tentative = !identical_spec_scale_t; + BOOL diff_scale_tentative = !identical_diff_scale_t; + BOOL norm_scale_tentative = !identical_norm_scale_t; + BOOL spec_scale_tentative = !identical_spec_scale_t; getChildView("TexScaleV")->setEnabled(editable && has_material); getChildView("shinyScaleV")->setEnabled(editable && has_material && specmap_id.notNull()); getChildView("bumpyScaleV")->setEnabled(editable && has_material && normmap_id.notNull()); - if (force_set_values) - { - getChild("TexScaleV")->forceSetValue(diff_scale_t); - } - else - { - getChild("TexScaleV")->setValue(diff_scale_t); - } - getChild("shinyScaleV")->setValue(norm_scale_t); - getChild("bumpyScaleV")->setValue(spec_scale_t); - - getChild("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); - getChild("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); - getChild("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative)); - } - - // Texture offset - { - bool identical_diff_offset_s = false; - bool identical_norm_offset_s = false; - bool identical_spec_offset_s = false; - - F32 diff_offset_s = 0.0f; - F32 norm_offset_s = 0.0f; - F32 spec_offset_s = 0.0f; - - LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s); - LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s); - LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s); - - BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s); - BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); - BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); - - getChild("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f); - getChild("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); - getChild("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); - - getChild("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); - getChild("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); - getChild("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); + if (force_set_values) + { + getChild("TexScaleV")->forceSetValue(diff_scale_t); + } + else + { + getChild("TexScaleV")->setValue(diff_scale_t); + } + getChild("shinyScaleV")->setValue(norm_scale_t); + getChild("bumpyScaleV")->setValue(spec_scale_t); + + getChild("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); + getChild("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); + getChild("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative)); + } + + // Texture offset + { + bool identical_diff_offset_s = false; + bool identical_norm_offset_s = false; + bool identical_spec_offset_s = false; + + F32 diff_offset_s = 0.0f; + F32 norm_offset_s = 0.0f; + F32 spec_offset_s = 0.0f; + + LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s); + LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s); + LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s); + + BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s); + BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); + BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); + + getChild("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f); + getChild("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); + getChild("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); + + getChild("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); + getChild("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); + getChild("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); getChildView("TexOffsetU")->setEnabled(editable && has_material); getChildView("shinyOffsetU")->setEnabled(editable && has_material && specmap_id.notNull()); getChildView("bumpyOffsetU")->setEnabled(editable && has_material && normmap_id.notNull()); - } + } + + { + bool identical_diff_offset_t = false; + bool identical_norm_offset_t = false; + bool identical_spec_offset_t = false; - { - bool identical_diff_offset_t = false; - bool identical_norm_offset_t = false; - bool identical_spec_offset_t = false; + F32 diff_offset_t = 0.0f; + F32 norm_offset_t = 0.0f; + F32 spec_offset_t = 0.0f; - F32 diff_offset_t = 0.0f; - F32 norm_offset_t = 0.0f; - F32 spec_offset_t = 0.0f; + LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t); + LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t); + LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t); - LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t); - LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t); - LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t); - - BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t); - BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); - BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); + BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t); + BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); + BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); - getChild("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f); - getChild("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); - getChild("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); + getChild("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f); + getChild("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); + getChild("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); - getChild("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); - getChild("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); - getChild("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); + getChild("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); + getChild("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); + getChild("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); getChildView("TexOffsetV")->setEnabled(editable && has_material); getChildView("shinyOffsetV")->setEnabled(editable && has_material && specmap_id.notNull()); getChildView("bumpyOffsetV")->setEnabled(editable && has_material && normmap_id.notNull()); - } + } - // Texture rotation - { - bool identical_diff_rotation = false; - bool identical_norm_rotation = false; - bool identical_spec_rotation = false; + // Texture rotation + { + bool identical_diff_rotation = false; + bool identical_norm_rotation = false; + bool identical_spec_rotation = false; - F32 diff_rotation = 0.f; - F32 norm_rotation = 0.f; - F32 spec_rotation = 0.f; + F32 diff_rotation = 0.f; + F32 norm_rotation = 0.f; + F32 spec_rotation = 0.f; - LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation); - LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation); - LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation); + LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation); + LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation); + LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation); - BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation); - BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation); - BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation); + BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation); + BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation); + BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation); - F32 diff_rot_deg = diff_rotation * RAD_TO_DEG; - F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; - F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; + F32 diff_rot_deg = diff_rotation * RAD_TO_DEG; + F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; + F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; getChildView("TexRot")->setEnabled(editable && has_material); getChildView("shinyRot")->setEnabled(editable && has_material && specmap_id.notNull()); getChildView("bumpyRot")->setEnabled(editable && has_material && normmap_id.notNull()); - getChild("TexRot")->setTentative(diff_rot_tentative); - getChild("shinyRot")->setTentative(LLSD(norm_rot_tentative)); - getChild("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); - - getChild("TexRot")->setValue( editable ? diff_rot_deg : 0.0f); - getChild("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); - getChild("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f); - } - - { - F32 glow = 0.f; - bool identical_glow = false; - LLSelectedTE::getGlow(glow,identical_glow); - getChild("glow")->setValue(glow); - getChild("glow")->setTentative(!identical_glow); - getChildView("glow")->setEnabled(editable); - getChildView("glow label")->setEnabled(editable); - } - - { - LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen"); - if (combobox_texgen) - { - // Maps from enum to combobox entry index - combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); - } - else - { - LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL; - } - - getChildView("combobox texgen")->setEnabled(editable); - getChild("combobox texgen")->setTentative(!identical); - getChildView("tex gen")->setEnabled(editable); - } - - { - U8 fullbright_flag = 0; - bool identical_fullbright = false; - - LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); - - getChild("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); - getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material); - getChild("checkbox fullbright")->setTentative(!identical_fullbright); + getChild("TexRot")->setTentative(diff_rot_tentative); + getChild("shinyRot")->setTentative(LLSD(norm_rot_tentative)); + getChild("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); + + getChild("TexRot")->setValue( editable ? diff_rot_deg : 0.0f); + getChild("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); + getChild("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f); + } + + { + F32 glow = 0.f; + bool identical_glow = false; + LLSelectedTE::getGlow(glow,identical_glow); + getChild("glow")->setValue(glow); + getChild("glow")->setTentative(!identical_glow); + getChildView("glow")->setEnabled(editable); + getChildView("glow label")->setEnabled(editable); + } + + { + LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen"); + if (combobox_texgen) + { + // Maps from enum to combobox entry index + combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); + } + else + { + LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL; + } + + getChildView("combobox texgen")->setEnabled(editable); + getChild("combobox texgen")->setTentative(!identical); + getChildView("tex gen")->setEnabled(editable); + } + + { + U8 fullbright_flag = 0; + bool identical_fullbright = false; + + LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); + + getChild("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); + getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material); + getChild("checkbox fullbright")->setTentative(!identical_fullbright); mComboMatMedia->setEnabledByValue("Materials", !has_pbr_material); - } - - // Repeats per meter - { - F32 repeats_diff = 1.f; - F32 repeats_norm = 1.f; - F32 repeats_spec = 1.f; - - bool identical_diff_repeats = false; - bool identical_norm_repeats = false; - bool identical_spec_repeats = false; - - LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); - LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); - LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); - - LLComboBox* mComboTexGen = getChild("combobox texgen"); - if (mComboTexGen) - { - S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; + } + + // Repeats per meter + { + F32 repeats_diff = 1.f; + F32 repeats_norm = 1.f; + F32 repeats_spec = 1.f; + + bool identical_diff_repeats = false; + bool identical_norm_repeats = false; + bool identical_spec_repeats = false; + + LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); + LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); + LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); + + LLComboBox* mComboTexGen = getChild("combobox texgen"); + if (mComboTexGen) + { + S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; bool enabled = editable && (index != 1); bool identical_repeats = true; S32 material_selection = mComboMatMedia->getCurrentIndex(); - F32 repeats = 1.0f; + F32 repeats = 1.0f; U32 material_type = MATTYPE_DIFFUSE; if (material_selection == MATMEDIA_MATERIAL) @@ -1715,195 +1715,195 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) break; } - BOOL repeats_tentative = !identical_repeats; - - LLSpinCtrl* rpt_ctrl = getChild("rptctrl"); - if (force_set_values) - { - //onCommit, previosly edited element updates related ones - rpt_ctrl->forceSetValue(editable ? repeats : 1.0f); - } - else - { - rpt_ctrl->setValue(editable ? repeats : 1.0f); - } - rpt_ctrl->setTentative(LLSD(repeats_tentative)); + BOOL repeats_tentative = !identical_repeats; + + LLSpinCtrl* rpt_ctrl = getChild("rptctrl"); + if (force_set_values) + { + //onCommit, previosly edited element updates related ones + rpt_ctrl->forceSetValue(editable ? repeats : 1.0f); + } + else + { + rpt_ctrl->setValue(editable ? repeats : 1.0f); + } + rpt_ctrl->setTentative(LLSD(repeats_tentative)); rpt_ctrl->setEnabled(has_material && !identical_planar_texgen && enabled); - } - } + } + } - // Materials - { - LLMaterialPtr material; - LLSelectedTEMaterial::getCurrent(material, identical); + // Materials + { + LLMaterialPtr material; + LLSelectedTEMaterial::getCurrent(material, identical); if (material && editable) - { - LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL; - - // Alpha - LLCtrlSelectionInterface* combobox_alphamode = - childGetSelectionInterface("combobox alphamode"); - if (combobox_alphamode) - { - U32 alpha_mode = material->getDiffuseAlphaMode(); - - if (transparency > 0.f) - { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - } - - if (!mIsAlpha) - { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - } - - combobox_alphamode->selectNthItem(alpha_mode); - } - else - { - LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; - } - getChild("maskcutoff")->setValue(material->getAlphaMaskCutoff()); - updateAlphaControls(); - - identical_planar_texgen = isIdenticalPlanarTexgen(); - - // Shiny (specular) - F32 offset_x, offset_y, repeat_x, repeat_y, rot; - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); - texture_ctrl->setImageAssetID(material->getSpecularID()); - - if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) - { - material->getSpecularOffset(offset_x,offset_y); - material->getSpecularRepeat(repeat_x,repeat_y); - - if (identical_planar_texgen) - { - repeat_x *= 2.0f; - repeat_y *= 2.0f; - } - - rot = material->getSpecularRotation(); - getChild("shinyScaleU")->setValue(repeat_x); - getChild("shinyScaleV")->setValue(repeat_y); - getChild("shinyRot")->setValue(rot*RAD_TO_DEG); - getChild("shinyOffsetU")->setValue(offset_x); - getChild("shinyOffsetV")->setValue(offset_y); - getChild("glossiness")->setValue(material->getSpecularLightExponent()); - getChild("environment")->setValue(material->getEnvironmentIntensity()); + { + LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL; + + // Alpha + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + if (combobox_alphamode) + { + U32 alpha_mode = material->getDiffuseAlphaMode(); + + if (transparency > 0.f) + { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + + if (!mIsAlpha) + { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + } + + combobox_alphamode->selectNthItem(alpha_mode); + } + else + { + LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; + } + getChild("maskcutoff")->setValue(material->getAlphaMaskCutoff()); + updateAlphaControls(); + + identical_planar_texgen = isIdenticalPlanarTexgen(); + + // Shiny (specular) + F32 offset_x, offset_y, repeat_x, repeat_y, rot; + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + texture_ctrl->setImageAssetID(material->getSpecularID()); + + if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) + { + material->getSpecularOffset(offset_x,offset_y); + material->getSpecularRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + repeat_x *= 2.0f; + repeat_y *= 2.0f; + } + + rot = material->getSpecularRotation(); + getChild("shinyScaleU")->setValue(repeat_x); + getChild("shinyScaleV")->setValue(repeat_y); + getChild("shinyRot")->setValue(rot*RAD_TO_DEG); + getChild("shinyOffsetU")->setValue(offset_x); + getChild("shinyOffsetV")->setValue(offset_y); + getChild("glossiness")->setValue(material->getSpecularLightExponent()); + getChild("environment")->setValue(material->getEnvironmentIntensity()); getChild("mirror")->setValue(material->getEnvironmentIntensity()); - updateShinyControls(!material->getSpecularID().isNull(), true); - } - - // Assert desired colorswatch color to match material AFTER updateShinyControls - // to avoid getting overwritten with the default on some UI state changes. - // - if (!material->getSpecularID().isNull()) - { - LLColorSwatchCtrl* shiny_swatch = getChild("shinycolorswatch"); - LLColor4 new_color = material->getSpecularLightColor(); - LLColor4 old_color = shiny_swatch->get(); - - shiny_swatch->setOriginal(new_color); - shiny_swatch->set(new_color, force_set_values || old_color != new_color || !editable); - } - - // Bumpy (normal) - texture_ctrl = getChild("bumpytexture control"); - texture_ctrl->setImageAssetID(material->getNormalID()); - - if (!material->getNormalID().isNull()) - { - material->getNormalOffset(offset_x,offset_y); - material->getNormalRepeat(repeat_x,repeat_y); - - if (identical_planar_texgen) - { - repeat_x *= 2.0f; - repeat_y *= 2.0f; - } - - rot = material->getNormalRotation(); - getChild("bumpyScaleU")->setValue(repeat_x); - getChild("bumpyScaleV")->setValue(repeat_y); - getChild("bumpyRot")->setValue(rot*RAD_TO_DEG); - getChild("bumpyOffsetU")->setValue(offset_x); - getChild("bumpyOffsetV")->setValue(offset_y); - - updateBumpyControls(!material->getNormalID().isNull(), true); - } - } - } + updateShinyControls(!material->getSpecularID().isNull(), true); + } + + // Assert desired colorswatch color to match material AFTER updateShinyControls + // to avoid getting overwritten with the default on some UI state changes. + // + if (!material->getSpecularID().isNull()) + { + LLColorSwatchCtrl* shiny_swatch = getChild("shinycolorswatch"); + LLColor4 new_color = material->getSpecularLightColor(); + LLColor4 old_color = shiny_swatch->get(); + + shiny_swatch->setOriginal(new_color); + shiny_swatch->set(new_color, force_set_values || old_color != new_color || !editable); + } + + // Bumpy (normal) + texture_ctrl = getChild("bumpytexture control"); + texture_ctrl->setImageAssetID(material->getNormalID()); + + if (!material->getNormalID().isNull()) + { + material->getNormalOffset(offset_x,offset_y); + material->getNormalRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + repeat_x *= 2.0f; + repeat_y *= 2.0f; + } + + rot = material->getNormalRotation(); + getChild("bumpyScaleU")->setValue(repeat_x); + getChild("bumpyScaleV")->setValue(repeat_y); + getChild("bumpyRot")->setValue(rot*RAD_TO_DEG); + getChild("bumpyOffsetU")->setValue(offset_x); + getChild("bumpyOffsetV")->setValue(offset_y); + + updateBumpyControls(!material->getNormalID().isNull(), true); + } + } + } S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (selected_count == 1); mMenuClipboardColor->setEnabled(editable && single_volume); - // Set variable values for numeric expressions - LLCalc* calcp = LLCalc::getInstance(); - calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); - calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal()); - calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal()); - calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal()); - calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal()); - calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal()); - calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal()); - } - else - { - // Disable all UICtrls - clearCtrls(); - - // Disable non-UICtrls - LLTextureCtrl* pbr_ctrl = findChild("pbr_control"); + // Set variable values for numeric expressions + LLCalc* calcp = LLCalc::getInstance(); + calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); + calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal()); + calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal()); + calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal()); + calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal()); + calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal()); + calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal()); + } + else + { + // Disable all UICtrls + clearCtrls(); + + // Disable non-UICtrls + LLTextureCtrl* pbr_ctrl = findChild("pbr_control"); if (pbr_ctrl) { pbr_ctrl->setImageAssetID(LLUUID::null); pbr_ctrl->setEnabled(FALSE); } - LLTextureCtrl* texture_ctrl = getChild("texture control"); - if (texture_ctrl) - { - texture_ctrl->setImageAssetID( LLUUID::null ); - texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. -// texture_ctrl->setValid(FALSE); - } - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); - if (mColorSwatch) - { - mColorSwatch->setEnabled( FALSE ); - mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") ); - mColorSwatch->setValid(FALSE); - } - LLRadioGroup* radio_mat_type = getChild("radio_material_type"); - if (radio_mat_type) - { - radio_mat_type->setSelectedIndex(0); - } - getChildView("color trans")->setEnabled(FALSE); - getChildView("rptctrl")->setEnabled(FALSE); - getChildView("tex gen")->setEnabled(FALSE); - getChildView("label shininess")->setEnabled(FALSE); - getChildView("label bumpiness")->setEnabled(FALSE); - getChildView("button align")->setEnabled(FALSE); + LLTextureCtrl* texture_ctrl = getChild("texture control"); + if (texture_ctrl) + { + texture_ctrl->setImageAssetID( LLUUID::null ); + texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. +// texture_ctrl->setValid(FALSE); + } + LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); + if (mColorSwatch) + { + mColorSwatch->setEnabled( FALSE ); + mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") ); + mColorSwatch->setValid(FALSE); + } + LLRadioGroup* radio_mat_type = getChild("radio_material_type"); + if (radio_mat_type) + { + radio_mat_type->setSelectedIndex(0); + } + getChildView("color trans")->setEnabled(FALSE); + getChildView("rptctrl")->setEnabled(FALSE); + getChildView("tex gen")->setEnabled(FALSE); + getChildView("label shininess")->setEnabled(FALSE); + getChildView("label bumpiness")->setEnabled(FALSE); + getChildView("button align")->setEnabled(FALSE); getChildView("pbr_from_inventory")->setEnabled(FALSE); getChildView("edit_selected_pbr")->setEnabled(FALSE); getChildView("save_selected_pbr")->setEnabled(FALSE); - - updateVisibility(); - // Set variable values for numeric expressions - LLCalc* calcp = LLCalc::getInstance(); - calcp->clearVar(LLCalc::TEX_U_SCALE); - calcp->clearVar(LLCalc::TEX_V_SCALE); - calcp->clearVar(LLCalc::TEX_U_OFFSET); - calcp->clearVar(LLCalc::TEX_V_OFFSET); - calcp->clearVar(LLCalc::TEX_ROTATION); - calcp->clearVar(LLCalc::TEX_TRANSPARENCY); - calcp->clearVar(LLCalc::TEX_GLOW); - } + updateVisibility(); + + // Set variable values for numeric expressions + LLCalc* calcp = LLCalc::getInstance(); + calcp->clearVar(LLCalc::TEX_U_SCALE); + calcp->clearVar(LLCalc::TEX_V_SCALE); + calcp->clearVar(LLCalc::TEX_U_OFFSET); + calcp->clearVar(LLCalc::TEX_V_OFFSET); + calcp->clearVar(LLCalc::TEX_ROTATION); + calcp->clearVar(LLCalc::TEX_TRANSPARENCY); + calcp->clearVar(LLCalc::TEX_GLOW); + } } // One-off listener that updates the build floater UI when the agent inventory adds or removes an item @@ -1912,7 +1912,7 @@ class PBRPickerAgentListener : public LLInventoryObserver protected: bool mChangePending = true; public: - PBRPickerAgentListener() : LLInventoryObserver() + PBRPickerAgentListener() : LLInventoryObserver() { gInventory.addObserver(this); } @@ -1922,7 +1922,7 @@ public: return mChangePending; } - void changed(U32 mask) override + void changed(U32 mask) override { if (!(mask & (ADD | REMOVE))) { @@ -2092,8 +2092,8 @@ void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */) void LLPanelFace::updateCopyTexButton() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() - && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() + mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() + && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1) && LLMaterialEditor::canClipboardObjectsMaterial()); std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); @@ -2102,8 +2102,8 @@ void LLPanelFace::updateCopyTexButton() void LLPanelFace::refresh() { - LL_DEBUGS("Materials") << LL_ENDL; - getState(); + LL_DEBUGS("Materials") << LL_ENDL; + getState(); } void LLPanelFace::refreshMedia() @@ -2224,7 +2224,7 @@ void LLPanelFace::refreshMedia() // initial media title is the media URL (until we get the name) media_title = media_data_get.getHomeURL(); } - // else all faces might be empty. + // else all faces might be empty. } else // there' re Different Medias' been set on on the faces. { @@ -2296,19 +2296,19 @@ void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side) // void LLPanelFace::navigateToTitleMedia( const std::string url ) { - std::string multi_media_info_str = LLTrans::getString("Multiple Media"); - if (url.empty() || multi_media_info_str == url) - { - // nothing to show - mNeedMediaTitle = false; - } - else if (mTitleMedia) - { - LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); - // check if url changed or if we need a new media source - if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) - { - mTitleMedia->navigateTo( url ); + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + if (url.empty() || multi_media_info_str == url) + { + // nothing to show + mNeedMediaTitle = false; + } + else if (mTitleMedia) + { + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + // check if url changed or if we need a new media source + if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) + { + mTitleMedia->navigateTo( url ); LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID()); if (impl) @@ -2316,11 +2316,11 @@ void LLPanelFace::navigateToTitleMedia( const std::string url ) // if it's a page with a movie, we don't want to hear it impl->setVolume(0); }; - } + } - // flag that we need to update the title (even if no request were made) - mNeedMediaTitle = true; - } + // flag that we need to update the title (even if no request were made) + mNeedMediaTitle = true; + } } bool LLPanelFace::selectedMediaEditable() @@ -2379,7 +2379,7 @@ void LLPanelFace::updateMediaSettings() const LLMediaEntry default_media_data; - // controls + // controls U8 value_u8 = default_media_data.getControls(); struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > { @@ -2868,58 +2868,58 @@ void LLPanelFace::updateMediaTitle() // static F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face) { - return (F32)(object->getTE(face)->getGlow()); + return (F32)(object->getTE(face)->getGlow()); } void LLPanelFace::onCommitColor(const LLSD& data) { - sendColor(); + sendColor(); } void LLPanelFace::onCommitShinyColor(const LLSD& data) { - LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); + LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); } void LLPanelFace::onCommitAlpha(const LLSD& data) { - sendAlpha(); + sendAlpha(); } void LLPanelFace::onCancelColor(const LLSD& data) { - LLSelectMgr::getInstance()->selectionRevertColors(); + LLSelectMgr::getInstance()->selectionRevertColors(); } void LLPanelFace::onCancelShinyColor(const LLSD& data) { - LLSelectMgr::getInstance()->selectionRevertShinyColors(); + LLSelectMgr::getInstance()->selectionRevertShinyColors(); } void LLPanelFace::onSelectColor(const LLSD& data) { - LLSelectMgr::getInstance()->saveSelectedObjectColors(); - sendColor(); + LLSelectMgr::getInstance()->saveSelectedObjectColors(); + sendColor(); } void LLPanelFace::onSelectShinyColor(const LLSD& data) { - LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); - LLSelectMgr::getInstance()->saveSelectedShinyColors(); + LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); + LLSelectMgr::getInstance()->saveSelectedShinyColors(); } // static void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - // Force to default states to side-step problems with menu contents - // and generally reflecting old state when switching tabs or objects - // - self->updateShinyControls(false,true); - self->updateBumpyControls(false,true); - self->updateUI(); - self->refreshMedia(); + LLPanelFace* self = (LLPanelFace*) userdata; + // Force to default states to side-step problems with menu contents + // and generally reflecting old state when switching tabs or objects + // + self->updateShinyControls(false,true); + self->updateBumpyControls(false,true); + self->updateUI(); + self->refreshMedia(); } void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */) @@ -2928,18 +2928,18 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */) LLRadioGroup* radio_pbr_type = findChild("radio_pbr_type"); LLComboBox* combo_shininess = findChild("combobox shininess"); LLComboBox* combo_bumpiness = findChild("combobox bumpiness"); - if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness) - { - LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; - return; - } - U32 materials_media = mComboMatMedia->getCurrentIndex(); - U32 material_type = radio_mat_type->getSelectedIndex(); - bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled(); + if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness) + { + LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; + return; + } + U32 materials_media = mComboMatMedia->getCurrentIndex(); + U32 material_type = radio_mat_type->getSelectedIndex(); + bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled(); bool show_material = materials_media == MATMEDIA_MATERIAL; - bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled())); - bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled(); - bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); + bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled())); + bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled(); + bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled(); const U32 pbr_type = findChild("radio_pbr_type")->getSelectedIndex(); const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type); @@ -2953,62 +2953,62 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */) getChildView("combobox texgen")->setVisible(show_material || show_media || show_pbr_asset); getChildView("button align textures")->setVisible(show_material || show_media); - // Media controls + // Media controls mTitleMediaText->setVisible(show_media); - getChildView("add_media")->setVisible(show_media); - getChildView("delete_media")->setVisible(show_media); - getChildView("button align")->setVisible(show_media); - - // Diffuse texture controls - getChildView("texture control")->setVisible(show_texture && show_material); - getChildView("label alphamode")->setVisible(show_texture && show_material); - getChildView("combobox alphamode")->setVisible(show_texture && show_material); - getChildView("label maskcutoff")->setVisible(false); - getChildView("maskcutoff")->setVisible(false); - if (show_texture && show_material) - { - updateAlphaControls(); - } + getChildView("add_media")->setVisible(show_media); + getChildView("delete_media")->setVisible(show_media); + getChildView("button align")->setVisible(show_media); + + // Diffuse texture controls + getChildView("texture control")->setVisible(show_texture && show_material); + getChildView("label alphamode")->setVisible(show_texture && show_material); + getChildView("combobox alphamode")->setVisible(show_texture && show_material); + getChildView("label maskcutoff")->setVisible(false); + getChildView("maskcutoff")->setVisible(false); + if (show_texture && show_material) + { + updateAlphaControls(); + } // texture scale and position controls - getChildView("TexScaleU")->setVisible(show_texture); - getChildView("TexScaleV")->setVisible(show_texture); - getChildView("TexRot")->setVisible(show_texture); - getChildView("TexOffsetU")->setVisible(show_texture); - getChildView("TexOffsetV")->setVisible(show_texture); - - // Specular map controls - getChildView("shinytexture control")->setVisible(show_shininess); - getChildView("combobox shininess")->setVisible(show_shininess); - getChildView("label shininess")->setVisible(show_shininess); - getChildView("label glossiness")->setVisible(false); - getChildView("glossiness")->setVisible(false); - getChildView("label environment")->setVisible(false); - getChildView("environment")->setVisible(false); - getChildView("label shinycolor")->setVisible(false); - getChildView("shinycolorswatch")->setVisible(false); - if (show_shininess) - { - updateShinyControls(); - } - getChildView("shinyScaleU")->setVisible(show_shininess); - getChildView("shinyScaleV")->setVisible(show_shininess); - getChildView("shinyRot")->setVisible(show_shininess); - getChildView("shinyOffsetU")->setVisible(show_shininess); - getChildView("shinyOffsetV")->setVisible(show_shininess); - - // Normal map controls - if (show_bumpiness) - { - updateBumpyControls(); - } - getChildView("bumpytexture control")->setVisible(show_bumpiness); - getChildView("combobox bumpiness")->setVisible(show_bumpiness); - getChildView("label bumpiness")->setVisible(show_bumpiness); - getChildView("bumpyScaleU")->setVisible(show_bumpiness); - getChildView("bumpyScaleV")->setVisible(show_bumpiness); - getChildView("bumpyRot")->setVisible(show_bumpiness); - getChildView("bumpyOffsetU")->setVisible(show_bumpiness); - getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + getChildView("TexScaleU")->setVisible(show_texture); + getChildView("TexScaleV")->setVisible(show_texture); + getChildView("TexRot")->setVisible(show_texture); + getChildView("TexOffsetU")->setVisible(show_texture); + getChildView("TexOffsetV")->setVisible(show_texture); + + // Specular map controls + getChildView("shinytexture control")->setVisible(show_shininess); + getChildView("combobox shininess")->setVisible(show_shininess); + getChildView("label shininess")->setVisible(show_shininess); + getChildView("label glossiness")->setVisible(false); + getChildView("glossiness")->setVisible(false); + getChildView("label environment")->setVisible(false); + getChildView("environment")->setVisible(false); + getChildView("label shinycolor")->setVisible(false); + getChildView("shinycolorswatch")->setVisible(false); + if (show_shininess) + { + updateShinyControls(); + } + getChildView("shinyScaleU")->setVisible(show_shininess); + getChildView("shinyScaleV")->setVisible(show_shininess); + getChildView("shinyRot")->setVisible(show_shininess); + getChildView("shinyOffsetU")->setVisible(show_shininess); + getChildView("shinyOffsetV")->setVisible(show_shininess); + + // Normal map controls + if (show_bumpiness) + { + updateBumpyControls(); + } + getChildView("bumpytexture control")->setVisible(show_bumpiness); + getChildView("combobox bumpiness")->setVisible(show_bumpiness); + getChildView("label bumpiness")->setVisible(show_bumpiness); + getChildView("bumpyScaleU")->setVisible(show_bumpiness); + getChildView("bumpyScaleV")->setVisible(show_bumpiness); + getChildView("bumpyRot")->setVisible(show_bumpiness); + getChildView("bumpyOffsetU")->setVisible(show_bumpiness); + getChildView("bumpyOffsetV")->setVisible(show_bumpiness); getChild("rptctrl")->setVisible(show_material || show_media); @@ -3020,11 +3020,11 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */) void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - // Force to default states to side-step problems with menu contents - // and generally reflecting old state when switching tabs or objects - // - self->updateShinyControls(false,true); - self->updateBumpyControls(false,true); + // Force to default states to side-step problems with menu contents + // and generally reflecting old state when switching tabs or objects + // + self->updateShinyControls(false,true); + self->updateBumpyControls(false,true); self->updateUI(); } @@ -3041,149 +3041,149 @@ void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata) // static void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; + LLPanelFace* self = (LLPanelFace*) userdata; - LLComboBox* mComboBumpiness = self->getChild("combobox bumpiness"); - if(!mComboBumpiness) - return; + LLComboBox* mComboBumpiness = self->getChild("combobox bumpiness"); + if(!mComboBumpiness) + return; - U32 bumpiness = mComboBumpiness->getCurrentIndex(); + U32 bumpiness = mComboBumpiness->getCurrentIndex(); - self->sendBump(bumpiness); + self->sendBump(bumpiness); } // static void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendTexGen(); + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendTexGen(); } // static void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox) { - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); - LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); - LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; - LLComboBox* comboShiny = getChild("combobox shininess"); - - if(mess_with_shiny_combobox) - { - if (!comboShiny) - { - return; - } - if (!shiny_texture_ID.isNull() && is_setting_texture) - { - if (!comboShiny->itemExists(USE_TEXTURE)) - { - comboShiny->add(USE_TEXTURE); - } - comboShiny->setSimple(USE_TEXTURE); - } - else - { - if (comboShiny->itemExists(USE_TEXTURE)) - { - comboShiny->remove(SHINY_TEXTURE); - comboShiny->selectFirstItem(); - } - } - } - else - { - if (shiny_texture_ID.isNull() && comboShiny && comboShiny->itemExists(USE_TEXTURE)) - { - comboShiny->remove(SHINY_TEXTURE); - comboShiny->selectFirstItem(); - } - } - - - LLRadioGroup* radio_mat_type = getChild("radio_material_type"); - U32 materials_media = mComboMatMedia->getCurrentIndex(); - U32 material_type = radio_mat_type->getSelectedIndex(); - bool show_material = (materials_media == MATMEDIA_MATERIAL); - bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); - U32 shiny_value = comboShiny->getCurrentIndex(); - bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture - getChildView("label glossiness")->setVisible(show_shinyctrls); - getChildView("glossiness")->setVisible(show_shinyctrls); - getChildView("label environment")->setVisible(show_shinyctrls); - getChildView("environment")->setVisible(show_shinyctrls); - getChildView("label shinycolor")->setVisible(show_shinyctrls); - getChildView("shinycolorswatch")->setVisible(show_shinyctrls); + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; + LLComboBox* comboShiny = getChild("combobox shininess"); + + if(mess_with_shiny_combobox) + { + if (!comboShiny) + { + return; + } + if (!shiny_texture_ID.isNull() && is_setting_texture) + { + if (!comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->add(USE_TEXTURE); + } + comboShiny->setSimple(USE_TEXTURE); + } + else + { + if (comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->remove(SHINY_TEXTURE); + comboShiny->selectFirstItem(); + } + } + } + else + { + if (shiny_texture_ID.isNull() && comboShiny && comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->remove(SHINY_TEXTURE); + comboShiny->selectFirstItem(); + } + } + + + LLRadioGroup* radio_mat_type = getChild("radio_material_type"); + U32 materials_media = mComboMatMedia->getCurrentIndex(); + U32 material_type = radio_mat_type->getSelectedIndex(); + bool show_material = (materials_media == MATMEDIA_MATERIAL); + bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); + U32 shiny_value = comboShiny->getCurrentIndex(); + bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture + getChildView("label glossiness")->setVisible(show_shinyctrls); + getChildView("glossiness")->setVisible(show_shinyctrls); + getChildView("label environment")->setVisible(show_shinyctrls); + getChildView("environment")->setVisible(show_shinyctrls); + getChildView("label shinycolor")->setVisible(show_shinyctrls); + getChildView("shinycolorswatch")->setVisible(show_shinyctrls); } // static void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox) { - LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); - LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); - LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; - LLComboBox* comboBumpy = getChild("combobox bumpiness"); - if (!comboBumpy) - { - return; - } - - if (mess_with_combobox) - { - LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); - LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); - LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; - - if (!bumpy_texture_ID.isNull() && is_setting_texture) - { - if (!comboBumpy->itemExists(USE_TEXTURE)) - { - comboBumpy->add(USE_TEXTURE); - } - comboBumpy->setSimple(USE_TEXTURE); - } - else - { - if (comboBumpy->itemExists(USE_TEXTURE)) - { - comboBumpy->remove(BUMPY_TEXTURE); - comboBumpy->selectFirstItem(); - } - } - } + LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + LLComboBox* comboBumpy = getChild("combobox bumpiness"); + if (!comboBumpy) + { + return; + } + + if (mess_with_combobox) + { + LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + + if (!bumpy_texture_ID.isNull() && is_setting_texture) + { + if (!comboBumpy->itemExists(USE_TEXTURE)) + { + comboBumpy->add(USE_TEXTURE); + } + comboBumpy->setSimple(USE_TEXTURE); + } + else + { + if (comboBumpy->itemExists(USE_TEXTURE)) + { + comboBumpy->remove(BUMPY_TEXTURE); + comboBumpy->selectFirstItem(); + } + } + } } // static void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; + LLPanelFace* self = (LLPanelFace*) userdata; + + LLComboBox* mComboShininess = self->getChild("combobox shininess"); + if(!mComboShininess) + return; - LLComboBox* mComboShininess = self->getChild("combobox shininess"); - if(!mComboShininess) - return; - - U32 shininess = mComboShininess->getCurrentIndex(); + U32 shininess = mComboShininess->getCurrentIndex(); - self->sendShiny(shininess); + self->sendShiny(shininess); } // static void LLPanelFace::updateAlphaControls() { - LLComboBox* comboAlphaMode = getChild("combobox alphamode"); - if (!comboAlphaMode) - { - return; - } - U32 alpha_value = comboAlphaMode->getCurrentIndex(); - bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking - + LLComboBox* comboAlphaMode = getChild("combobox alphamode"); + if (!comboAlphaMode) + { + return; + } + U32 alpha_value = comboAlphaMode->getCurrentIndex(); + bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking + U32 mat_media = MATMEDIA_MATERIAL; if (mComboMatMedia) { mat_media = mComboMatMedia->getCurrentIndex(); } - + U32 mat_type = MATTYPE_DIFFUSE; LLRadioGroup* radio_mat_type = getChild("radio_material_type"); if(radio_mat_type) @@ -3193,31 +3193,31 @@ void LLPanelFace::updateAlphaControls() show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL); show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE); - - getChildView("label maskcutoff")->setVisible(show_alphactrls); - getChildView("maskcutoff")->setVisible(show_alphactrls); + + getChildView("label maskcutoff")->setVisible(show_alphactrls); + getChildView("maskcutoff")->setVisible(show_alphactrls); } // static void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->updateAlphaControls(); - LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode()); + LLPanelFace* self = (LLPanelFace*) userdata; + self->updateAlphaControls(); + LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode()); } // static void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendFullbright(); + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendFullbright(); } // static void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendGlow(); + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendGlow(); } // static @@ -3306,102 +3306,102 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item) void LLPanelFace::onCommitTexture( const LLSD& data ) { - add(LLStatViewer::EDIT_TEXTURE, 1); - sendTexture(); + add(LLStatViewer::EDIT_TEXTURE, 1); + sendTexture(); } void LLPanelFace::onCancelTexture(const LLSD& data) { - LLSelectMgr::getInstance()->selectionRevertTextures(); + LLSelectMgr::getInstance()->selectionRevertTextures(); } void LLPanelFace::onSelectTexture(const LLSD& data) { - LLSelectMgr::getInstance()->saveSelectedObjectTextures(); - sendTexture(); - - LLGLenum image_format; - bool identical_image_format = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format); - - LLCtrlSelectionInterface* combobox_alphamode = - childGetSelectionInterface("combobox alphamode"); - - U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - if (combobox_alphamode) - { - switch (image_format) - { - case GL_RGBA: - case GL_ALPHA: - { - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - } - break; - - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; - } - break; - } - - combobox_alphamode->selectNthItem(alpha_mode); - } - LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); + LLSelectMgr::getInstance()->saveSelectedObjectTextures(); + sendTexture(); + + LLGLenum image_format; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format); + + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + if (combobox_alphamode) + { + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + break; + + case GL_RGB: break; + default: + { + LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + } + break; + } + + combobox_alphamode->selectNthItem(alpha_mode); + } + LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); } void LLPanelFace::onCloseTexturePicker(const LLSD& data) { - LL_DEBUGS("Materials") << data << LL_ENDL; - updateUI(); + LL_DEBUGS("Materials") << data << LL_ENDL; + updateUI(); } void LLPanelFace::onCommitSpecularTexture( const LLSD& data ) { - LL_DEBUGS("Materials") << data << LL_ENDL; - sendShiny(SHINY_TEXTURE); + LL_DEBUGS("Materials") << data << LL_ENDL; + sendShiny(SHINY_TEXTURE); } void LLPanelFace::onCommitNormalTexture( const LLSD& data ) { - LL_DEBUGS("Materials") << data << LL_ENDL; - LLUUID nmap_id = getCurrentNormalMap(); - sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); + LL_DEBUGS("Materials") << data << LL_ENDL; + LLUUID nmap_id = getCurrentNormalMap(); + sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } void LLPanelFace::onCancelSpecularTexture(const LLSD& data) { - U8 shiny = 0; - bool identical_shiny = false; - LLSelectedTE::getShiny(shiny, identical_shiny); - LLUUID spec_map_id = getChild("shinytexture control")->getImageAssetID(); - shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; - sendShiny(shiny); + U8 shiny = 0; + bool identical_shiny = false; + LLSelectedTE::getShiny(shiny, identical_shiny); + LLUUID spec_map_id = getChild("shinytexture control")->getImageAssetID(); + shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; + sendShiny(shiny); } void LLPanelFace::onCancelNormalTexture(const LLSD& data) { - U8 bumpy = 0; - bool identical_bumpy = false; - LLSelectedTE::getBumpmap(bumpy, identical_bumpy); - LLUUID spec_map_id = getChild("bumpytexture control")->getImageAssetID(); - bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE; - sendBump(bumpy); + U8 bumpy = 0; + bool identical_bumpy = false; + LLSelectedTE::getBumpmap(bumpy, identical_bumpy); + LLUUID spec_map_id = getChild("bumpytexture control")->getImageAssetID(); + bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE; + sendBump(bumpy); } void LLPanelFace::onSelectSpecularTexture(const LLSD& data) { - LL_DEBUGS("Materials") << data << LL_ENDL; - sendShiny(SHINY_TEXTURE); + LL_DEBUGS("Materials") << data << LL_ENDL; + sendShiny(SHINY_TEXTURE); } void LLPanelFace::onSelectNormalTexture(const LLSD& data) { - LL_DEBUGS("Materials") << data << LL_ENDL; - LLUUID nmap_id = getCurrentNormalMap(); - sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); + LL_DEBUGS("Materials") << data << LL_ENDL; + LLUUID nmap_id = getCurrentNormalMap(); + sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } ////////////////////////////////////////////////////////////////////////////// @@ -3478,212 +3478,212 @@ bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const L //static void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU) { - LLSelectedTEMaterial::setNormalOffsetX(self,offsetU); - LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU); - self->getChild("TexOffsetU")->forceSetValue(offsetU); - self->sendTextureInfo(); + LLSelectedTEMaterial::setNormalOffsetX(self,offsetU); + LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU); + self->getChild("TexOffsetU")->forceSetValue(offsetU); + self->sendTextureInfo(); } //static void LLPanelFace::syncOffsetY(LLPanelFace* self, F32 offsetV) { - LLSelectedTEMaterial::setNormalOffsetY(self,offsetV); - LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV); - self->getChild("TexOffsetV")->forceSetValue(offsetV); - self->sendTextureInfo(); + LLSelectedTEMaterial::setNormalOffsetY(self,offsetV); + LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV); + self->getChild("TexOffsetV")->forceSetValue(offsetV); + self->sendTextureInfo(); } //static void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetX(self,self->getCurrentBumpyOffsetU()); - } - else - { - LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); - } + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self,self->getCurrentBumpyOffsetU()); + } + else + { + LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); + } } //static void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetY(self,self->getCurrentBumpyOffsetV()); - } - else - { - LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); - } + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self,self->getCurrentBumpyOffsetV()); + } + else + { + LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); + } } //static void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetX(self, self->getCurrentShinyOffsetU()); - } - else - { - LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); - } + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self, self->getCurrentShinyOffsetU()); + } + else + { + LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); + } } //static void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetY(self,self->getCurrentShinyOffsetV()); - } - else - { - LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); - } + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self,self->getCurrentShinyOffsetV()); + } + else + { + LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); + } } //static void LLPanelFace::syncRepeatX(LLPanelFace* self, F32 scaleU) { - LLSelectedTEMaterial::setNormalRepeatX(self,scaleU); - LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU); - self->sendTextureInfo(); + LLSelectedTEMaterial::setNormalRepeatX(self,scaleU); + LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU); + self->sendTextureInfo(); } //static void LLPanelFace::syncRepeatY(LLPanelFace* self, F32 scaleV) { - LLSelectedTEMaterial::setNormalRepeatY(self,scaleV); - LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV); - self->sendTextureInfo(); + LLSelectedTEMaterial::setNormalRepeatY(self,scaleV); + LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV); + self->sendTextureInfo(); } //static void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); - if (self->isIdenticalPlanarTexgen()) - { - bumpy_scale_u *= 0.5f; - } - - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU()); - syncRepeatX(self, bumpy_scale_u); - } - else - { - LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); - } + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_u *= 0.5f; + } + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU()); + syncRepeatX(self, bumpy_scale_u); + } + else + { + LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); + } } //static void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); - if (self->isIdenticalPlanarTexgen()) - { - bumpy_scale_v *= 0.5f; - } + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_v *= 0.5f; + } - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV()); - syncRepeatY(self, bumpy_scale_v); - } - else - { - LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); - } + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV()); + syncRepeatY(self, bumpy_scale_v); + } + else + { + LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); + } } //static void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 shiny_scale_u = self->getCurrentShinyScaleU(); - if (self->isIdenticalPlanarTexgen()) - { - shiny_scale_u *= 0.5f; - } - - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU()); - syncRepeatX(self, shiny_scale_u); - } - else - { - LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); - } + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 shiny_scale_u = self->getCurrentShinyScaleU(); + if (self->isIdenticalPlanarTexgen()) + { + shiny_scale_u *= 0.5f; + } + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU()); + syncRepeatX(self, shiny_scale_u); + } + else + { + LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); + } } //static void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 shiny_scale_v = self->getCurrentShinyScaleV(); - if (self->isIdenticalPlanarTexgen()) - { - shiny_scale_v *= 0.5f; - } - - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV()); - syncRepeatY(self, shiny_scale_v); - } - else - { - LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); - } + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 shiny_scale_v = self->getCurrentShinyScaleV(); + if (self->isIdenticalPlanarTexgen()) + { + shiny_scale_v *= 0.5f; + } + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV()); + syncRepeatY(self, shiny_scale_v); + } + else + { + LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); + } } //static void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot, int te) { - LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te); - LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te); - self->sendTextureInfo(); + LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te); + LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te); + self->sendTextureInfo(); } //static void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexRot")->forceSetValue(self->getCurrentBumpyRot()); - syncMaterialRot(self, self->getCurrentBumpyRot()); - } - else - { + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexRot")->forceSetValue(self->getCurrentBumpyRot()); + syncMaterialRot(self, self->getCurrentBumpyRot()); + } + else + { if ((bool)self->childGetValue("checkbox planar align").asBoolean()) { LLFace* last_face = NULL; @@ -3696,22 +3696,22 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) { LLSelectedTEMaterial::setNormalRotation(self, self->getCurrentBumpyRot() * DEG_TO_RAD); } - } + } } //static void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - self->getChild("TexRot")->forceSetValue(self->getCurrentShinyRot()); - syncMaterialRot(self, self->getCurrentShinyRot()); - } - else - { + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexRot")->forceSetValue(self->getCurrentShinyRot()); + syncMaterialRot(self, self->getCurrentShinyRot()); + } + else + { if ((bool)self->childGetValue("checkbox planar align").asBoolean()) { LLFace* last_face = NULL; @@ -3724,136 +3724,136 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) { LLSelectedTEMaterial::setSpecularRotation(self, self->getCurrentShinyRot() * DEG_TO_RAD); } - } + } } //static void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); } //static void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); } //static void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); + LLPanelFace* self = (LLPanelFace*) userdata; + LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); } // static void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendTextureInfo(); - // vertical scale and repeats per meter depends on each other, so force set on changes - self->updateUI(true); + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendTextureInfo(); + // vertical scale and repeats per meter depends on each other, so force set on changes + self->updateUI(true); } // static void LLPanelFace::onCommitTextureScaleX( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - F32 bumpy_scale_u = self->getChild("TexScaleU")->getValue().asReal(); - if (self->isIdenticalPlanarTexgen()) - { - bumpy_scale_u *= 0.5f; - } - syncRepeatX(self, bumpy_scale_u); - } - else - { - self->sendTextureInfo(); - } - self->updateUI(true); + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + F32 bumpy_scale_u = self->getChild("TexScaleU")->getValue().asReal(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_u *= 0.5f; + } + syncRepeatX(self, bumpy_scale_u); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); } // static void LLPanelFace::onCommitTextureScaleY( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - F32 bumpy_scale_v = self->getChild("TexScaleV")->getValue().asReal(); - if (self->isIdenticalPlanarTexgen()) - { - bumpy_scale_v *= 0.5f; - } - syncRepeatY(self, bumpy_scale_v); - } - else - { - self->sendTextureInfo(); - } - self->updateUI(true); + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + F32 bumpy_scale_v = self->getChild("TexScaleV")->getValue().asReal(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_v *= 0.5f; + } + syncRepeatY(self, bumpy_scale_v); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); } // static void LLPanelFace::onCommitTextureRot( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; + LLPanelFace* self = (LLPanelFace*) userdata; - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncMaterialRot(self, self->getChild("TexRot")->getValue().asReal()); - } - else - { - self->sendTextureInfo(); - } - self->updateUI(true); + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncMaterialRot(self, self->getChild("TexRot")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); } // static void LLPanelFace::onCommitTextureOffsetX( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetX(self, self->getChild("TexOffsetU")->getValue().asReal()); - } - else - { - self->sendTextureInfo(); - } - self->updateUI(true); + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self, self->getChild("TexOffsetU")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); } // static void LLPanelFace::onCommitTextureOffsetY( LLUICtrl* ctrl, void* userdata ) { - LLPanelFace* self = (LLPanelFace*) userdata; - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - syncOffsetY(self, self->getChild("TexOffsetV")->getValue().asReal()); - } - else - { - self->sendTextureInfo(); - } - self->updateUI(true); + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self, self->getChild("TexOffsetV")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); } // Commit the number of repeats per meter // static void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - - LLUICtrl* repeats_ctrl = self->getChild("rptctrl"); - - U32 materials_media = self->mComboMatMedia->getCurrentIndex(); + LLPanelFace* self = (LLPanelFace*) userdata; + + LLUICtrl* repeats_ctrl = self->getChild("rptctrl"); + + U32 materials_media = self->mComboMatMedia->getCurrentIndex(); U32 material_type = 0; if (materials_media == MATMEDIA_PBR) { @@ -3866,126 +3866,126 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) material_type = radio_mat_type->getSelectedIndex(); } - F32 repeats_per_meter = repeats_ctrl->getValue().asReal(); - + F32 repeats_per_meter = repeats_ctrl->getValue().asReal(); + F32 obj_scale_s = 1.0f; F32 obj_scale_t = 1.0f; - bool identical_scale_s = false; - bool identical_scale_t = false; - - LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); - LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); - - LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); - LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); - LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); - LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); - - if (gSavedSettings.getBOOL("SyncMaterialSettings")) - { - LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); - - bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); - bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); - - shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); - shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); - } - else - { - switch (material_type) - { - case MATTYPE_DIFFUSE: - { - LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); - } - break; - - case MATTYPE_NORMAL: - { - bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); - bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); - } - break; - - case MATTYPE_SPECULAR: - { - shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); - shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); - } - break; - - default: - llassert(false); - break; - } - } - // vertical scale and repeats per meter depends on each other, so force set on changes - self->updateUI(true); + bool identical_scale_s = false; + bool identical_scale_t = false; + + LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); + LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); + + LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); + LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); + LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); + LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); + + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + } + else + { + switch (material_type) + { + case MATTYPE_DIFFUSE: + { + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + } + break; + + case MATTYPE_NORMAL: + { + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + case MATTYPE_SPECULAR: + { + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + default: + llassert(false); + break; + } + } + // vertical scale and repeats per meter depends on each other, so force set on changes + self->updateUI(true); } struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor { - virtual bool apply(LLViewerObject* object, S32 te) - { - viewer_media_t pMediaImpl; - - const LLTextureEntry* tep = object->getTE(te); - const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; - if ( mep ) - { - pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); - } - - if ( pMediaImpl.isNull()) - { - // If we didn't find face media for this face, check whether this face is showing parcel media. - pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getID()); - } - - if ( pMediaImpl.notNull()) - { - LLPluginClassMedia *media = pMediaImpl->getMediaPlugin(); - if(media) - { - S32 media_width = media->getWidth(); - S32 media_height = media->getHeight(); - S32 texture_width = media->getTextureWidth(); - S32 texture_height = media->getTextureHeight(); - F32 scale_s = (F32)media_width / (F32)texture_width; - F32 scale_t = (F32)media_height / (F32)texture_height; - - // set scale and adjust offset - object->setTEScaleS( te, scale_s ); - object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now. - object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f ); - object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f ); - } - } - return true; - }; + virtual bool apply(LLViewerObject* object, S32 te) + { + viewer_media_t pMediaImpl; + + const LLTextureEntry* tep = object->getTE(te); + const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; + if ( mep ) + { + pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); + } + + if ( pMediaImpl.isNull()) + { + // If we didn't find face media for this face, check whether this face is showing parcel media. + pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getID()); + } + + if ( pMediaImpl.notNull()) + { + LLPluginClassMedia *media = pMediaImpl->getMediaPlugin(); + if(media) + { + S32 media_width = media->getWidth(); + S32 media_height = media->getHeight(); + S32 texture_width = media->getTextureWidth(); + S32 texture_height = media->getTextureHeight(); + F32 scale_s = (F32)media_width / (F32)texture_width; + F32 scale_t = (F32)media_height / (F32)texture_height; + + // set scale and adjust offset + object->setTEScaleS( te, scale_s ); + object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now. + object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f ); + object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f ); + } + } + return true; + }; }; void LLPanelFace::onClickAutoFix(void* userdata) { - LLPanelFaceSetMediaFunctor setfunc; - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); + LLPanelFaceSetMediaFunctor setfunc; + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); - LLPanelFaceSendFunctor sendfunc; - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); + LLPanelFaceSendFunctor sendfunc; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } void LLPanelFace::onAlignTexture(void* userdata) @@ -4362,7 +4362,7 @@ void LLPanelFace::onCopyTexture() { te_data["te"]["itemfullperm"] = full_perm; - te_data["te"]["fromlibrary"] = from_library; + te_data["te"]["fromlibrary"] = from_library; // If full permission object, texture is free to copy, // but otherwise we need to check inventory and extract permissions @@ -4490,7 +4490,7 @@ void LLPanelFace::onPasteTexture() } // we can copy if single face was copied in edit face mode or if face count matches - if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) + if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) && compare_tes != clipboard.size()) { LLSD notif_args; @@ -4872,9 +4872,9 @@ bool LLPanelFace::menuEnableItem(const LLSD& userdata) // static void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->getState(); - self->sendTextureInfo(); + LLPanelFace* self = (LLPanelFace*) userdata; + self->getState(); + self->sendTextureInfo(); } void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::function edit) @@ -5123,54 +5123,54 @@ void LLPanelFace::onCommitGLTFTextureOffsetV(LLUICtrl* ctrl) void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) { - LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; - LLRadioGroup* radio_mat_type = findChild("radio_material_type"); - if(!radio_mat_type) - { - return; - } - U32 mattype = radio_mat_type->getSelectedIndex(); - std::string which_control="texture control"; - switch (mattype) - { - case MATTYPE_SPECULAR: - which_control = "shinytexture control"; - break; - case MATTYPE_NORMAL: - which_control = "bumpytexture control"; - break; - // no default needed - } - LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; - LLTextureCtrl* texture_ctrl = getChild(which_control); - if (texture_ctrl) - { - LLUUID obj_owner_id; - std::string obj_owner_name; - LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); - - LLSaleInfo sale_info; - LLSelectMgr::instance().selectGetSaleInfo(sale_info); - - bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? - bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? - bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? - bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? - - if (can_copy && can_transfer) - { - texture_ctrl->setCanApply(true, true); - return; - } - - // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale - texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); - - if (gSavedSettings.getBOOL("TextureLivePreview")) - { - LLNotificationsUtil::add("LivePreviewUnavailable"); - } - } + LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; + LLRadioGroup* radio_mat_type = findChild("radio_material_type"); + if(!radio_mat_type) + { + return; + } + U32 mattype = radio_mat_type->getSelectedIndex(); + std::string which_control="texture control"; + switch (mattype) + { + case MATTYPE_SPECULAR: + which_control = "shinytexture control"; + break; + case MATTYPE_NORMAL: + which_control = "bumpytexture control"; + break; + // no default needed + } + LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; + LLTextureCtrl* texture_ctrl = getChild(which_control); + if (texture_ctrl) + { + LLUUID obj_owner_id; + std::string obj_owner_name; + LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); + + LLSaleInfo sale_info; + LLSelectMgr::instance().selectGetSaleInfo(sale_info); + + bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? + bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? + bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? + bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? + + if (can_copy && can_transfer) + { + texture_ctrl->setCanApply(true, true); + return; + } + + // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale + texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); + + if (gSavedSettings.getBOOL("TextureLivePreview")) + { + LLNotificationsUtil::add("LivePreviewUnavailable"); + } + } } void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp) @@ -5210,81 +5210,81 @@ void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp) bool LLPanelFace::isIdenticalPlanarTexgen() { - LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; - bool identical_texgen = false; - LLSelectedTE::getTexGen(selected_texgen, identical_texgen); - return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + bool identical_texgen = false; + LLSelectedTE::getTexGen(selected_texgen, identical_texgen); + return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); } void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) -{ - struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor - { - LLFace* get(LLViewerObject* object, S32 te) - { - return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; - } - } get_te_face_func; - identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr); +{ + struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor + { + LLFace* get(LLViewerObject* object, S32 te) + { + return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; + } + } get_te_face_func; + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr); } void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) { - LLGLenum image_format; - struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor - { - LLGLenum get(LLViewerObject* object, S32 te_index) - { - LLViewerTexture* image = object->getTEImage(te_index); - return image ? image->getPrimaryFormat() : GL_RGB; - } - } get_glenum; - identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); - image_format_to_return = image_format; + LLGLenum image_format; + struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor + { + LLGLenum get(LLViewerObject* object, S32 te_index) + { + LLViewerTexture* image = object->getTEImage(te_index); + return image ? image->getPrimaryFormat() : GL_RGB; + } + } get_glenum; + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); + image_format_to_return = image_format; } void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) -{ - struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor - { - LLUUID get(LLViewerObject* object, S32 te_index) - { - LLTextureEntry *te = object->getTE(te_index); - if (te) - { - if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER) - || (te->getID() == IMG_USE_BAKED_LEFTARM) || (te->getID() == IMG_USE_BAKED_LEFTLEG) || (te->getID() == IMG_USE_BAKED_AUX1) || (te->getID() == IMG_USE_BAKED_AUX2) || (te->getID() == IMG_USE_BAKED_AUX3)) - { - return te->getID(); - } - } - - LLUUID id; - LLViewerTexture* image = object->getTEImage(te_index); - if (image) - { - id = image->getID(); - } - - if (!id.isNull() && LLViewerMedia::getInstance()->textureHasMedia(id)) - { - if (te) - { - LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; - if(!tex) - { - tex = LLViewerFetchedTexture::sDefaultImagep; - } - if (tex) - { - id = tex->getID(); - } - } - } - return id; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); +{ + struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor + { + LLUUID get(LLViewerObject* object, S32 te_index) + { + LLTextureEntry *te = object->getTE(te_index); + if (te) + { + if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER) + || (te->getID() == IMG_USE_BAKED_LEFTARM) || (te->getID() == IMG_USE_BAKED_LEFTLEG) || (te->getID() == IMG_USE_BAKED_AUX1) || (te->getID() == IMG_USE_BAKED_AUX2) || (te->getID() == IMG_USE_BAKED_AUX3)) + { + return te->getID(); + } + } + + LLUUID id; + LLViewerTexture* image = object->getTEImage(te_index); + if (image) + { + id = image->getID(); + } + + if (!id.isNull() && LLViewerMedia::getInstance()->textureHasMedia(id)) + { + if (te) + { + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; + if(!tex) + { + tex = LLViewerFetchedTexture::sDefaultImagep; + } + if (tex) + { + id = tex->getID(); + } + } + } + return id; + } + } func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); } void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bool& has_faces_with_pbr, bool& has_faces_without_pbr) @@ -5317,7 +5317,7 @@ void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bo { mIdenticalId = false; } - + LLGLTFMaterial* te_override = object->getTE(te_index)->getGLTFMaterialOverride(); if (te_override) { @@ -5360,140 +5360,140 @@ void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bo void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) { - struct MaterialFunctor : public LLSelectedTEGetFunctor - { - LLMaterialPtr get(LLViewerObject* object, S32 te_index) - { - return object->getTE(te_index)->getMaterialParams(); - } - } func; - identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); + struct MaterialFunctor : public LLSelectedTEGetFunctor + { + LLMaterialPtr get(LLViewerObject* object, S32 te_index) + { + return object->getTE(te_index)->getMaterialParams(); + } + } func; + identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); } void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical) { - struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); - U32 s_axis = VX; - U32 t_axis = VY; - F32 repeats_s = 1.0f; - F32 repeats_t = 1.0f; - if (mat) - { - mat->getSpecularRepeat(repeats_s, repeats_t); - repeats_s /= object->getScale().mV[s_axis]; - repeats_t /= object->getScale().mV[t_axis]; - } - return llmax(repeats_s, repeats_t); - } - - } max_spec_repeats_func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); + struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + U32 s_axis = VX; + U32 t_axis = VY; + F32 repeats_s = 1.0f; + F32 repeats_t = 1.0f; + if (mat) + { + mat->getSpecularRepeat(repeats_s, repeats_t); + repeats_s /= object->getScale().mV[s_axis]; + repeats_t /= object->getScale().mV[t_axis]; + } + return llmax(repeats_s, repeats_t); + } + + } max_spec_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); } void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical) { - struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); - U32 s_axis = VX; - U32 t_axis = VY; - F32 repeats_s = 1.0f; - F32 repeats_t = 1.0f; - if (mat) - { - mat->getNormalRepeat(repeats_s, repeats_t); - repeats_s /= object->getScale().mV[s_axis]; - repeats_t /= object->getScale().mV[t_axis]; - } - return llmax(repeats_s, repeats_t); - } - - } max_norm_repeats_func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); + struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + U32 s_axis = VX; + U32 t_axis = VY; + F32 repeats_s = 1.0f; + F32 repeats_t = 1.0f; + if (mat) + { + mat->getNormalRepeat(repeats_s, repeats_t); + repeats_s /= object->getScale().mV[s_axis]; + repeats_t /= object->getScale().mV[t_axis]; + } + return llmax(repeats_s, repeats_t); + } + + } max_norm_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); } void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha) { - struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor - { - LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {} - LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {} - virtual ~LLSelectedTEGetDiffuseAlphaMode() {} - - U8 get(LLViewerObject* object, S32 face) - { - U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - LLTextureEntry* tep = object->getTE(face); - if (tep) - { - LLMaterial* mat = tep->getMaterialParams().get(); - if (mat) - { - diffuse_mode = mat->getDiffuseAlphaMode(); - } - } - - return diffuse_mode; - } - bool _isAlpha; // whether or not the diffuse texture selected contains alpha information - } get_diff_mode(diffuse_texture_has_alpha); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); + struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor + { + LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {} + LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {} + virtual ~LLSelectedTEGetDiffuseAlphaMode() {} + + U8 get(LLViewerObject* object, S32 face) + { + U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + LLTextureEntry* tep = object->getTE(face); + if (tep) + { + LLMaterial* mat = tep->getMaterialParams().get(); + if (mat) + { + diffuse_mode = mat->getDiffuseAlphaMode(); + } + } + + return diffuse_mode; + } + bool _isAlpha; // whether or not the diffuse texture selected contains alpha information + } get_diff_mode(diffuse_texture_has_alpha); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); } void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) -{ - struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - U32 s_axis = VX; - U32 t_axis = VY; - LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); - return object->getScale().mV[s_axis]; - } +{ + struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[s_axis]; + } - } scale_s_func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); + } scale_s_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); } void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) -{ - struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - U32 s_axis = VX; - U32 t_axis = VY; - LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); - return object->getScale().mV[t_axis]; - } +{ + struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[t_axis]; + } - } scale_t_func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); + } scale_t_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); } void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical) { - struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - U32 s_axis = VX; - U32 t_axis = VY; - LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); - F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; - F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis]; - return llmax(repeats_s, repeats_t); - } - - } max_diff_repeats_func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); + struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; + F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis]; + return llmax(repeats_s, repeats_t); + } + + } max_diff_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 05860b995f..da53b4a14c 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -1,25 +1,25 @@ -/** +/** * @file llpanelface.h * @brief Panel in the tools floater for editing face textures, colors, etc. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -65,179 +65,179 @@ class PBRPickerObjectListener; // boost who? // template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > class LLMaterialEditFunctor { public: - LLMaterialEditFunctor(const DataType& data) : _data(data) {} - virtual ~LLMaterialEditFunctor() {} - virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } - DataType _data; + LLMaterialEditFunctor(const DataType& data) : _data(data) {} + virtual ~LLMaterialEditFunctor() {} + virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } + DataType _data; }; template< - typename DataType, - DataType (LLMaterial::*MaterialGetFunc)() > + typename DataType, + DataType (LLMaterial::*MaterialGetFunc)() > class LLMaterialGetFunctor { public: - LLMaterialGetFunctor() {} - virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } + LLMaterialGetFunctor() {} + virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } }; template< - typename DataType, - DataType (LLTextureEntry::*TEGetFunc)() > + typename DataType, + DataType (LLTextureEntry::*TEGetFunc)() > class LLTEGetFunctor { public: - LLTEGetFunctor() {} - virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } + LLTEGetFunctor() {} + virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } }; class LLPanelFace : public LLPanel { public: - virtual BOOL postBuild(); - LLPanelFace(); - virtual ~LLPanelFace(); + virtual BOOL postBuild(); + LLPanelFace(); + virtual ~LLPanelFace(); - void refresh(); - void refreshMedia(); - void unloadMedia(); + void refresh(); + void refreshMedia(); + void unloadMedia(); static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side); /*virtual*/ void onVisibilityChange(BOOL new_visibility); /*virtual*/ void draw(); - LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) - { - LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); - llassert_always(new_material); + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); - // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture - // - new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); - return new_material; - } + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } - LLRender::eTexIndex getTextureChannelToEdit(); + LLRender::eTexIndex getTextureChannelToEdit(); LLRender::eTexIndex getTextureDropChannel(); LLGLTFMaterial::TextureInfo getPBRDropChannel(); protected: - void navigateToTitleMedia(const std::string url); - bool selectedMediaEditable(); - void clearMediaSettings(); - void updateMediaSettings(); - void updateMediaTitle(); - - void getState(); - - void sendTexture(); // applies and sends texture - void sendTextureInfo(); // applies and sends texture scale, offset, etc. - void sendColor(); // applies and sends color - void sendAlpha(); // applies and sends transparency - void sendBump(U32 bumpiness); // applies and sends bump map - void sendTexGen(); // applies and sends bump map - void sendShiny(U32 shininess); // applies and sends shininess - void sendFullbright(); // applies and sends full bright - - void sendGlow(); + void navigateToTitleMedia(const std::string url); + bool selectedMediaEditable(); + void clearMediaSettings(); + void updateMediaSettings(); + void updateMediaTitle(); + + void getState(); + + void sendTexture(); // applies and sends texture + void sendTextureInfo(); // applies and sends texture scale, offset, etc. + void sendColor(); // applies and sends color + void sendAlpha(); // applies and sends transparency + void sendBump(U32 bumpiness); // applies and sends bump map + void sendTexGen(); // applies and sends bump map + void sendShiny(U32 shininess); // applies and sends shininess + void sendFullbright(); // applies and sends full bright + + void sendGlow(); void alignTestureLayer(); void updateCopyTexButton(); - void onCommitPbr(const LLSD& data); - void onCancelPbr(const LLSD& data); - void onSelectPbr(const LLSD& data); + void onCommitPbr(const LLSD& data); + void onCancelPbr(const LLSD& data); + void onSelectPbr(const LLSD& data); static BOOL onDragPbr(LLUICtrl* ctrl, LLInventoryItem* item); - // this function is to return TRUE if the drag should succeed. - static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); - - void onCommitTexture(const LLSD& data); - void onCancelTexture(const LLSD& data); - void onSelectTexture(const LLSD& data); - void onCommitSpecularTexture(const LLSD& data); - void onCancelSpecularTexture(const LLSD& data); - void onSelectSpecularTexture(const LLSD& data); - void onCommitNormalTexture(const LLSD& data); - void onCancelNormalTexture(const LLSD& data); - void onSelectNormalTexture(const LLSD& data); - void onCommitColor(const LLSD& data); - void onCommitShinyColor(const LLSD& data); - void onCommitAlpha(const LLSD& data); - void onCancelColor(const LLSD& data); - void onCancelShinyColor(const LLSD& data); - void onSelectColor(const LLSD& data); - void onSelectShinyColor(const LLSD& data); - - void onCloseTexturePicker(const LLSD& data); + // this function is to return TRUE if the drag should succeed. + static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); + + void onCommitTexture(const LLSD& data); + void onCancelTexture(const LLSD& data); + void onSelectTexture(const LLSD& data); + void onCommitSpecularTexture(const LLSD& data); + void onCancelSpecularTexture(const LLSD& data); + void onSelectSpecularTexture(const LLSD& data); + void onCommitNormalTexture(const LLSD& data); + void onCancelNormalTexture(const LLSD& data); + void onSelectNormalTexture(const LLSD& data); + void onCommitColor(const LLSD& data); + void onCommitShinyColor(const LLSD& data); + void onCommitAlpha(const LLSD& data); + void onCancelColor(const LLSD& data); + void onCancelShinyColor(const LLSD& data); + void onSelectColor(const LLSD& data); + void onSelectShinyColor(const LLSD& data); + + void onCloseTexturePicker(const LLSD& data); static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); - // Make UI reflect state of currently selected material (refresh) - // and UI mode (e.g. editing normal map v diffuse map) - // - // @param force_set_values forces spinners to set value even if they are focused - void updateUI(bool force_set_values = false); - - // Convenience func to determine if all faces in selection have - // identical planar texgen settings during edits - // - bool isIdenticalPlanarTexgen(); - - // Callback funcs for individual controls - // - static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void syncRepeatX(LLPanelFace* self, F32 scaleU); - static void syncRepeatY(LLPanelFace* self, F32 scaleV); - static void syncOffsetX(LLPanelFace* self, F32 offsetU); - static void syncOffsetY(LLPanelFace* self, F32 offsetV); - static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); - - static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); - static void onCommitPbrType(LLUICtrl* ctrl, void* userdata); - static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); - static void onCommitBump( LLUICtrl* ctrl, void* userdata); - static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); - static void onCommitShiny( LLUICtrl* ctrl, void* userdata); - static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); - static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); - static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); + // Make UI reflect state of currently selected material (refresh) + // and UI mode (e.g. editing normal map v diffuse map) + // + // @param force_set_values forces spinners to set value even if they are focused + void updateUI(bool force_set_values = false); + + // Convenience func to determine if all faces in selection have + // identical planar texgen settings during edits + // + bool isIdenticalPlanarTexgen(); + + // Callback funcs for individual controls + // + static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void syncRepeatX(LLPanelFace* self, F32 scaleU); + static void syncRepeatY(LLPanelFace* self, F32 scaleV); + static void syncOffsetX(LLPanelFace* self, F32 offsetU); + static void syncOffsetY(LLPanelFace* self, F32 offsetV); + static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); + + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); + static void onCommitPbrType(LLUICtrl* ctrl, void* userdata); + static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); + static void onCommitBump( LLUICtrl* ctrl, void* userdata); + static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); + static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); + static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); + static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); + static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); void onCommitGLTFTextureScaleU(LLUICtrl* ctrl); void onCommitGLTFTextureScaleV(LLUICtrl* ctrl); @@ -245,11 +245,11 @@ protected: void onCommitGLTFTextureOffsetU(LLUICtrl* ctrl); void onCommitGLTFTextureOffsetV(LLUICtrl* ctrl); - static void onClickAutoFix(void*); - static void onAlignTexture(void*); - static void onClickBtnLoadInvPBR(void* userdata); - static void onClickBtnEditPBR(void* userdata); - static void onClickBtnSavePBR(void* userdata); + static void onClickAutoFix(void*); + static void onAlignTexture(void*); + static void onClickBtnLoadInvPBR(void* userdata); + static void onClickBtnEditPBR(void* userdata); + static void onClickBtnSavePBR(void* userdata); public: // needs to be accessible to selection manager void onCopyColor(); // records all selected faces @@ -263,200 +263,200 @@ protected: void menuDoToSelected(const LLSD& userdata); bool menuEnableItem(const LLSD& userdata); - static F32 valueGlow(LLViewerObject* object, S32 face); + static F32 valueGlow(LLViewerObject* object, S32 face); + - private: - bool isAlpha() { return mIsAlpha; } - - // Convenience funcs to keep the visual flack to a minimum - // - LLUUID getCurrentNormalMap(); - LLUUID getCurrentSpecularMap(); - U32 getCurrentShininess(); - U32 getCurrentBumpiness(); - U8 getCurrentDiffuseAlphaMode(); - U8 getCurrentAlphaMaskCutoff(); - U8 getCurrentEnvIntensity(); - U8 getCurrentGlossiness(); - F32 getCurrentBumpyRot(); - F32 getCurrentBumpyScaleU(); - F32 getCurrentBumpyScaleV(); - F32 getCurrentBumpyOffsetU(); - F32 getCurrentBumpyOffsetV(); - F32 getCurrentShinyRot(); - F32 getCurrentShinyScaleU(); - F32 getCurrentShinyScaleV(); - F32 getCurrentShinyOffsetU(); - F32 getCurrentShinyOffsetV(); + bool isAlpha() { return mIsAlpha; } + + // Convenience funcs to keep the visual flack to a minimum + // + LLUUID getCurrentNormalMap(); + LLUUID getCurrentSpecularMap(); + U32 getCurrentShininess(); + U32 getCurrentBumpiness(); + U8 getCurrentDiffuseAlphaMode(); + U8 getCurrentAlphaMaskCutoff(); + U8 getCurrentEnvIntensity(); + U8 getCurrentGlossiness(); + F32 getCurrentBumpyRot(); + F32 getCurrentBumpyScaleU(); + F32 getCurrentBumpyScaleV(); + F32 getCurrentBumpyOffsetU(); + F32 getCurrentBumpyOffsetV(); + F32 getCurrentShinyRot(); + F32 getCurrentShinyScaleU(); + F32 getCurrentShinyScaleV(); + F32 getCurrentShinyOffsetU(); + F32 getCurrentShinyOffsetV(); LLComboBox *mComboMatMedia; LLMediaCtrl *mTitleMedia; LLTextBox *mTitleMediaText; - // Update visibility of controls to match current UI mode - // (e.g. materials vs media editing) - // - // Do NOT call updateUI from within this function. - // - void updateVisibility(LLViewerObject* objectp = nullptr); - - // Hey look everyone, a type-safe alternative to copy and paste! :) - // - - // Update material parameters by applying 'edit_func' to selected TEs - // - template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > - static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) - { - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); - struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor - { - LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} - virtual ~LLSelectedTEEditMaterial() {}; - virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) - { - if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) - { - LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); - llassert_always(new_material); - - // Determine correct alpha mode for current diffuse texture - // (i.e. does it have an alpha channel that makes alpha mode useful) - // - // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) - // need to get per-face answer to this question for sane alpha mode retention on updates. - // - bool is_alpha_face = object->isImageAlphaBlended(face); - - // need to keep this original answer for valid comparisons in logic below - // - U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - U8 default_alpha_mode = original_default_alpha_mode; - - if (!current_material.isNull()) - { - default_alpha_mode = current_material->getDiffuseAlphaMode(); - } - - // Insure we don't inherit the default of blend by accident... - // this will be stomped by a legit request to change the alpha mode by the apply() below - // - new_material->setDiffuseAlphaMode(default_alpha_mode); - - // Do "It"! - // - _edit->apply(new_material); - - U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); - LLUUID new_normal_map_id = new_material->getNormalID(); - LLUUID new_spec_map_id = new_material->getSpecularID(); - - if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) - { - new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - - bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); - bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); - - if (!is_need_material) - { - LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; - LLMaterialMgr::getInstance()->remove(object->getID(),face); - new_material = NULL; - } - else - { - LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; - LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); - } - - object->setTEMaterialParams(face, new_material); - return new_material; - } - return NULL; - } - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; - LLPanelFace *_panel; - const LLUUID & _only_for_object_id; - } editor(p, &edit, only_for_object_id); - LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); - } - - template< - typename DataType, - typename ReturnType, - ReturnType (LLMaterial::* const MaterialGetFunc)() const > - static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEMaterialVal : public LLSelectedTEGetFunctor - { - GetTEMaterialVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEMaterialVal() {} - - DataType get(LLViewerObject* object, S32 face) - { - DataType ret = _default; - LLMaterialPtr material_ptr; - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - if (tep) - { - material_ptr = tep->getMaterialParams(); - if (!material_ptr.isNull()) - { - ret = (material_ptr->*(MaterialGetFunc))(); - } - } - return ret; - } - DataType _default; - } GetFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); - data_to_return = data_value; - } - - template< - typename DataType, - typename ReturnType, // some kids just have to different... - ReturnType (LLTextureEntry::* const TEGetFunc)() const > - static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEVal : public LLSelectedTEGetFunctor - { - GetTEVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEVal() {} - - DataType get(LLViewerObject* object, S32 face) { - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - return tep ? ((tep->*(TEGetFunc))()) : _default; - } - DataType _default; - } GetTEValFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); - data_to_return = data_value; - } - - // Update vis and enabling of specific subsets of controls based on material params - // (e.g. hide the spec controls if no spec texture is applied) - // - void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateAlphaControls(); - - /* - * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. - * If agent selects texture which is not allowed to be applied for the currently selected object, - * all controls of the floater texture picker which allow to apply the texture will be disabled. - */ + // Update visibility of controls to match current UI mode + // (e.g. materials vs media editing) + // + // Do NOT call updateUI from within this function. + // + void updateVisibility(LLViewerObject* objectp = nullptr); + + // Hey look everyone, a type-safe alternative to copy and paste! :) + // + + // Update material parameters by applying 'edit_func' to selected TEs + // + template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) + { + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); + struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor + { + LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} + virtual ~LLSelectedTEEditMaterial() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) + { + if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) + { + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); + llassert_always(new_material); + + // Determine correct alpha mode for current diffuse texture + // (i.e. does it have an alpha channel that makes alpha mode useful) + // + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } + + // Insure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below + // + new_material->setDiffuseAlphaMode(default_alpha_mode); + + // Do "It"! + // + _edit->apply(new_material); + + U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); + LLUUID new_normal_map_id = new_material->getNormalID(); + LLUUID new_spec_map_id = new_material->getSpecularID(); + + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); + bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + + if (!is_need_material) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + new_material = NULL; + } + else + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); + } + + object->setTEMaterialParams(face, new_material); + return new_material; + } + return NULL; + } + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; + LLPanelFace *_panel; + const LLUUID & _only_for_object_id; + } editor(p, &edit, only_for_object_id); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); + } + + template< + typename DataType, + typename ReturnType, + ReturnType (LLMaterial::* const MaterialGetFunc)() const > + static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEMaterialVal : public LLSelectedTEGetFunctor + { + GetTEMaterialVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEMaterialVal() {} + + DataType get(LLViewerObject* object, S32 face) + { + DataType ret = _default; + LLMaterialPtr material_ptr; + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + if (tep) + { + material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + ret = (material_ptr->*(MaterialGetFunc))(); + } + } + return ret; + } + DataType _default; + } GetFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); + data_to_return = data_value; + } + + template< + typename DataType, + typename ReturnType, // some kids just have to different... + ReturnType (LLTextureEntry::* const TEGetFunc)() const > + static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEVal : public LLSelectedTEGetFunctor + { + GetTEVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEVal() {} + + DataType get(LLViewerObject* object, S32 face) { + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + return tep ? ((tep->*(TEGetFunc))()) : _default; + } + DataType _default; + } GetTEValFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); + data_to_return = data_value; + } + + // Update vis and enabling of specific subsets of controls based on material params + // (e.g. hide the spec controls if no spec texture is applied) + // + void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateAlphaControls(); + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ void onTextureSelectionChanged(LLInventoryItem* itemp); void onPbrSelectionChanged(LLInventoryItem* itemp); @@ -471,8 +471,8 @@ private: LLMenuButton* mMenuClipboardColor; LLMenuButton* mMenuClipboardTexture; - bool mIsAlpha; - + bool mIsAlpha; + LLSD mClipboardParams; LLSD mMediaSettings; @@ -515,17 +515,17 @@ private: std::unique_ptr mVOInventoryListener; public: - #if defined(DEF_GET_MAT_STATE) - #undef DEF_GET_MAT_STATE - #endif + #if defined(DEF_GET_MAT_STATE) + #undef DEF_GET_MAT_STATE + #endif - #if defined(DEF_GET_TE_STATE) - #undef DEF_GET_TE_STATE - #endif + #if defined(DEF_GET_TE_STATE) + #undef DEF_GET_TE_STATE + #endif - #if defined(DEF_EDIT_MAT_STATE) - DEF_EDIT_MAT_STATE - #endif + #if defined(DEF_EDIT_MAT_STATE) + DEF_EDIT_MAT_STATE + #endif // Accessors for selected TE material state // @@ -551,74 +551,74 @@ public: getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ } - class LLSelectedTEMaterial - { - public: - static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); - static void getMaxSpecularRepeats(F32& repeats, bool& identical); - static void getMaxNormalRepeats(F32& repeats, bool& identical); - static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); - - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) - - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) - - DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); - DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); - - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); - - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); - - DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); - DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); - - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); - DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); - }; - - class LLSelectedTE - { - public: - static void getFace(class LLFace*& face_to_return, bool& identical_face); - static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); - static void getTexId(LLUUID& id, bool& identical); + class LLSelectedTEMaterial + { + public: + static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); + static void getMaxSpecularRepeats(F32& repeats, bool& identical); + static void getMaxNormalRepeats(F32& repeats, bool& identical); + static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) + + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) + + DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); + DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + + DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); + DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); + DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + }; + + class LLSelectedTE + { + public: + static void getFace(class LLFace*& face_to_return, bool& identical_face); + static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); + static void getTexId(LLUUID& id, bool& identical); static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr); - static void getObjectScaleS(F32& scale_s, bool& identical); - static void getObjectScaleT(F32& scale_t, bool& identical); - static void getMaxDiffuseRepeats(F32& repeats, bool& identical); - - DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) - DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) - DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) - DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); - }; + static void getObjectScaleS(F32& scale_s, bool& identical); + static void getObjectScaleT(F32& scale_t, bool& identical); + static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + + DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) + DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) + DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) + DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); + }; }; #endif diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 2db431d165..5111241e92 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpanelmaininventory.cpp * @brief Implementation of llpanelmaininventory. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -77,29 +77,29 @@ static LLPanelInjector t_inventory("panel_main_inventory") class LLFloaterInventoryFinder : public LLFloater { public: - LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view); - virtual void draw(); - /*virtual*/ BOOL postBuild(); - void changeFilter(LLInventoryFilter* filter); - void updateElementsFromFilter(); - BOOL getCheckShowEmpty(); - BOOL getCheckSinceLogoff(); - U32 getDateSearchDirection(); - - void onCreatorSelfFilterCommit(); - void onCreatorOtherFilterCommit(); - - static void onTimeAgo(LLUICtrl*, void *); - static void onCloseBtn(void* user_data); - static void selectAllTypes(void* user_data); - static void selectNoTypes(void* user_data); + LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view); + virtual void draw(); + /*virtual*/ BOOL postBuild(); + void changeFilter(LLInventoryFilter* filter); + void updateElementsFromFilter(); + BOOL getCheckShowEmpty(); + BOOL getCheckSinceLogoff(); + U32 getDateSearchDirection(); + + void onCreatorSelfFilterCommit(); + void onCreatorOtherFilterCommit(); + + static void onTimeAgo(LLUICtrl*, void *); + static void onCloseBtn(void* user_data); + static void selectAllTypes(void* user_data); + static void selectNoTypes(void* user_data); private: - LLPanelMainInventory* mPanelMainInventory; - LLSpinCtrl* mSpinSinceDays; - LLSpinCtrl* mSpinSinceHours; - LLCheckBoxCtrl* mCreatorSelf; - LLCheckBoxCtrl* mCreatorOthers; - LLInventoryFilter* mFilter; + LLPanelMainInventory* mPanelMainInventory; + LLSpinCtrl* mSpinSinceDays; + LLSpinCtrl* mSpinSinceHours; + LLCheckBoxCtrl* mCreatorSelf; + LLCheckBoxCtrl* mCreatorOthers; + LLInventoryFilter* mFilter; }; ///---------------------------------------------------------------------------- @@ -107,15 +107,15 @@ private: ///---------------------------------------------------------------------------- LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) - : LLPanel(p), - mActivePanel(NULL), - mWornItemsPanel(NULL), - mSavedFolderState(NULL), - mFilterText(""), - mMenuGearDefault(NULL), - mMenuVisibility(NULL), - mMenuAddHandle(), - mNeedUploadCost(true), + : LLPanel(p), + mActivePanel(NULL), + mWornItemsPanel(NULL), + mSavedFolderState(NULL), + mFilterText(""), + mMenuGearDefault(NULL), + mMenuVisibility(NULL), + mMenuAddHandle(), + mNeedUploadCost(true), mMenuViewDefault(NULL), mSingleFolderMode(false), mForceShowInvLayout(false), @@ -123,128 +123,128 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mListViewRootUpdatedConnection(), mGalleryRootUpdatedConnection() { - // Menu Callbacks (non contex menus) - mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2)); - mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this)); - mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); - mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); - mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2)); - mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this)); - mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this)); - mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2)); + // Menu Callbacks (non contex menus) + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2)); + mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this)); + mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this)); + mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2)); mEnableCallbackRegistrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasSettingsInventory(); }); mEnableCallbackRegistrar.add("Inventory.MaterialsEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasMaterialsInventory(); }); - mSavedFolderState = new LLSaveFolderState(); - mSavedFolderState->setApply(FALSE); + mSavedFolderState = new LLSaveFolderState(); + mSavedFolderState->setApply(FALSE); } BOOL LLPanelMainInventory::postBuild() { - gInventory.addObserver(this); - - mFilterTabs = getChild("inventory filter tabs"); - mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this)); - + gInventory.addObserver(this); + + mFilterTabs = getChild("inventory filter tabs"); + mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this)); + mCounterCtrl = getChild("ItemcountText"); - - //panel->getFilter().markDefault(); - - // Set up the default inv. panel/filter settings. - mActivePanel = getChild(ALL_ITEMS); - if (mActivePanel) - { - // "All Items" is the previous only view, so it gets the InventorySortOrder - mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER)); - mActivePanel->getFilter().markDefault(); - mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); - mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2)); - mResortActivePanel = true; - } - LLInventoryPanel* recent_items_panel = getChild(RECENT_ITEMS); - if (recent_items_panel) - { - // assign default values until we will be sure that we have setting to restore - recent_items_panel->setSinceLogoff(TRUE); - recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); - recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - LLInventoryFilter& recent_filter = recent_items_panel->getFilter(); - recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY)); - recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems"); - recent_filter.markDefault(); - recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2)); - } - - mWornItemsPanel = getChild(WORN_ITEMS); - if (mWornItemsPanel) - { - U32 filter_types = 0x0; - filter_types |= 0x1 << LLInventoryType::IT_WEARABLE; - filter_types |= 0x1 << LLInventoryType::IT_ATTACHMENT; - filter_types |= 0x1 << LLInventoryType::IT_OBJECT; - mWornItemsPanel->setFilterTypes(filter_types); - mWornItemsPanel->setFilterWorn(); - mWornItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mWornItemsPanel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS); - LLInventoryFilter& worn_filter = mWornItemsPanel->getFilter(); - worn_filter.setFilterCategoryTypes(worn_filter.getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX)); - worn_filter.markDefault(); - mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2)); - } - mSearchTypeCombo = getChild("search_type"); - if(mSearchTypeCombo) - { - mSearchTypeCombo->setCommitCallback(boost::bind(&LLPanelMainInventory::onSelectSearchType, this)); - } - // Now load the stored settings from disk, if available. - std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME)); - LL_INFOS("Inventory") << "LLPanelMainInventory::init: reading from " << filterSaveName << LL_ENDL; - llifstream file(filterSaveName.c_str()); - LLSD savedFilterState; - if (file.is_open()) - { - LLSDSerialize::fromXML(savedFilterState, file); - file.close(); - - // Load the persistent "Recent Items" settings. - // Note that the "All Items" settings do not persist. - if(recent_items_panel) - { - if(savedFilterState.has(recent_items_panel->getFilter().getName())) - { - LLSD recent_items = savedFilterState.get( - recent_items_panel->getFilter().getName()); - LLInventoryFilter::Params p; - LLParamSDParser parser; - parser.readSD(recent_items, p); - recent_items_panel->getFilter().fromParams(p); - recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER)); - } - } - if(mActivePanel) - { - if(savedFilterState.has(mActivePanel->getFilter().getName())) - { - LLSD items = savedFilterState.get(mActivePanel->getFilter().getName()); - LLInventoryFilter::Params p; - LLParamSDParser parser; - parser.readSD(items, p); - mActivePanel->getFilter().setSearchVisibilityTypes(p); - } - } - - } - - mFilterEditor = getChild("inventory search editor"); - if (mFilterEditor) - { - mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); - } - - mGearMenuButton = getChild("options_gear_btn"); - mVisibilityMenuButton = getChild("options_visibility_btn"); + + //panel->getFilter().markDefault(); + + // Set up the default inv. panel/filter settings. + mActivePanel = getChild(ALL_ITEMS); + if (mActivePanel) + { + // "All Items" is the previous only view, so it gets the InventorySortOrder + mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER)); + mActivePanel->getFilter().markDefault(); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2)); + mResortActivePanel = true; + } + LLInventoryPanel* recent_items_panel = getChild(RECENT_ITEMS); + if (recent_items_panel) + { + // assign default values until we will be sure that we have setting to restore + recent_items_panel->setSinceLogoff(TRUE); + recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); + recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + LLInventoryFilter& recent_filter = recent_items_panel->getFilter(); + recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY)); + recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems"); + recent_filter.markDefault(); + recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2)); + } + + mWornItemsPanel = getChild(WORN_ITEMS); + if (mWornItemsPanel) + { + U32 filter_types = 0x0; + filter_types |= 0x1 << LLInventoryType::IT_WEARABLE; + filter_types |= 0x1 << LLInventoryType::IT_ATTACHMENT; + filter_types |= 0x1 << LLInventoryType::IT_OBJECT; + mWornItemsPanel->setFilterTypes(filter_types); + mWornItemsPanel->setFilterWorn(); + mWornItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mWornItemsPanel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS); + LLInventoryFilter& worn_filter = mWornItemsPanel->getFilter(); + worn_filter.setFilterCategoryTypes(worn_filter.getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX)); + worn_filter.markDefault(); + mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2)); + } + mSearchTypeCombo = getChild("search_type"); + if(mSearchTypeCombo) + { + mSearchTypeCombo->setCommitCallback(boost::bind(&LLPanelMainInventory::onSelectSearchType, this)); + } + // Now load the stored settings from disk, if available. + std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME)); + LL_INFOS("Inventory") << "LLPanelMainInventory::init: reading from " << filterSaveName << LL_ENDL; + llifstream file(filterSaveName.c_str()); + LLSD savedFilterState; + if (file.is_open()) + { + LLSDSerialize::fromXML(savedFilterState, file); + file.close(); + + // Load the persistent "Recent Items" settings. + // Note that the "All Items" settings do not persist. + if(recent_items_panel) + { + if(savedFilterState.has(recent_items_panel->getFilter().getName())) + { + LLSD recent_items = savedFilterState.get( + recent_items_panel->getFilter().getName()); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(recent_items, p); + recent_items_panel->getFilter().fromParams(p); + recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER)); + } + } + if(mActivePanel) + { + if(savedFilterState.has(mActivePanel->getFilter().getName())) + { + LLSD items = savedFilterState.get(mActivePanel->getFilter().getName()); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(items, p); + mActivePanel->getFilter().setSearchVisibilityTypes(p); + } + } + + } + + mFilterEditor = getChild("inventory search editor"); + if (mFilterEditor) + { + mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); + } + + mGearMenuButton = getChild("options_gear_btn"); + mVisibilityMenuButton = getChild("options_visibility_btn"); mViewMenuButton = getChild("view_btn"); mBackBtn = getChild("back_btn"); @@ -274,73 +274,73 @@ BOOL LLPanelMainInventory::postBuild() mGalleryRootUpdatedConnection = mCombinationGalleryPanel->setRootChangedCallback(boost::bind(&LLPanelMainInventory::onCombinationRootChanged, this, true)); mCombinationGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelMainInventory::onCombinationGallerySelectionChanged, this, _1)); - initListCommandsHandlers(); + initListCommandsHandlers(); - const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); - const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); + const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); + const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); - LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); - if (menu) - { - menu->getChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); - menu->getChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); - } + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { + menu->getChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); + menu->getChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); + } - // Trigger callback for focus received so we can deselect items in inbox/outbox - LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); + // Trigger callback for focus received so we can deselect items in inbox/outbox + LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); - return TRUE; + return TRUE; } // Destroys the object LLPanelMainInventory::~LLPanelMainInventory( void ) { - // Save the filters state. - // Some params types cannot be saved this way - // for example, LLParamSDParser doesn't know about U64, - // so some FilterOps params should be revised. - LLSD filterRoot; - LLInventoryPanel* all_items_panel = getChild(ALL_ITEMS); - if (all_items_panel) - { - LLSD filterState; - LLInventoryPanel::InventoryState p; - all_items_panel->getFilter().toParams(p.filter); - all_items_panel->getRootViewModel().getSorter().toParams(p.sort); - if (p.validateBlock(false)) - { - LLParamSDParser().writeSD(filterState, p); - filterRoot[all_items_panel->getName()] = filterState; - } - } - - LLInventoryPanel* panel = findChild(RECENT_ITEMS); - if (panel) - { - LLSD filterState; - LLInventoryPanel::InventoryState p; - panel->getFilter().toParams(p.filter); - panel->getRootViewModel().getSorter().toParams(p.sort); - if (p.validateBlock(false)) - { - LLParamSDParser().writeSD(filterState, p); - filterRoot[panel->getName()] = filterState; - } - } - - std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME)); - llofstream filtersFile(filterSaveName.c_str()); - if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) - { - LL_WARNS() << "Could not write to filters save file " << filterSaveName << LL_ENDL; - } - else - { - filtersFile.close(); - } - - gInventory.removeObserver(this); - delete mSavedFolderState; + // Save the filters state. + // Some params types cannot be saved this way + // for example, LLParamSDParser doesn't know about U64, + // so some FilterOps params should be revised. + LLSD filterRoot; + LLInventoryPanel* all_items_panel = getChild(ALL_ITEMS); + if (all_items_panel) + { + LLSD filterState; + LLInventoryPanel::InventoryState p; + all_items_panel->getFilter().toParams(p.filter); + all_items_panel->getRootViewModel().getSorter().toParams(p.sort); + if (p.validateBlock(false)) + { + LLParamSDParser().writeSD(filterState, p); + filterRoot[all_items_panel->getName()] = filterState; + } + } + + LLInventoryPanel* panel = findChild(RECENT_ITEMS); + if (panel) + { + LLSD filterState; + LLInventoryPanel::InventoryState p; + panel->getFilter().toParams(p.filter); + panel->getRootViewModel().getSorter().toParams(p.sort); + if (p.validateBlock(false)) + { + LLParamSDParser().writeSD(filterState, p); + filterRoot[panel->getName()] = filterState; + } + } + + std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME)); + llofstream filtersFile(filterSaveName.c_str()); + if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) + { + LL_WARNS() << "Could not write to filters save file " << filterSaveName << LL_ENDL; + } + else + { + filtersFile.close(); + } + + gInventory.removeObserver(this); + delete mSavedFolderState; auto menu = mMenuAddHandle.get(); if(menu) @@ -361,57 +361,57 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel() { - return getChild(ALL_ITEMS); + return getChild(ALL_ITEMS); } void LLPanelMainInventory::selectAllItemsPanel() { - mFilterTabs->selectFirstTab(); + mFilterTabs->selectFirstTab(); } bool LLPanelMainInventory::isRecentItemsPanelSelected() { - return (RECENT_ITEMS == getActivePanel()->getName()); + return (RECENT_ITEMS == getActivePanel()->getName()); } void LLPanelMainInventory::startSearch() { - // this forces focus to line editor portion of search editor - if (mFilterEditor) - { - mFilterEditor->focusFirstItem(TRUE); - } + // this forces focus to line editor portion of search editor + if (mFilterEditor) + { + mFilterEditor->focusFirstItem(TRUE); + } } BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask) { - LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; - if (root_folder) - { - // first check for user accepting current search results - if (mFilterEditor - && mFilterEditor->hasFocus() - && (key == KEY_RETURN - || key == KEY_DOWN) - && mask == MASK_NONE) - { - // move focus to inventory proper - mActivePanel->setFocus(TRUE); - root_folder->scrollToShowSelection(); - return TRUE; - } - - if (mActivePanel->hasFocus() && key == KEY_UP) - { - startSearch(); - } + LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; + if (root_folder) + { + // first check for user accepting current search results + if (mFilterEditor + && mFilterEditor->hasFocus() + && (key == KEY_RETURN + || key == KEY_DOWN) + && mask == MASK_NONE) + { + // move focus to inventory proper + mActivePanel->setFocus(TRUE); + root_folder->scrollToShowSelection(); + return TRUE; + } + + if (mActivePanel->hasFocus() && key == KEY_UP) + { + startSearch(); + } if(mSingleFolderMode && key == KEY_LEFT) { onBackFolderClicked(); } - } + } - return LLPanel::handleKeyHere(key, mask); + return LLPanel::handleKeyHere(key, mask); } @@ -420,12 +420,12 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask) void LLPanelMainInventory::doToSelected(const LLSD& userdata) { - getPanel()->doToSelected(userdata); + getPanel()->doToSelected(userdata); } void LLPanelMainInventory::closeAllFolders() { - getPanel()->getRootFolder()->closeAllFolders(); + getPanel()->getRootFolder()->closeAllFolders(); } S32 get_instance_num() @@ -440,13 +440,13 @@ LLFloaterSidePanelContainer* LLPanelMainInventory::newWindow() { S32 instance_num = get_instance_num(); - if (!gAgentCamera.cameraMouselook()) - { + if (!gAgentCamera.cameraMouselook()) + { LLFloaterSidePanelContainer* floater = LLFloaterReg::showTypedInstance("inventory", LLSD(instance_num)); LLSidepanelInventory* sidepanel_inventory = floater->findChild("main_panel"); sidepanel_inventory->initInventoryViews(); - return floater; - } + return floater; + } return NULL; } @@ -476,7 +476,7 @@ void LLPanelMainInventory::newFolderWindow(LLUUID folder_id, LLUUID item_to_sele } } } - + S32 instance_num = get_instance_num(); LLFloaterSidePanelContainer* inventory_container = LLFloaterReg::showTypedInstance("inventory", LLSD(instance_num)); @@ -504,7 +504,7 @@ void LLPanelMainInventory::newFolderWindow(LLUUID folder_id, LLUUID item_to_sele void LLPanelMainInventory::doCreate(const LLSD& userdata) { - reset_inventory_filter(); + reset_inventory_filter(); if(mSingleFolderMode) { if(isListViewMode() || isCombinationViewMode()) @@ -565,14 +565,14 @@ void LLPanelMainInventory::doCreate(const LLSD& userdata) void LLPanelMainInventory::resetFilters() { - LLFloaterInventoryFinder *finder = getFinder(); - getCurrentFilter().resetDefault(); - if (finder) - { - finder->updateElementsFromFilter(); - } + LLFloaterInventoryFinder *finder = getFinder(); + getCurrentFilter().resetDefault(); + if (finder) + { + finder->updateElementsFromFilter(); + } - setFilterTextFromFilter(); + setFilterTextFromFilter(); } void LLPanelMainInventory::resetAllItemsFilters() @@ -600,44 +600,44 @@ void LLPanelMainInventory::findLinks(const LLUUID& item_id, const std::string& i void LLPanelMainInventory::setSortBy(const LLSD& userdata) { - U32 sort_order_mask = getActivePanel()->getSortOrder(); - std::string sort_type = userdata.asString(); - if (sort_type == "name") - { - sort_order_mask &= ~LLInventoryFilter::SO_DATE; - } - else if (sort_type == "date") - { - sort_order_mask |= LLInventoryFilter::SO_DATE; - } - else if (sort_type == "foldersalwaysbyname") - { - if ( sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME ) - { - sort_order_mask &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; - } - else - { - sort_order_mask |= LLInventoryFilter::SO_FOLDERS_BY_NAME; - } - } - else if (sort_type == "systemfolderstotop") - { - if ( sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) - { - sort_order_mask &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; - } - else - { - sort_order_mask |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; - } - } + U32 sort_order_mask = getActivePanel()->getSortOrder(); + std::string sort_type = userdata.asString(); + if (sort_type == "name") + { + sort_order_mask &= ~LLInventoryFilter::SO_DATE; + } + else if (sort_type == "date") + { + sort_order_mask |= LLInventoryFilter::SO_DATE; + } + else if (sort_type == "foldersalwaysbyname") + { + if ( sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME ) + { + sort_order_mask &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; + } + else + { + sort_order_mask |= LLInventoryFilter::SO_FOLDERS_BY_NAME; + } + } + else if (sort_type == "systemfolderstotop") + { + if ( sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) + { + sort_order_mask &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + } + else + { + sort_order_mask |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + } + } if(mSingleFolderMode && !isListViewMode()) { mCombinationGalleryPanel->setSortOrder(sort_order_mask, true); } - getActivePanel()->setSortOrder(sort_order_mask); + getActivePanel()->setSortOrder(sort_order_mask); if (isRecentItemsPanelSelected()) { gSavedSettings.setU32("RecentItemsSortOrder", sort_order_mask); @@ -650,23 +650,23 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata) void LLPanelMainInventory::onSelectSearchType() { - std::string new_type = mSearchTypeCombo->getValue(); - if (new_type == "search_by_name") - { - setSearchType(LLInventoryFilter::SEARCHTYPE_NAME); - } - if (new_type == "search_by_creator") - { - setSearchType(LLInventoryFilter::SEARCHTYPE_CREATOR); - } - if (new_type == "search_by_description") - { - setSearchType(LLInventoryFilter::SEARCHTYPE_DESCRIPTION); - } - if (new_type == "search_by_UUID") - { - setSearchType(LLInventoryFilter::SEARCHTYPE_UUID); - } + std::string new_type = mSearchTypeCombo->getValue(); + if (new_type == "search_by_name") + { + setSearchType(LLInventoryFilter::SEARCHTYPE_NAME); + } + if (new_type == "search_by_creator") + { + setSearchType(LLInventoryFilter::SEARCHTYPE_CREATOR); + } + if (new_type == "search_by_description") + { + setSearchType(LLInventoryFilter::SEARCHTYPE_DESCRIPTION); + } + if (new_type == "search_by_UUID") + { + setSearchType(LLInventoryFilter::SEARCHTYPE_UUID); + } } void LLPanelMainInventory::setSearchType(LLInventoryFilter::ESearchType type) @@ -703,70 +703,70 @@ void LLPanelMainInventory::updateSearchTypeCombo() search_type = getActivePanel()->getSearchType(); } - switch(search_type) - { - case LLInventoryFilter::SEARCHTYPE_CREATOR: - mSearchTypeCombo->setValue("search_by_creator"); - break; - case LLInventoryFilter::SEARCHTYPE_DESCRIPTION: - mSearchTypeCombo->setValue("search_by_description"); - break; - case LLInventoryFilter::SEARCHTYPE_UUID: - mSearchTypeCombo->setValue("search_by_UUID"); - break; - case LLInventoryFilter::SEARCHTYPE_NAME: - default: - mSearchTypeCombo->setValue("search_by_name"); - break; - } + switch(search_type) + { + case LLInventoryFilter::SEARCHTYPE_CREATOR: + mSearchTypeCombo->setValue("search_by_creator"); + break; + case LLInventoryFilter::SEARCHTYPE_DESCRIPTION: + mSearchTypeCombo->setValue("search_by_description"); + break; + case LLInventoryFilter::SEARCHTYPE_UUID: + mSearchTypeCombo->setValue("search_by_UUID"); + break; + case LLInventoryFilter::SEARCHTYPE_NAME: + default: + mSearchTypeCombo->setValue("search_by_name"); + break; + } } // static BOOL LLPanelMainInventory::filtersVisible(void* user_data) { - LLPanelMainInventory* self = (LLPanelMainInventory*)user_data; - if(!self) return FALSE; + LLPanelMainInventory* self = (LLPanelMainInventory*)user_data; + if(!self) return FALSE; - return self->getFinder() != NULL; + return self->getFinder() != NULL; } void LLPanelMainInventory::onClearSearch() { - BOOL initially_active = FALSE; - LLFloater *finder = getFinder(); - if (mActivePanel && (getActivePanel() != mWornItemsPanel)) - { - initially_active = mActivePanel->getFilter().isNotDefault(); - setFilterSubString(LLStringUtil::null); - mActivePanel->setFilterTypes(0xffffffffffffffffULL); - mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS); - } - - if (finder) - { - LLFloaterInventoryFinder::selectAllTypes(finder); - } - - // re-open folders that were initially open in case filter was active - if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode) - { - mSavedFolderState->setApply(TRUE); - mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); - LLOpenFoldersWithSelection opener; - mActivePanel->getRootFolder()->applyFunctorRecursively(opener); - mActivePanel->getRootFolder()->scrollToShowSelection(); - } - mFilterSubString = ""; - - LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory(); - if (sidepanel_inventory) - { - LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild("marketplace_inbox"); - if (inbox_panel) - { - inbox_panel->onClearSearch(); - } - } + BOOL initially_active = FALSE; + LLFloater *finder = getFinder(); + if (mActivePanel && (getActivePanel() != mWornItemsPanel)) + { + initially_active = mActivePanel->getFilter().isNotDefault(); + setFilterSubString(LLStringUtil::null); + mActivePanel->setFilterTypes(0xffffffffffffffffULL); + mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS); + } + + if (finder) + { + LLFloaterInventoryFinder::selectAllTypes(finder); + } + + // re-open folders that were initially open in case filter was active + if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode) + { + mSavedFolderState->setApply(TRUE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + LLOpenFoldersWithSelection opener; + mActivePanel->getRootFolder()->applyFunctorRecursively(opener); + mActivePanel->getRootFolder()->scrollToShowSelection(); + } + mFilterSubString = ""; + + LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory(); + if (sidepanel_inventory) + { + LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild("marketplace_inbox"); + if (inbox_panel) + { + inbox_panel->onClearSearch(); + } + } } void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) @@ -782,15 +782,15 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) mCombinationGalleryPanel->setFilterSubString(search_string); } - if (search_string == "") - { - onClearSearch(); - } + if (search_string == "") + { + onClearSearch(); + } - if (!mActivePanel) - { - return; - } + if (!mActivePanel) + { + return; + } if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted()) { @@ -798,215 +798,215 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) LLInventoryModelBackgroundFetch::instance().start(); } - mFilterSubString = search_string; - if (mActivePanel->getFilterSubString().empty() && mFilterSubString.empty()) - { - // current filter and new filter empty, do nothing - return; - } + mFilterSubString = search_string; + if (mActivePanel->getFilterSubString().empty() && mFilterSubString.empty()) + { + // current filter and new filter empty, do nothing + return; + } - // save current folder open state if no filter currently applied - if (!mActivePanel->getFilter().isNotDefault()) - { - mSavedFolderState->setApply(FALSE); - mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); - } + // save current folder open state if no filter currently applied + if (!mActivePanel->getFilter().isNotDefault()) + { + mSavedFolderState->setApply(FALSE); + mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + } - // set new filter string - setFilterSubString(mFilterSubString); + // set new filter string + setFilterSubString(mFilterSubString); LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory(); - if (sidepanel_inventory) - { - LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild("marketplace_inbox"); - if (inbox_panel) - { - inbox_panel->onFilterEdit(search_string); - } - } + if (sidepanel_inventory) + { + LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild("marketplace_inbox"); + if (inbox_panel) + { + inbox_panel->onFilterEdit(search_string); + } + } } //static BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward) { - LLPanelMainInventory* active_view = NULL; - - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) - { - LLPanelMainInventory* iv = dynamic_cast(*iter); - if (iv) - { - if (gFocusMgr.childHasKeyboardFocus(iv)) - { - active_view = iv; - break; - } - } - } - - if (!active_view) - { - return FALSE; - } - - std::string search_string(find_text); - - if (search_string.empty()) - { - return FALSE; - } - - if (active_view->getPanel() && - active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward)) - { - return TRUE; - } - - return FALSE; + LLPanelMainInventory* active_view = NULL; + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLPanelMainInventory* iv = dynamic_cast(*iter); + if (iv) + { + if (gFocusMgr.childHasKeyboardFocus(iv)) + { + active_view = iv; + break; + } + } + } + + if (!active_view) + { + return FALSE; + } + + std::string search_string(find_text); + + if (search_string.empty()) + { + return FALSE; + } + + if (active_view->getPanel() && + active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward)) + { + return TRUE; + } + + return FALSE; } void LLPanelMainInventory::onFilterSelected() { - // Find my index + // Find my index setActivePanel(); - if (!mActivePanel) - { - return; - } - - if (getActivePanel() == mWornItemsPanel) - { - mActivePanel->openAllFolders(); - } - updateSearchTypeCombo(); - setFilterSubString(mFilterSubString); - LLInventoryFilter& filter = getCurrentFilter(); - LLFloaterInventoryFinder *finder = getFinder(); - if (finder) - { - finder->changeFilter(&filter); + if (!mActivePanel) + { + return; + } + + if (getActivePanel() == mWornItemsPanel) + { + mActivePanel->openAllFolders(); + } + updateSearchTypeCombo(); + setFilterSubString(mFilterSubString); + LLInventoryFilter& filter = getCurrentFilter(); + LLFloaterInventoryFinder *finder = getFinder(); + if (finder) + { + finder->changeFilter(&filter); if (mSingleFolderMode) { finder->setTitle(getLocalizedRootName()); } - } - if (filter.isActive() && !LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted()) - { + } + if (filter.isActive() && !LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted()) + { llassert(false); // this should have been done on startup - LLInventoryModelBackgroundFetch::instance().start(); - } - setFilterTextFromFilter(); + LLInventoryModelBackgroundFetch::instance().start(); + } + setFilterTextFromFilter(); } -const std::string LLPanelMainInventory::getFilterSubString() -{ - return mActivePanel->getFilterSubString(); +const std::string LLPanelMainInventory::getFilterSubString() +{ + return mActivePanel->getFilterSubString(); } -void LLPanelMainInventory::setFilterSubString(const std::string& string) -{ - mActivePanel->setFilterSubString(string); +void LLPanelMainInventory::setFilterSubString(const std::string& string) +{ + mActivePanel->setFilterSubString(string); } BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - // Check to see if we are auto scrolling from the last frame - LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); - BOOL needsToScroll = panel->getScrollableContainer()->canAutoScroll(x, y); - if(mFilterTabs) - { - if(needsToScroll) - { - mFilterTabs->startDragAndDropDelayTimer(); - } - } - - BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); - - return handled; + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + // Check to see if we are auto scrolling from the last frame + LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); + BOOL needsToScroll = panel->getScrollableContainer()->canAutoScroll(x, y); + if(mFilterTabs) + { + if(needsToScroll) + { + mFilterTabs->startDragAndDropDelayTimer(); + } + } + + BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + + return handled; } // virtual void LLPanelMainInventory::changed(U32) { - updateItemcountText(); + updateItemcountText(); } void LLPanelMainInventory::setFocusFilterEditor() { - if(mFilterEditor) - { - mFilterEditor->setFocus(true); - } + if(mFilterEditor) + { + mFilterEditor->setFocus(true); + } } // virtual void LLPanelMainInventory::draw() { - if (mActivePanel && mFilterEditor) - { - mFilterEditor->setText(mFilterSubString); - } - if (mActivePanel && mResortActivePanel) - { - // EXP-756: Force resorting of the list the first time we draw the list: - // In the case of date sorting, we don't have enough information at initialization time - // to correctly sort the folders. Later manual resort doesn't do anything as the order value is - // set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order. - U32 order = mActivePanel->getSortOrder(); - mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME); - mActivePanel->setSortOrder(order); - mResortActivePanel = false; - } - LLPanel::draw(); - updateItemcountText(); + if (mActivePanel && mFilterEditor) + { + mFilterEditor->setText(mFilterSubString); + } + if (mActivePanel && mResortActivePanel) + { + // EXP-756: Force resorting of the list the first time we draw the list: + // In the case of date sorting, we don't have enough information at initialization time + // to correctly sort the folders. Later manual resort doesn't do anything as the order value is + // set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order. + U32 order = mActivePanel->getSortOrder(); + mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME); + mActivePanel->setSortOrder(order); + mResortActivePanel = false; + } + LLPanel::draw(); + updateItemcountText(); updateCombinationVisibility(); } void LLPanelMainInventory::updateItemcountText() { - if(mItemCount != gInventory.getItemCount()) - { - mItemCount = gInventory.getItemCount(); - mItemCountString = ""; - LLLocale locale(LLLocale::USER_LOCALE); - LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount); - } - - if(mCategoryCount != gInventory.getCategoryCount()) - { - mCategoryCount = gInventory.getCategoryCount(); - mCategoryCountString = ""; - LLLocale locale(LLLocale::USER_LOCALE); - LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount); - } - - LLStringUtil::format_map_t string_args; - string_args["[ITEM_COUNT]"] = mItemCountString; - string_args["[CATEGORY_COUNT]"] = mCategoryCountString; - string_args["[FILTER]"] = getFilterText(); - - std::string text = ""; - - if (LLInventoryModelBackgroundFetch::instance().folderFetchActive()) - { - text = getString("ItemcountFetching", string_args); - } - else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched()) - { - text = getString("ItemcountCompleted", string_args); - } - else - { - text = getString("ItemcountUnknown", string_args); - } + if(mItemCount != gInventory.getItemCount()) + { + mItemCount = gInventory.getItemCount(); + mItemCountString = ""; + LLLocale locale(LLLocale::USER_LOCALE); + LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount); + } + + if(mCategoryCount != gInventory.getCategoryCount()) + { + mCategoryCount = gInventory.getCategoryCount(); + mCategoryCountString = ""; + LLLocale locale(LLLocale::USER_LOCALE); + LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount); + } + + LLStringUtil::format_map_t string_args; + string_args["[ITEM_COUNT]"] = mItemCountString; + string_args["[CATEGORY_COUNT]"] = mCategoryCountString; + string_args["[FILTER]"] = getFilterText(); + + std::string text = ""; + + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive()) + { + text = getString("ItemcountFetching", string_args); + } + else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched()) + { + text = getString("ItemcountCompleted", string_args); + } + else + { + text = getString("ItemcountUnknown", string_args); + } if (mSingleFolderMode) { @@ -1022,40 +1022,40 @@ void LLPanelMainInventory::updateItemcountText() text = getString("ItemcountCompleted", string_args); } } - + mCounterCtrl->setValue(text); mCounterCtrl->setToolTip(text); } void LLPanelMainInventory::onFocusReceived() { - LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel("inventory"); - if (!sidepanel_inventory) - { - LL_WARNS() << "Could not find Inventory Panel in My Inventory floater" << LL_ENDL; - return; - } + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel("inventory"); + if (!sidepanel_inventory) + { + LL_WARNS() << "Could not find Inventory Panel in My Inventory floater" << LL_ENDL; + return; + } - sidepanel_inventory->clearSelections(false, true); + sidepanel_inventory->clearSelections(false, true); } -void LLPanelMainInventory::setFilterTextFromFilter() -{ - mFilterText = getCurrentFilter().getFilterText(); +void LLPanelMainInventory::setFilterTextFromFilter() +{ + mFilterText = getCurrentFilter().getFilterText(); } void LLPanelMainInventory::toggleFindOptions() { - LLFloater *floater = getFinder(); - if (!floater) - { - LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this); - mFinderHandle = finder->getHandle(); - finder->openFloater(); + LLFloater *floater = getFinder(); + if (!floater) + { + LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this); + mFinderHandle = finder->getHandle(); + finder->openFloater(); - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - if (parent_floater) - parent_floater->addDependentFloater(mFinderHandle); + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + parent_floater->addDependentFloater(mFinderHandle); if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted()) { @@ -1067,232 +1067,232 @@ void LLPanelMainInventory::toggleFindOptions() { finder->setTitle(getLocalizedRootName()); } - } - else - { - floater->closeFloater(); - } + } + else + { + floater->closeFloater(); + } } void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { - getChild(ALL_ITEMS)->setSelectCallback(cb); - getChild(RECENT_ITEMS)->setSelectCallback(cb); + getChild(ALL_ITEMS)->setSelectCallback(cb); + getChild(RECENT_ITEMS)->setSelectCallback(cb); } void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque& items, BOOL user_action) { - updateListCommands(); - panel->onSelectionChange(items, user_action); + updateListCommands(); + panel->onSelectionChange(items, user_action); } ///---------------------------------------------------------------------------- /// LLFloaterInventoryFinder ///---------------------------------------------------------------------------- -LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() -{ - return (LLFloaterInventoryFinder*)mFinderHandle.get(); +LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() +{ + return (LLFloaterInventoryFinder*)mFinderHandle.get(); } -LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) : - LLFloater(LLSD()), - mPanelMainInventory(inventory_view), - mFilter(&inventory_view->getPanel()->getFilter()) +LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) : + LLFloater(LLSD()), + mPanelMainInventory(inventory_view), + mFilter(&inventory_view->getPanel()->getFilter()) { - buildFromFile("floater_inventory_view_finder.xml"); - updateElementsFromFilter(); + buildFromFile("floater_inventory_view_finder.xml"); + updateElementsFromFilter(); } BOOL LLFloaterInventoryFinder::postBuild() { - const LLRect& viewrect = mPanelMainInventory->getRect(); - setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); + const LLRect& viewrect = mPanelMainInventory->getRect(); + setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); - childSetAction("All", selectAllTypes, this); - childSetAction("None", selectNoTypes, this); + childSetAction("All", selectAllTypes, this); + childSetAction("None", selectNoTypes, this); - mSpinSinceHours = getChild("spin_hours_ago"); - childSetCommitCallback("spin_hours_ago", onTimeAgo, this); + mSpinSinceHours = getChild("spin_hours_ago"); + childSetCommitCallback("spin_hours_ago", onTimeAgo, this); - mSpinSinceDays = getChild("spin_days_ago"); - childSetCommitCallback("spin_days_ago", onTimeAgo, this); + mSpinSinceDays = getChild("spin_days_ago"); + childSetCommitCallback("spin_days_ago", onTimeAgo, this); - mCreatorSelf = getChild("check_created_by_me"); - mCreatorOthers = getChild("check_created_by_others"); - mCreatorSelf->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorSelfFilterCommit, this)); - mCreatorOthers->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorOtherFilterCommit, this)); + mCreatorSelf = getChild("check_created_by_me"); + mCreatorOthers = getChild("check_created_by_others"); + mCreatorSelf->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorSelfFilterCommit, this)); + mCreatorOthers->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorOtherFilterCommit, this)); - childSetAction("Close", onCloseBtn, this); + childSetAction("Close", onCloseBtn, this); - updateElementsFromFilter(); - return TRUE; + updateElementsFromFilter(); + return TRUE; } void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) { - LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; - if (!self) return; - - if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) - { - self->getChild("check_since_logoff")->setValue(false); - - U32 days = (U32)self->mSpinSinceDays->get(); - U32 hours = (U32)self->mSpinSinceHours->get(); - if (hours >= 24) - { - // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible. - // There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in - // this case add to days. Any value > 24 means they have input the hours manually, so do not add to the - // current day value. - if (24 == hours) // Got to 24 via spinner clicking or text input of 24 - { - days = days + hours / 24; - } - else // Text input, so do not add to days - { - days = hours / 24; - } - hours = (U32)hours % 24; - self->mSpinSinceHours->setFocus(false); - self->mSpinSinceDays->setFocus(false); - self->mSpinSinceDays->set((F32)days); - self->mSpinSinceHours->set((F32)hours); - self->mSpinSinceHours->setFocus(true); - } - } + LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; + if (!self) return; + + if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) + { + self->getChild("check_since_logoff")->setValue(false); + + U32 days = (U32)self->mSpinSinceDays->get(); + U32 hours = (U32)self->mSpinSinceHours->get(); + if (hours >= 24) + { + // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible. + // There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in + // this case add to days. Any value > 24 means they have input the hours manually, so do not add to the + // current day value. + if (24 == hours) // Got to 24 via spinner clicking or text input of 24 + { + days = days + hours / 24; + } + else // Text input, so do not add to days + { + days = hours / 24; + } + hours = (U32)hours % 24; + self->mSpinSinceHours->setFocus(false); + self->mSpinSinceDays->setFocus(false); + self->mSpinSinceDays->set((F32)days); + self->mSpinSinceHours->set((F32)hours); + self->mSpinSinceHours->setFocus(true); + } + } } void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) { - mFilter = filter; - updateElementsFromFilter(); + mFilter = filter; + updateElementsFromFilter(); } void LLFloaterInventoryFinder::updateElementsFromFilter() { - if (!mFilter) - return; - - // Get data needed for filter display - U32 filter_types = mFilter->getFilterObjectTypes(); - LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); - U32 hours = mFilter->getHoursAgo(); - U32 date_search_direction = mFilter->getDateSearchDirection(); - - LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType(); - bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF)); - bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS)); - - // update the ui elements - setTitle(mFilter->getName()); - - getChild("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); - - getChild("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); - getChild("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); - getChild("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); - getChild("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); - getChild("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL)); - getChild("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); - getChild("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); - getChild("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); - getChild("check_sound")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); - getChild("check_texture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); - getChild("check_snapshot")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); + if (!mFilter) + return; + + // Get data needed for filter display + U32 filter_types = mFilter->getFilterObjectTypes(); + LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); + U32 hours = mFilter->getHoursAgo(); + U32 date_search_direction = mFilter->getDateSearchDirection(); + + LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType(); + bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF)); + bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS)); + + // update the ui elements + setTitle(mFilter->getName()); + + getChild("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); + + getChild("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); + getChild("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); + getChild("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); + getChild("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + getChild("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL)); + getChild("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); + getChild("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); + getChild("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); + getChild("check_sound")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); + getChild("check_texture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); + getChild("check_snapshot")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); getChild("check_settings")->setValue((S32)(filter_types & 0x1 << LLInventoryType::IT_SETTINGS)); - getChild("check_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); + getChild("check_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); - getChild("check_created_by_me")->setValue(show_created_by_me); - getChild("check_created_by_others")->setValue(show_created_by_others); + getChild("check_created_by_me")->setValue(show_created_by_me); + getChild("check_created_by_others")->setValue(show_created_by_others); - getChild("check_since_logoff")->setValue(mFilter->isSinceLogoff()); - mSpinSinceHours->set((F32)(hours % 24)); - mSpinSinceDays->set((F32)(hours / 24)); - getChild("date_search_direction")->setSelectedIndex(date_search_direction); + getChild("check_since_logoff")->setValue(mFilter->isSinceLogoff()); + mSpinSinceHours->set((F32)(hours % 24)); + mSpinSinceDays->set((F32)(hours / 24)); + getChild("date_search_direction")->setSelectedIndex(date_search_direction); } void LLFloaterInventoryFinder::draw() { - U64 filter = 0xffffffffffffffffULL; - BOOL filtered_by_all_types = TRUE; - - if (!getChild("check_animation")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); - filtered_by_all_types = FALSE; - } - - - if (!getChild("check_calling_card")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_clothing")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_gesture")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_GESTURE); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_landmark")->getValue()) - - - { - filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_material")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_MATERIAL); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_notecard")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_object")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_OBJECT); - filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_script")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_LSL); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_sound")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_SOUND); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_texture")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); - filtered_by_all_types = FALSE; - } - - if (!getChild("check_snapshot")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); - filtered_by_all_types = FALSE; - } + U64 filter = 0xffffffffffffffffULL; + BOOL filtered_by_all_types = TRUE; + + if (!getChild("check_animation")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); + filtered_by_all_types = FALSE; + } + + + if (!getChild("check_calling_card")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_clothing")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_gesture")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_GESTURE); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_landmark")->getValue()) + + + { + filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_material")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_MATERIAL); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_notecard")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_object")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_OBJECT); + filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_script")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_LSL); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_sound")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_SOUND); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_texture")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); + filtered_by_all_types = FALSE; + } + + if (!getChild("check_snapshot")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); + filtered_by_all_types = FALSE; + } if (!getChild("check_settings")->getValue()) { @@ -1300,11 +1300,11 @@ void LLFloaterInventoryFinder::draw() filtered_by_all_types = FALSE; } - if (!filtered_by_all_types || (mPanelMainInventory->getPanel()->getFilter().getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE)) - { - // don't include folders in filter, unless I've selected everything or filtering by date - filter &= ~(0x1 << LLInventoryType::IT_CATEGORY); - } + if (!filtered_by_all_types || (mPanelMainInventory->getPanel()->getFilter().getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE)) + { + // don't include folders in filter, unless I've selected everything or filtering by date + filter &= ~(0x1 << LLInventoryType::IT_CATEGORY); + } bool is_sf_mode = mPanelMainInventory->isSingleFolderMode(); @@ -1328,28 +1328,28 @@ void LLFloaterInventoryFinder::draw() mPanelMainInventory->getPanel()->setFilterTypes(filter); } - if (getCheckSinceLogoff()) - { - mSpinSinceDays->set(0); - mSpinSinceHours->set(0); - } - U32 days = (U32)mSpinSinceDays->get(); - U32 hours = (U32)mSpinSinceHours->get(); - if (hours >= 24) - { - days = hours / 24; - hours = (U32)hours % 24; - // A UI element that has focus will not display a new value set to it - mSpinSinceHours->setFocus(false); - mSpinSinceDays->setFocus(false); - mSpinSinceDays->set((F32)days); - mSpinSinceHours->set((F32)hours); - mSpinSinceHours->setFocus(true); - } - hours += days * 24; - - - mPanelMainInventory->setFilterTextFromFilter(); + if (getCheckSinceLogoff()) + { + mSpinSinceDays->set(0); + mSpinSinceHours->set(0); + } + U32 days = (U32)mSpinSinceDays->get(); + U32 hours = (U32)mSpinSinceHours->get(); + if (hours >= 24) + { + days = hours / 24; + hours = (U32)hours % 24; + // A UI element that has focus will not display a new value set to it + mSpinSinceHours->setFocus(false); + mSpinSinceDays->setFocus(false); + mSpinSinceDays->set((F32)days); + mSpinSinceHours->set((F32)hours); + mSpinSinceHours->setFocus(true); + } + hours += days * 24; + + + mPanelMainInventory->setFilterTextFromFilter(); if(is_sf_mode && mPanelMainInventory->isGalleryViewMode()) { mPanelMainInventory->mCombinationGalleryPanel->getFilter().setHoursAgo(hours); @@ -1369,109 +1369,109 @@ void LLFloaterInventoryFinder::draw() mPanelMainInventory->getPanel()->setDateSearchDirection(getDateSearchDirection()); } - LLPanel::draw(); + LLPanel::draw(); } void LLFloaterInventoryFinder::onCreatorSelfFilterCommit() { - bool show_creator_self = mCreatorSelf->getValue(); - bool show_creator_other = mCreatorOthers->getValue(); + bool show_creator_self = mCreatorSelf->getValue(); + bool show_creator_other = mCreatorOthers->getValue(); - if(show_creator_self && show_creator_other) - { + if(show_creator_self && show_creator_other) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_ALL); - } - else if(show_creator_self) - { + } + else if(show_creator_self) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_SELF); - } - else if(!show_creator_self || !show_creator_other) - { + } + else if(!show_creator_self || !show_creator_other) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_OTHERS); - mCreatorOthers->set(TRUE); - } + mCreatorOthers->set(TRUE); + } } void LLFloaterInventoryFinder::onCreatorOtherFilterCommit() { - bool show_creator_self = mCreatorSelf->getValue(); - bool show_creator_other = mCreatorOthers->getValue(); + bool show_creator_self = mCreatorSelf->getValue(); + bool show_creator_other = mCreatorOthers->getValue(); - if(show_creator_self && show_creator_other) - { + if(show_creator_self && show_creator_other) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_ALL); - } - else if(show_creator_other) - { + } + else if(show_creator_other) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_OTHERS); - } - else if(!show_creator_other || !show_creator_self) - { + } + else if(!show_creator_other || !show_creator_self) + { mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_SELF); - mCreatorSelf->set(TRUE); - } + mCreatorSelf->set(TRUE); + } } BOOL LLFloaterInventoryFinder::getCheckShowEmpty() { - return getChild("check_show_empty")->getValue(); + return getChild("check_show_empty")->getValue(); } BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() { - return getChild("check_since_logoff")->getValue(); + return getChild("check_since_logoff")->getValue(); } U32 LLFloaterInventoryFinder::getDateSearchDirection() { - return getChild("date_search_direction")->getSelectedIndex(); + return getChild("date_search_direction")->getSelectedIndex(); } void LLFloaterInventoryFinder::onCloseBtn(void* user_data) { - LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; - finderp->closeFloater(); + LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; + finderp->closeFloater(); } // static void LLFloaterInventoryFinder::selectAllTypes(void* user_data) { - LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; - if(!self) return; - - self->getChild("check_animation")->setValue(TRUE); - self->getChild("check_calling_card")->setValue(TRUE); - self->getChild("check_clothing")->setValue(TRUE); - self->getChild("check_gesture")->setValue(TRUE); - self->getChild("check_landmark")->setValue(TRUE); - self->getChild("check_material")->setValue(TRUE); - self->getChild("check_notecard")->setValue(TRUE); - self->getChild("check_object")->setValue(TRUE); - self->getChild("check_script")->setValue(TRUE); - self->getChild("check_sound")->setValue(TRUE); - self->getChild("check_texture")->setValue(TRUE); - self->getChild("check_snapshot")->setValue(TRUE); + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + self->getChild("check_animation")->setValue(TRUE); + self->getChild("check_calling_card")->setValue(TRUE); + self->getChild("check_clothing")->setValue(TRUE); + self->getChild("check_gesture")->setValue(TRUE); + self->getChild("check_landmark")->setValue(TRUE); + self->getChild("check_material")->setValue(TRUE); + self->getChild("check_notecard")->setValue(TRUE); + self->getChild("check_object")->setValue(TRUE); + self->getChild("check_script")->setValue(TRUE); + self->getChild("check_sound")->setValue(TRUE); + self->getChild("check_texture")->setValue(TRUE); + self->getChild("check_snapshot")->setValue(TRUE); self->getChild("check_settings")->setValue(TRUE); } //static void LLFloaterInventoryFinder::selectNoTypes(void* user_data) { - LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; - if(!self) return; - - self->getChild("check_animation")->setValue(FALSE); - self->getChild("check_calling_card")->setValue(FALSE); - self->getChild("check_clothing")->setValue(FALSE); - self->getChild("check_gesture")->setValue(FALSE); - self->getChild("check_landmark")->setValue(FALSE); - self->getChild("check_material")->setValue(FALSE); - self->getChild("check_notecard")->setValue(FALSE); - self->getChild("check_object")->setValue(FALSE); - self->getChild("check_script")->setValue(FALSE); - self->getChild("check_sound")->setValue(FALSE); - self->getChild("check_texture")->setValue(FALSE); - self->getChild("check_snapshot")->setValue(FALSE); + LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; + if(!self) return; + + self->getChild("check_animation")->setValue(FALSE); + self->getChild("check_calling_card")->setValue(FALSE); + self->getChild("check_clothing")->setValue(FALSE); + self->getChild("check_gesture")->setValue(FALSE); + self->getChild("check_landmark")->setValue(FALSE); + self->getChild("check_material")->setValue(FALSE); + self->getChild("check_notecard")->setValue(FALSE); + self->getChild("check_object")->setValue(FALSE); + self->getChild("check_script")->setValue(FALSE); + self->getChild("check_sound")->setValue(FALSE); + self->getChild("check_texture")->setValue(FALSE); + self->getChild("check_snapshot")->setValue(FALSE); self->getChild("check_settings")->setValue(FALSE); } @@ -1480,28 +1480,28 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) void LLPanelMainInventory::initListCommandsHandlers() { - childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this)); + childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this)); childSetAction("view_mode_btn", boost::bind(&LLPanelMainInventory::onViewModeClick, this)); childSetAction("up_btn", boost::bind(&LLPanelMainInventory::onUpFolderClicked, this)); childSetAction("back_btn", boost::bind(&LLPanelMainInventory::onBackFolderClicked, this)); childSetAction("forward_btn", boost::bind(&LLPanelMainInventory::onForwardFolderClicked, this)); - mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2)); - mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); - mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); + mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2)); + mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); + mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2)); - mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_BOTTOM_LEFT, true); + mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_BOTTOM_LEFT, true); mMenuViewDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_view_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mViewMenuButton->setMenu(mMenuViewDefault, LLMenuButton::MP_BOTTOM_LEFT, true); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mMenuAddHandle = menu->getHandle(); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuAddHandle = menu->getHandle(); - mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); - // Update the trash button when selected item(s) get worn or taken off. - LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); + // Update the trash button when selected item(s) get worn or taken off. + LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); } void LLPanelMainInventory::updateListCommands() @@ -1513,15 +1513,15 @@ void LLPanelMainInventory::onAddButtonClick() // Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed // unless "Always show folders" is checked in the filter options. - LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); - if (menu) - { + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { disableAddIfNeeded(); - setUploadCostIfNeeded(); + setUploadCostIfNeeded(); - showActionMenu(menu,"add_btn"); - } + showActionMenu(menu,"add_btn"); + } } void LLPanelMainInventory::setActivePanel() @@ -1735,22 +1735,22 @@ LLUUID LLPanelMainInventory::getSingleFolderViewRoot() void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) { - if (menu) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLView* spawning_view = getChild (spawning_view_name); - S32 menu_x, menu_y; - //show menu in co-ordinates of panel - spawning_view->localPointToOtherView(0, 0, &menu_x, &menu_y, this); - LLMenuGL::showPopup(this, menu, menu_x, menu_y); - } + if (menu) + { + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLView* spawning_view = getChild (spawning_view_name); + S32 menu_x, menu_y; + //show menu in co-ordinates of panel + spawning_view->localPointToOtherView(0, 0, &menu_x, &menu_y, this); + LLMenuGL::showPopup(this, menu, menu_x, menu_y); + } } void LLPanelMainInventory::onClipboardAction(const LLSD& userdata) { - std::string command_name = userdata.asString(); - getActivePanel()->doToSelected(command_name); + std::string command_name = userdata.asString(); + getActivePanel()->doToSelected(command_name); } void LLPanelMainInventory::saveTexture(const LLSD& userdata) @@ -1771,89 +1771,89 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata) item_id = static_cast(current_item->getViewModelItem())->getUUID(); } - LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance("preview_texture", LLSD(item_id), TAKE_FOCUS_YES); - if (preview_texture) - { - preview_texture->openToSave(); - } + LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance("preview_texture", LLSD(item_id), TAKE_FOCUS_YES); + if (preview_texture) + { + preview_texture->openToSave(); + } } void LLPanelMainInventory::onCustomAction(const LLSD& userdata) { - if (!isActionEnabled(userdata)) - return; - - const std::string command_name = userdata.asString(); - - if (command_name == "new_window") - { - newWindow(); - } - if (command_name == "sort_by_name") - { - const LLSD arg = "name"; - setSortBy(arg); - } - if (command_name == "sort_by_recent") - { - const LLSD arg = "date"; - setSortBy(arg); - } - if (command_name == "sort_folders_by_name") - { - const LLSD arg = "foldersalwaysbyname"; - setSortBy(arg); - } - if (command_name == "sort_system_folders_to_top") - { - const LLSD arg = "systemfolderstotop"; - setSortBy(arg); - } - if (command_name == "show_filters") - { - toggleFindOptions(); - } - if (command_name == "reset_filters") - { - resetFilters(); - } - if (command_name == "close_folders") - { - closeAllFolders(); - } - if (command_name == "empty_trash") - { - const std::string notification = "ConfirmEmptyTrash"; - gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH); - } - if (command_name == "empty_lostnfound") - { - const std::string notification = "ConfirmEmptyLostAndFound"; - gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND); - } - if (command_name == "save_texture") - { - saveTexture(userdata); - } - // This doesn't currently work, since the viewer can't change an assetID an item. - if (command_name == "regenerate_link") - { - LLInventoryPanel *active_panel = getActivePanel(); - LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem(); - if (!current_item) - { - return; - } - const LLUUID item_id = static_cast(current_item->getViewModelItem())->getUUID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item) - { - item->regenerateLink(); - } - active_panel->setSelection(item_id, TAKE_FOCUS_NO); - } - if (command_name == "find_original") - { + if (!isActionEnabled(userdata)) + return; + + const std::string command_name = userdata.asString(); + + if (command_name == "new_window") + { + newWindow(); + } + if (command_name == "sort_by_name") + { + const LLSD arg = "name"; + setSortBy(arg); + } + if (command_name == "sort_by_recent") + { + const LLSD arg = "date"; + setSortBy(arg); + } + if (command_name == "sort_folders_by_name") + { + const LLSD arg = "foldersalwaysbyname"; + setSortBy(arg); + } + if (command_name == "sort_system_folders_to_top") + { + const LLSD arg = "systemfolderstotop"; + setSortBy(arg); + } + if (command_name == "show_filters") + { + toggleFindOptions(); + } + if (command_name == "reset_filters") + { + resetFilters(); + } + if (command_name == "close_folders") + { + closeAllFolders(); + } + if (command_name == "empty_trash") + { + const std::string notification = "ConfirmEmptyTrash"; + gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH); + } + if (command_name == "empty_lostnfound") + { + const std::string notification = "ConfirmEmptyLostAndFound"; + gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND); + } + if (command_name == "save_texture") + { + saveTexture(userdata); + } + // This doesn't currently work, since the viewer can't change an assetID an item. + if (command_name == "regenerate_link") + { + LLInventoryPanel *active_panel = getActivePanel(); + LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem(); + if (!current_item) + { + return; + } + const LLUUID item_id = static_cast(current_item->getViewModelItem())->getUUID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item) + { + item->regenerateLink(); + } + active_panel->setSelection(item_id, TAKE_FOCUS_NO); + } + if (command_name == "find_original") + { if(mSingleFolderMode && isGalleryViewMode()) { LLInventoryObject *obj = gInventory.getObject(mCombinationGalleryPanel->getFirstSelectedItemID()); @@ -1864,17 +1864,17 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) } else { - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (!current_item) - { - return; - } - static_cast(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto"); + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) + { + return; + } + static_cast(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto"); } - } + } - if (command_name == "find_links") - { + if (command_name == "find_links") + { if(mSingleFolderMode && isGalleryViewMode()) { LLFloaterSidePanelContainer* inventory_container = newWindow(); @@ -1906,10 +1906,10 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) const std::string &item_name = current_item->getViewModelItem()->getName(); findLinks(item_id, item_name); } - } + } - if (command_name == "replace_links") - { + if (command_name == "replace_links") + { LLSD params; if(mSingleFolderMode && isGalleryViewMode()) { @@ -1917,23 +1917,23 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) } else { - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (current_item) - { - LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem(); + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (current_item) + { + LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem(); - if (bridge) - { - LLInventoryObject* obj = bridge->getInventoryObject(); - if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER) - { - params = LLSD(obj->getUUID()); - } - } - } + if (bridge) + { + LLInventoryObject* obj = bridge->getInventoryObject(); + if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER) + { + params = LLSD(obj->getUUID()); + } + } } - LLFloaterReg::showInstance("linkreplace", params); - } + } + LLFloaterReg::showInstance("linkreplace", params); + } if (command_name == "close_inv_windows") { @@ -1954,20 +1954,20 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) getCurrentFilter().toggleSearchVisibilityOutfits(); } - if (command_name == "toggle_search_trash") - { + if (command_name == "toggle_search_trash") + { getCurrentFilter().toggleSearchVisibilityTrash(); - } + } - if (command_name == "toggle_search_library") - { + if (command_name == "toggle_search_library") + { getCurrentFilter().toggleSearchVisibilityLibrary(); - } + } - if (command_name == "include_links") - { + if (command_name == "include_links") + { getCurrentFilter().toggleSearchVisibilityLinks(); - } + } if (command_name == "share") { @@ -2001,15 +2001,15 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility ) { - if(!new_visibility) - { - LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); - if (menu) - { - menu->setVisible(FALSE); - } - getActivePanel()->getRootFolder()->finishRenamingItem(); - } + if(!new_visibility) + { + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { + menu->setVisible(FALSE); + } + getActivePanel()->getRootFolder()->finishRenamingItem(); + } } bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata) @@ -2027,124 +2027,124 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata) inv_item = dynamic_cast(static_cast(current_item->getViewModelItem())->getInventoryObject()); } } - if(inv_item) - { - bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED); + if(inv_item) + { + bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED); LLInventoryType::EType curr_type = inv_item->getInventoryType(); - return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT); - } + return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT); + } - return false; + return false; } BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) { - const std::string command_name = userdata.asString(); - if (command_name == "not_empty") - { - BOOL status = FALSE; - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (current_item) - { - const LLUUID& item_id = static_cast(current_item->getViewModelItem())->getUUID(); - LLInventoryModel::cat_array_t* cat_array; - LLInventoryModel::item_array_t* item_array; - gInventory.getDirectDescendentsOf(item_id, cat_array, item_array); - status = (0 == cat_array->size() && 0 == item_array->size()); - } - return status; - } - if (command_name == "delete") - { - return getActivePanel()->isSelectionRemovable(); - } - if (command_name == "save_texture") - { - return isSaveTextureEnabled(userdata); - } - if (command_name == "find_original") - { + const std::string command_name = userdata.asString(); + if (command_name == "not_empty") + { + BOOL status = FALSE; + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (current_item) + { + const LLUUID& item_id = static_cast(current_item->getViewModelItem())->getUUID(); + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(item_id, cat_array, item_array); + status = (0 == cat_array->size() && 0 == item_array->size()); + } + return status; + } + if (command_name == "delete") + { + return getActivePanel()->isSelectionRemovable(); + } + if (command_name == "save_texture") + { + return isSaveTextureEnabled(userdata); + } + if (command_name == "find_original") + { LLUUID item_id; if(mSingleFolderMode && isGalleryViewMode()) { item_id = mCombinationGalleryPanel->getFirstSelectedItemID(); } else{ - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (!current_item) return FALSE; + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) return FALSE; item_id = static_cast(current_item->getViewModelItem())->getUUID(); } - const LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item && item->getIsLinkType() && !item->getIsBrokenLink()) - { - return TRUE; - } - return FALSE; - } + const LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item && item->getIsLinkType() && !item->getIsBrokenLink()) + { + return TRUE; + } + return FALSE; + } - if (command_name == "find_links") - { + if (command_name == "find_links") + { LLUUID item_id; if(mSingleFolderMode && isGalleryViewMode()) { item_id = mCombinationGalleryPanel->getFirstSelectedItemID(); } else{ - LLFolderView* root = getActivePanel()->getRootFolder(); - std::set selection_set = root->getSelectionList(); - if (selection_set.size() != 1) return FALSE; - LLFolderViewItem* current_item = root->getCurSelectedItem(); - if (!current_item) return FALSE; - item_id = static_cast(current_item->getViewModelItem())->getUUID(); - } - const LLInventoryObject *obj = gInventory.getObject(item_id); - if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType())) - { - return TRUE; - } - return FALSE; - } - // This doesn't currently work, since the viewer can't change an assetID an item. - if (command_name == "regenerate_link") - { - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (!current_item) return FALSE; - const LLUUID& item_id = static_cast(current_item->getViewModelItem())->getUUID(); - const LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item && item->getIsBrokenLink()) - { - return TRUE; - } - return FALSE; - } - - if (command_name == "share") - { + LLFolderView* root = getActivePanel()->getRootFolder(); + std::set selection_set = root->getSelectionList(); + if (selection_set.size() != 1) return FALSE; + LLFolderViewItem* current_item = root->getCurSelectedItem(); + if (!current_item) return FALSE; + item_id = static_cast(current_item->getViewModelItem())->getUUID(); + } + const LLInventoryObject *obj = gInventory.getObject(item_id); + if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType())) + { + return TRUE; + } + return FALSE; + } + // This doesn't currently work, since the viewer can't change an assetID an item. + if (command_name == "regenerate_link") + { + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) return FALSE; + const LLUUID& item_id = static_cast(current_item->getViewModelItem())->getUUID(); + const LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item && item->getIsBrokenLink()) + { + return TRUE; + } + return FALSE; + } + + if (command_name == "share") + { if(mSingleFolderMode && isGalleryViewMode()) { return can_share_item(mCombinationGalleryPanel->getFirstSelectedItemID()); } else{ - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); - if (!current_item) return FALSE; - LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel("inventory"); - return parent ? parent->canShare() : FALSE; - } - } - if (command_name == "empty_trash") - { - const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); - return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); - } - if (command_name == "empty_lostnfound") - { - const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); - return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); - } - - return TRUE; + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) return FALSE; + LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel("inventory"); + return parent ? parent->canShare() : FALSE; + } + } + if (command_name == "empty_trash") + { + const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); + return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); + } + if (command_name == "empty_lostnfound") + { + const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); + return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); + } + + return TRUE; } bool LLPanelMainInventory::isActionVisible(const LLSD& userdata) @@ -2164,47 +2164,47 @@ bool LLPanelMainInventory::isActionVisible(const LLSD& userdata) BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) { - U32 sort_order_mask = (mSingleFolderMode && isGalleryViewMode()) ? mCombinationGalleryPanel->getSortOrder() : getActivePanel()->getSortOrder(); - const std::string command_name = userdata.asString(); - if (command_name == "sort_by_name") - { - return ~sort_order_mask & LLInventoryFilter::SO_DATE; - } + U32 sort_order_mask = (mSingleFolderMode && isGalleryViewMode()) ? mCombinationGalleryPanel->getSortOrder() : getActivePanel()->getSortOrder(); + const std::string command_name = userdata.asString(); + if (command_name == "sort_by_name") + { + return ~sort_order_mask & LLInventoryFilter::SO_DATE; + } - if (command_name == "sort_by_recent") - { - return sort_order_mask & LLInventoryFilter::SO_DATE; - } + if (command_name == "sort_by_recent") + { + return sort_order_mask & LLInventoryFilter::SO_DATE; + } - if (command_name == "sort_folders_by_name") - { - return sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME; - } + if (command_name == "sort_folders_by_name") + { + return sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME; + } - if (command_name == "sort_system_folders_to_top") - { - return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; - } + if (command_name == "sort_system_folders_to_top") + { + return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + } if (command_name == "toggle_search_outfits") { return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_OUTFITS) != 0; } - if (command_name == "toggle_search_trash") - { - return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0; - } + if (command_name == "toggle_search_trash") + { + return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0; + } - if (command_name == "toggle_search_library") - { - return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0; - } + if (command_name == "toggle_search_library") + { + return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0; + } - if (command_name == "include_links") - { + if (command_name == "include_links") + { return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0; - } + } if (command_name == "list_view") { @@ -2219,20 +2219,20 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) return isCombinationViewMode(); } - return FALSE; + return FALSE; } void LLPanelMainInventory::setUploadCostIfNeeded() { - LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); - if(mNeedUploadCost && menu) - { - const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); - const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if(mNeedUploadCost && menu) + { + const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); + const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); - menu->getChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); - menu->getChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); - } + menu->getChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); + menu->getChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); + } } bool is_add_allowed(LLUUID folder_id) @@ -2412,7 +2412,7 @@ void LLPanelMainInventory::updateCombinationVisibility() { mCombinationGalleryPanel->handleModifiedFilter(); } - + getActivePanel()->getRootFolder(); if (mReshapeInvLayout @@ -2536,7 +2536,7 @@ void LLPanelMainInventory::setViewMode(EViewModeType mode) sort_order = mCombinationInventoryPanel->getSortOrder(); break; } - + LLUUID cur_root = getCurrentSFVRoot(); mViewMode = mode; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 91c33b461f..7f111d7619 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpanelvolume.cpp * @brief Object editing (position, scale, etc.) in the tools floater * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -90,63 +90,63 @@ const F32 DEFAULT_GRAVITY_MULTIPLIER = 1.f; const F32 DEFAULT_DENSITY = 1000.f; // "Features" Tab -BOOL LLPanelVolume::postBuild() +BOOL LLPanelVolume::postBuild() { - // Flexible Objects Parameters - { - childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL); - childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL); - childSetCommitCallback("FlexNumSections",onCommitFlexible,this); - getChild("FlexNumSections")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexGravity",onCommitFlexible,this); - getChild("FlexGravity")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexFriction",onCommitFlexible,this); - getChild("FlexFriction")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexWind",onCommitFlexible,this); - getChild("FlexWind")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexTension",onCommitFlexible,this); - getChild("FlexTension")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexForceX",onCommitFlexible,this); - getChild("FlexForceX")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexForceY",onCommitFlexible,this); - getChild("FlexForceY")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("FlexForceZ",onCommitFlexible,this); - getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); - } - - // LIGHT Parameters - { - childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch){ - LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2)); - LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2)); - childSetCommitCallback("colorswatch",onCommitLight,this); - } - - LLTextureCtrl* LightTexPicker = getChild("light texture control"); - if (LightTexPicker) - { - LightTexPicker->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelTexture, this, _2)); - LightTexPicker->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectTexture, this, _2)); - childSetCommitCallback("light texture control", onCommitLight, this); - } - - childSetCommitCallback("Light Intensity",onCommitLight,this); - getChild("Light Intensity")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("Light Radius",onCommitLight,this); - getChild("Light Radius")->setValidateBeforeCommit(precommitValidate); - childSetCommitCallback("Light Falloff",onCommitLight,this); - getChild("Light Falloff")->setValidateBeforeCommit(precommitValidate); - - childSetCommitCallback("Light FOV", onCommitLight, this); - getChild("Light FOV")->setValidateBeforeCommit( precommitValidate); - childSetCommitCallback("Light Focus", onCommitLight, this); - getChild("Light Focus")->setValidateBeforeCommit( precommitValidate); - childSetCommitCallback("Light Ambiance", onCommitLight, this); - getChild("Light Ambiance")->setValidateBeforeCommit( precommitValidate); - } - + // Flexible Objects Parameters + { + childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL); + childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL); + childSetCommitCallback("FlexNumSections",onCommitFlexible,this); + getChild("FlexNumSections")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexGravity",onCommitFlexible,this); + getChild("FlexGravity")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexFriction",onCommitFlexible,this); + getChild("FlexFriction")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexWind",onCommitFlexible,this); + getChild("FlexWind")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexTension",onCommitFlexible,this); + getChild("FlexTension")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexForceX",onCommitFlexible,this); + getChild("FlexForceX")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexForceY",onCommitFlexible,this); + getChild("FlexForceY")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("FlexForceZ",onCommitFlexible,this); + getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); + } + + // LIGHT Parameters + { + childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch){ + LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2)); + LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2)); + childSetCommitCallback("colorswatch",onCommitLight,this); + } + + LLTextureCtrl* LightTexPicker = getChild("light texture control"); + if (LightTexPicker) + { + LightTexPicker->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelTexture, this, _2)); + LightTexPicker->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectTexture, this, _2)); + childSetCommitCallback("light texture control", onCommitLight, this); + } + + childSetCommitCallback("Light Intensity",onCommitLight,this); + getChild("Light Intensity")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("Light Radius",onCommitLight,this); + getChild("Light Radius")->setValidateBeforeCommit(precommitValidate); + childSetCommitCallback("Light Falloff",onCommitLight,this); + getChild("Light Falloff")->setValidateBeforeCommit(precommitValidate); + + childSetCommitCallback("Light FOV", onCommitLight, this); + getChild("Light FOV")->setValidateBeforeCommit( precommitValidate); + childSetCommitCallback("Light Focus", onCommitLight, this); + getChild("Light Focus")->setValidateBeforeCommit( precommitValidate); + childSetCommitCallback("Light Ambiance", onCommitLight, this); + getChild("Light Ambiance")->setValidateBeforeCommit( precommitValidate); + } + // REFLECTION PROBE Parameters { childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this); @@ -156,71 +156,71 @@ BOOL LLPanelVolume::postBuild() childSetCommitCallback("Probe Near Clip", onCommitProbe, this); } - // PHYSICS Parameters - { - // PhysicsShapeType combobox - mComboPhysicsShapeType = getChild("Physics Shape Type Combo Ctrl"); - mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType)); - - // PhysicsGravity - mSpinPhysicsGravity = getChild("Physics Gravity"); - mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity)); + // PHYSICS Parameters + { + // PhysicsShapeType combobox + mComboPhysicsShapeType = getChild("Physics Shape Type Combo Ctrl"); + mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType)); + + // PhysicsGravity + mSpinPhysicsGravity = getChild("Physics Gravity"); + mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity)); - // PhysicsFriction - mSpinPhysicsFriction = getChild("Physics Friction"); - mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction)); + // PhysicsFriction + mSpinPhysicsFriction = getChild("Physics Friction"); + mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction)); - // PhysicsDensity - mSpinPhysicsDensity = getChild("Physics Density"); - mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity)); + // PhysicsDensity + mSpinPhysicsDensity = getChild("Physics Density"); + mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity)); - // PhysicsRestitution - mSpinPhysicsRestitution = getChild("Physics Restitution"); - mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); - } + // PhysicsRestitution + mSpinPhysicsRestitution = getChild("Physics Restitution"); + mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); + } mMenuClipboardFeatures = getChild("clipboard_features_params_btn"); mMenuClipboardLight = getChild("clipboard_light_params_btn"); - std::map material_name_map; - material_name_map["Stone"]= LLTrans::getString("Stone"); - material_name_map["Metal"]= LLTrans::getString("Metal"); - material_name_map["Glass"]= LLTrans::getString("Glass"); - material_name_map["Wood"]= LLTrans::getString("Wood"); - material_name_map["Flesh"]= LLTrans::getString("Flesh"); - material_name_map["Plastic"]= LLTrans::getString("Plastic"); - material_name_map["Rubber"]= LLTrans::getString("Rubber"); - material_name_map["Light"]= LLTrans::getString("Light"); - - LLMaterialTable::basic.initTableTransNames(material_name_map); - - // material type popup - mComboMaterial = getChild("material"); - childSetCommitCallback("material",onCommitMaterial,this); - mComboMaterial->removeall(); - - for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); - iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo* minfop = *iter; - if (minfop->mMCode != LL_MCODE_LIGHT) - { - mComboMaterial->add(minfop->mName); - } - } - mComboMaterialItemCount = mComboMaterial->getItemCount(); - - // Start with everyone disabled - clearCtrls(); - - return TRUE; + std::map material_name_map; + material_name_map["Stone"]= LLTrans::getString("Stone"); + material_name_map["Metal"]= LLTrans::getString("Metal"); + material_name_map["Glass"]= LLTrans::getString("Glass"); + material_name_map["Wood"]= LLTrans::getString("Wood"); + material_name_map["Flesh"]= LLTrans::getString("Flesh"); + material_name_map["Plastic"]= LLTrans::getString("Plastic"); + material_name_map["Rubber"]= LLTrans::getString("Rubber"); + material_name_map["Light"]= LLTrans::getString("Light"); + + LLMaterialTable::basic.initTableTransNames(material_name_map); + + // material type popup + mComboMaterial = getChild("material"); + childSetCommitCallback("material",onCommitMaterial,this); + mComboMaterial->removeall(); + + for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); + iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo* minfop = *iter; + if (minfop->mMCode != LL_MCODE_LIGHT) + { + mComboMaterial->add(minfop->mName); + } + } + mComboMaterialItemCount = mComboMaterial->getItemCount(); + + // Start with everyone disabled + clearCtrls(); + + return TRUE; } LLPanelVolume::LLPanelVolume() - : LLPanel(), - mComboMaterialItemCount(0) + : LLPanel(), + mComboMaterialItemCount(0) { - setMouseOpaque(FALSE); + setMouseOpaque(FALSE); mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2)); mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2)); @@ -229,142 +229,142 @@ LLPanelVolume::LLPanelVolume() LLPanelVolume::~LLPanelVolume() { - // Children all cleaned up by default view destructor. + // Children all cleaned up by default view destructor. } void LLPanelVolume::getState( ) { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); - LLViewerObject* root_objectp = objectp; - if(!objectp) - { - objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - // *FIX: shouldn't we just keep the child? - if (objectp) - { - LLViewerObject* parentp = objectp->getRootEdit(); - - if (parentp) - { - root_objectp = parentp; - } - else - { - root_objectp = objectp; - } - } - } - - LLVOVolume *volobjp = NULL; - if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) - { - volobjp = (LLVOVolume *)objectp; - } - LLVOVolume *root_volobjp = NULL; + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); + LLViewerObject* root_objectp = objectp; + if(!objectp) + { + objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + // *FIX: shouldn't we just keep the child? + if (objectp) + { + LLViewerObject* parentp = objectp->getRootEdit(); + + if (parentp) + { + root_objectp = parentp; + } + else + { + root_objectp = objectp; + } + } + } + + LLVOVolume *volobjp = NULL; + if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) + { + volobjp = (LLVOVolume *)objectp; + } + LLVOVolume *root_volobjp = NULL; if (root_objectp && (root_objectp->getPCode() == LL_PCODE_VOLUME)) { root_volobjp = (LLVOVolume *)root_objectp; } - - if( !objectp ) - { - //forfeit focus - if (gFocusMgr.childHasKeyboardFocus(this)) - { - gFocusMgr.setKeyboardFocus(NULL); - } - - // Disable all text input fields - clearCtrls(); - - return; - } - - LLUUID owner_id; - std::string owner_name; - LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); - - // BUG? Check for all objects being editable? - BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); - BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) - && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; - BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && + + if( !objectp ) + { + //forfeit focus + if (gFocusMgr.childHasKeyboardFocus(this)) + { + gFocusMgr.setKeyboardFocus(NULL); + } + + // Disable all text input fields + clearCtrls(); + + return; + } + + LLUUID owner_id; + std::string owner_name; + LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); + + // BUG? Check for all objects being editable? + BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); + BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) + && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; + BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1; - // Select Single Message - if (single_volume) - { - getChildView("edit_object")->setVisible(true); - getChildView("edit_object")->setEnabled(true); - getChildView("select_single")->setVisible(false); - } - else - { - getChildView("edit_object")->setVisible(false); - getChildView("select_single")->setVisible(true); - getChildView("select_single")->setEnabled(true); - } - - // Light properties - BOOL is_light = volobjp && volobjp->getIsLight(); - getChild("Light Checkbox Ctrl")->setValue(is_light); - getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); - - if (is_light && editable && single_volume) - { - //mLabelColor ->setEnabled( TRUE ); - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch) - { - LightColorSwatch->setEnabled( TRUE ); - LightColorSwatch->setValid( TRUE ); - LightColorSwatch->set(volobjp->getLightSRGBBaseColor()); - } - - LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); - if (LightTextureCtrl) - { - LightTextureCtrl->setEnabled(TRUE); - LightTextureCtrl->setValid(TRUE); - LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); - } - - getChildView("Light Intensity")->setEnabled(true); - getChildView("Light Radius")->setEnabled(true); - getChildView("Light Falloff")->setEnabled(true); - - getChildView("Light FOV")->setEnabled(true); - getChildView("Light Focus")->setEnabled(true); - getChildView("Light Ambiance")->setEnabled(true); - - getChild("Light Intensity")->setValue(volobjp->getLightIntensity()); - getChild("Light Radius")->setValue(volobjp->getLightRadius()); - getChild("Light Falloff")->setValue(volobjp->getLightFalloff()); - - LLVector3 params = volobjp->getSpotLightParams(); - getChild("Light FOV")->setValue(params.mV[0]); - getChild("Light Focus")->setValue(params.mV[1]); - getChild("Light Ambiance")->setValue(params.mV[2]); - - mLightSavedColor = volobjp->getLightSRGBBaseColor(); - } - else - { - getChild("Light Intensity", true)->clear(); - getChild("Light Radius", true)->clear(); - getChild("Light Falloff", true)->clear(); - - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch) - { - LightColorSwatch->setEnabled( FALSE ); - LightColorSwatch->setValid( FALSE ); - } - LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); - if (LightTextureCtrl) - { - LightTextureCtrl->setEnabled(FALSE); - LightTextureCtrl->setValid(FALSE); + // Select Single Message + if (single_volume) + { + getChildView("edit_object")->setVisible(true); + getChildView("edit_object")->setEnabled(true); + getChildView("select_single")->setVisible(false); + } + else + { + getChildView("edit_object")->setVisible(false); + getChildView("select_single")->setVisible(true); + getChildView("select_single")->setEnabled(true); + } + + // Light properties + BOOL is_light = volobjp && volobjp->getIsLight(); + getChild("Light Checkbox Ctrl")->setValue(is_light); + getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); + + if (is_light && editable && single_volume) + { + //mLabelColor ->setEnabled( TRUE ); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch) + { + LightColorSwatch->setEnabled( TRUE ); + LightColorSwatch->setValid( TRUE ); + LightColorSwatch->set(volobjp->getLightSRGBBaseColor()); + } + + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(TRUE); + LightTextureCtrl->setValid(TRUE); + LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); + } + + getChildView("Light Intensity")->setEnabled(true); + getChildView("Light Radius")->setEnabled(true); + getChildView("Light Falloff")->setEnabled(true); + + getChildView("Light FOV")->setEnabled(true); + getChildView("Light Focus")->setEnabled(true); + getChildView("Light Ambiance")->setEnabled(true); + + getChild("Light Intensity")->setValue(volobjp->getLightIntensity()); + getChild("Light Radius")->setValue(volobjp->getLightRadius()); + getChild("Light Falloff")->setValue(volobjp->getLightFalloff()); + + LLVector3 params = volobjp->getSpotLightParams(); + getChild("Light FOV")->setValue(params.mV[0]); + getChild("Light Focus")->setValue(params.mV[1]); + getChild("Light Ambiance")->setValue(params.mV[2]); + + mLightSavedColor = volobjp->getLightSRGBBaseColor(); + } + else + { + getChild("Light Intensity", true)->clear(); + getChild("Light Radius", true)->clear(); + getChild("Light Falloff", true)->clear(); + + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch) + { + LightColorSwatch->setEnabled( FALSE ); + LightColorSwatch->setValid( FALSE ); + } + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(FALSE); + LightTextureCtrl->setValid(FALSE); if (objectp->isAttachment()) { @@ -374,16 +374,16 @@ void LLPanelVolume::getState( ) { LightTextureCtrl->setImmediateFilterPermMask(PERM_NONE); } - } + } - getChildView("Light Intensity")->setEnabled(false); - getChildView("Light Radius")->setEnabled(false); - getChildView("Light Falloff")->setEnabled(false); + getChildView("Light Intensity")->setEnabled(false); + getChildView("Light Radius")->setEnabled(false); + getChildView("Light Falloff")->setEnabled(false); - getChildView("Light FOV")->setEnabled(false); - getChildView("Light Focus")->setEnabled(false); - getChildView("Light Ambiance")->setEnabled(false); - } + getChildView("Light FOV")->setEnabled(false); + getChildView("Light Focus")->setEnabled(false); + getChildView("Light Ambiance")->setEnabled(false); + } // Reflection Probe BOOL is_probe = volobjp && volobjp->isReflectionProbe(); @@ -394,7 +394,7 @@ void LLPanelVolume::getState( ) bool mirrors_enabled = LLPipeline::RenderMirrors; - getChildView("Probe Update Type")->setVisible(mirrors_enabled); + getChildView("Probe Update Type")->setVisible(mirrors_enabled); getChildView("Probe Update Label")->setVisible(mirrors_enabled); getChildView("Probe Dynamic")->setVisible(!mirrors_enabled); @@ -425,7 +425,7 @@ void LLPanelVolume::getState( ) } - std::string update_type = "Static"; + std::string update_type = "Static"; if (volobjp->getReflectionProbeIsDynamic() && !volobjp->getReflectionProbeIsMirror()) { @@ -437,9 +437,9 @@ void LLPanelVolume::getState( ) } else if (volobjp->getReflectionProbeIsDynamic() && volobjp->getReflectionProbeIsMirror()) - { - update_type = "Dynamic Mirror"; - } + { + update_type = "Dynamic Mirror"; + } getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror"); @@ -451,12 +451,12 @@ void LLPanelVolume::getState( ) } // Animated Mesh - BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject(); - getChild("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh); + BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject(); + getChild("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh); BOOL enabled_animated_object_box = FALSE; if (root_volobjp && root_volobjp == volobjp) { - enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable; + enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable; #if 0 if (!enabled_animated_object_box) { @@ -469,7 +469,7 @@ void LLPanelVolume::getState( ) } } #endif - if (enabled_animated_object_box && !is_animated_mesh && + if (enabled_animated_object_box && !is_animated_mesh && root_volobjp->isAttachment() && !gAgentAvatarp->canAttachMoreAnimatedObjects()) { // Turning this attachment animated would cause us to exceed the limit. @@ -477,182 +477,182 @@ void LLPanelVolume::getState( ) } } getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(enabled_animated_object_box); - - //refresh any bakes - if (root_volobjp) - { - root_volobjp->refreshBakeTexture(); - - LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* objectp = *iter; - if (objectp) - { - objectp->refreshBakeTexture(); - } - } - - if (gAgentAvatarp) - { - gAgentAvatarp->updateMeshVisibility(); - } - } - - // Flexible properties - BOOL is_flexible = volobjp && volobjp->isFlexible(); - getChild("Flexible1D Checkbox Ctrl")->setValue(is_flexible); - if (is_flexible || (volobjp && volobjp->canBeFlexible())) - { - getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced()); - } - else - { - getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); - } - if (is_flexible && editable && single_volume) - { - getChildView("FlexNumSections")->setVisible(true); - getChildView("FlexGravity")->setVisible(true); - getChildView("FlexTension")->setVisible(true); - getChildView("FlexFriction")->setVisible(true); - getChildView("FlexWind")->setVisible(true); - getChildView("FlexForceX")->setVisible(true); - getChildView("FlexForceY")->setVisible(true); - getChildView("FlexForceZ")->setVisible(true); - - getChildView("FlexNumSections")->setEnabled(true); - getChildView("FlexGravity")->setEnabled(true); - getChildView("FlexTension")->setEnabled(true); - getChildView("FlexFriction")->setEnabled(true); - getChildView("FlexWind")->setEnabled(true); - getChildView("FlexForceX")->setEnabled(true); - getChildView("FlexForceY")->setEnabled(true); - getChildView("FlexForceZ")->setEnabled(true); - - LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - - getChild("FlexNumSections")->setValue((F32)attributes->getSimulateLOD()); - getChild("FlexGravity")->setValue(attributes->getGravity()); - getChild("FlexTension")->setValue(attributes->getTension()); - getChild("FlexFriction")->setValue(attributes->getAirFriction()); - getChild("FlexWind")->setValue(attributes->getWindSensitivity()); - getChild("FlexForceX")->setValue(attributes->getUserForce().mV[VX]); - getChild("FlexForceY")->setValue(attributes->getUserForce().mV[VY]); - getChild("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]); - } - else - { - getChild("FlexNumSections", true)->clear(); - getChild("FlexGravity", true)->clear(); - getChild("FlexTension", true)->clear(); - getChild("FlexFriction", true)->clear(); - getChild("FlexWind", true)->clear(); - getChild("FlexForceX", true)->clear(); - getChild("FlexForceY", true)->clear(); - getChild("FlexForceZ", true)->clear(); - - getChildView("FlexNumSections")->setEnabled(false); - getChildView("FlexGravity")->setEnabled(false); - getChildView("FlexTension")->setEnabled(false); - getChildView("FlexFriction")->setEnabled(false); - getChildView("FlexWind")->setEnabled(false); - getChildView("FlexForceX")->setEnabled(false); - getChildView("FlexForceY")->setEnabled(false); - getChildView("FlexForceZ")->setEnabled(false); - } - - // Material properties - - // Update material part - // slightly inefficient - materials are unique per object, not per TE - U8 material_code = 0; - struct f : public LLSelectedTEGetFunctor - { - U8 get(LLViewerObject* object, S32 te) - { - return object->getMaterial(); - } - } func; - bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); - std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); - if (editable && single_volume && material_same) - { - mComboMaterial->setEnabled( TRUE ); - if (material_code == LL_MCODE_LIGHT) - { - if (mComboMaterial->getItemCount() == mComboMaterialItemCount) - { - mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); - } - mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); - } - else - { - if (mComboMaterial->getItemCount() != mComboMaterialItemCount) - { - mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); - } - - mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); - } - } - else - { - mComboMaterial->setEnabled( FALSE ); - } - - // Physics properties - - mSpinPhysicsGravity->set(objectp->getPhysicsGravity()); - mSpinPhysicsGravity->setEnabled(editable); - - mSpinPhysicsFriction->set(objectp->getPhysicsFriction()); - mSpinPhysicsFriction->setEnabled(editable); - - mSpinPhysicsDensity->set(objectp->getPhysicsDensity()); - mSpinPhysicsDensity->setEnabled(editable); - - mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution()); - mSpinPhysicsRestitution->setEnabled(editable); - - // update the physics shape combo to include allowed physics shapes - mComboPhysicsShapeType->removeall(); - mComboPhysicsShapeType->add(getString("None"), LLSD(1)); - - BOOL isMesh = FALSE; - LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - if (sculpt_params) - { - U8 sculpt_type = sculpt_params->getSculptType(); - U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; - isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH); - } - - if(isMesh && objectp) - { - const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); - LLUUID mesh_id = volume_params.getSculptID(); - if(gMeshRepo.hasPhysicsShape(mesh_id)) - { - // if a mesh contains an uploaded or decomposed physics mesh, - // allow 'Prim' - mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); - } - } - else - { - // simple prims always allow physics shape prim - mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); - } - - mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2)); - mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType())); - mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced())); - - mObject = objectp; - mRootObject = root_objectp; + + //refresh any bakes + if (root_volobjp) + { + root_volobjp->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + if (gAgentAvatarp) + { + gAgentAvatarp->updateMeshVisibility(); + } + } + + // Flexible properties + BOOL is_flexible = volobjp && volobjp->isFlexible(); + getChild("Flexible1D Checkbox Ctrl")->setValue(is_flexible); + if (is_flexible || (volobjp && volobjp->canBeFlexible())) + { + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced()); + } + else + { + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); + } + if (is_flexible && editable && single_volume) + { + getChildView("FlexNumSections")->setVisible(true); + getChildView("FlexGravity")->setVisible(true); + getChildView("FlexTension")->setVisible(true); + getChildView("FlexFriction")->setVisible(true); + getChildView("FlexWind")->setVisible(true); + getChildView("FlexForceX")->setVisible(true); + getChildView("FlexForceY")->setVisible(true); + getChildView("FlexForceZ")->setVisible(true); + + getChildView("FlexNumSections")->setEnabled(true); + getChildView("FlexGravity")->setEnabled(true); + getChildView("FlexTension")->setEnabled(true); + getChildView("FlexFriction")->setEnabled(true); + getChildView("FlexWind")->setEnabled(true); + getChildView("FlexForceX")->setEnabled(true); + getChildView("FlexForceY")->setEnabled(true); + getChildView("FlexForceZ")->setEnabled(true); + + LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + + getChild("FlexNumSections")->setValue((F32)attributes->getSimulateLOD()); + getChild("FlexGravity")->setValue(attributes->getGravity()); + getChild("FlexTension")->setValue(attributes->getTension()); + getChild("FlexFriction")->setValue(attributes->getAirFriction()); + getChild("FlexWind")->setValue(attributes->getWindSensitivity()); + getChild("FlexForceX")->setValue(attributes->getUserForce().mV[VX]); + getChild("FlexForceY")->setValue(attributes->getUserForce().mV[VY]); + getChild("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]); + } + else + { + getChild("FlexNumSections", true)->clear(); + getChild("FlexGravity", true)->clear(); + getChild("FlexTension", true)->clear(); + getChild("FlexFriction", true)->clear(); + getChild("FlexWind", true)->clear(); + getChild("FlexForceX", true)->clear(); + getChild("FlexForceY", true)->clear(); + getChild("FlexForceZ", true)->clear(); + + getChildView("FlexNumSections")->setEnabled(false); + getChildView("FlexGravity")->setEnabled(false); + getChildView("FlexTension")->setEnabled(false); + getChildView("FlexFriction")->setEnabled(false); + getChildView("FlexWind")->setEnabled(false); + getChildView("FlexForceX")->setEnabled(false); + getChildView("FlexForceY")->setEnabled(false); + getChildView("FlexForceZ")->setEnabled(false); + } + + // Material properties + + // Update material part + // slightly inefficient - materials are unique per object, not per TE + U8 material_code = 0; + struct f : public LLSelectedTEGetFunctor + { + U8 get(LLViewerObject* object, S32 te) + { + return object->getMaterial(); + } + } func; + bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); + std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); + if (editable && single_volume && material_same) + { + mComboMaterial->setEnabled( TRUE ); + if (material_code == LL_MCODE_LIGHT) + { + if (mComboMaterial->getItemCount() == mComboMaterialItemCount) + { + mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); + } + mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); + } + else + { + if (mComboMaterial->getItemCount() != mComboMaterialItemCount) + { + mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); + } + + mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); + } + } + else + { + mComboMaterial->setEnabled( FALSE ); + } + + // Physics properties + + mSpinPhysicsGravity->set(objectp->getPhysicsGravity()); + mSpinPhysicsGravity->setEnabled(editable); + + mSpinPhysicsFriction->set(objectp->getPhysicsFriction()); + mSpinPhysicsFriction->setEnabled(editable); + + mSpinPhysicsDensity->set(objectp->getPhysicsDensity()); + mSpinPhysicsDensity->setEnabled(editable); + + mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution()); + mSpinPhysicsRestitution->setEnabled(editable); + + // update the physics shape combo to include allowed physics shapes + mComboPhysicsShapeType->removeall(); + mComboPhysicsShapeType->add(getString("None"), LLSD(1)); + + BOOL isMesh = FALSE; + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if (sculpt_params) + { + U8 sculpt_type = sculpt_params->getSculptType(); + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH); + } + + if(isMesh && objectp) + { + const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); + LLUUID mesh_id = volume_params.getSculptID(); + if(gMeshRepo.hasPhysicsShape(mesh_id)) + { + // if a mesh contains an uploaded or decomposed physics mesh, + // allow 'Prim' + mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); + } + } + else + { + // simple prims always allow physics shape prim + mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); + } + + mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2)); + mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType())); + mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced())); + + mObject = objectp; + mRootObject = root_objectp; mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume mMenuClipboardLight->setEnabled(editable && single_volume && volobjp); @@ -661,76 +661,76 @@ void LLPanelVolume::getState( ) // static bool LLPanelVolume::precommitValidate( const LLSD& data ) { - // TODO: Richard will fill this in later. - return TRUE; // FALSE means that validation failed and new value should not be commited. + // TODO: Richard will fill this in later. + return TRUE; // FALSE means that validation failed and new value should not be commited. } void LLPanelVolume::refresh() { - getState(); - if (mObject.notNull() && mObject->isDead()) - { - mObject = NULL; - } - - if (mRootObject.notNull() && mRootObject->isDead()) - { - mRootObject = NULL; - } - - bool enable_mesh = false; - - LLSD sim_features; - LLViewerRegion *region = gAgent.getRegion(); - if(region) - { - LLSD sim_features; - region->getSimulatorFeatures(sim_features); - enable_mesh = sim_features.has("PhysicsShapeTypes"); - } - getChildView("label physicsshapetype")->setVisible(enable_mesh); - getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); - getChildView("Physics Gravity")->setVisible(enable_mesh); - getChildView("Physics Friction")->setVisible(enable_mesh); - getChildView("Physics Density")->setVisible(enable_mesh); - getChildView("Physics Restitution")->setVisible(enable_mesh); - + getState(); + if (mObject.notNull() && mObject->isDead()) + { + mObject = NULL; + } + + if (mRootObject.notNull() && mRootObject->isDead()) + { + mRootObject = NULL; + } + + bool enable_mesh = false; + + LLSD sim_features; + LLViewerRegion *region = gAgent.getRegion(); + if(region) + { + LLSD sim_features; + region->getSimulatorFeatures(sim_features); + enable_mesh = sim_features.has("PhysicsShapeTypes"); + } + getChildView("label physicsshapetype")->setVisible(enable_mesh); + getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); + getChildView("Physics Gravity")->setVisible(enable_mesh); + getChildView("Physics Friction")->setVisible(enable_mesh); + getChildView("Physics Density")->setVisible(enable_mesh); + getChildView("Physics Restitution")->setVisible(enable_mesh); + /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */ } void LLPanelVolume::draw() { - LLPanel::draw(); + LLPanel::draw(); } // virtual void LLPanelVolume::clearCtrls() { - LLPanel::clearCtrls(); - - getChildView("select_single")->setEnabled(false); - getChildView("select_single")->setVisible(true); - getChildView("edit_object")->setEnabled(false); - getChildView("edit_object")->setVisible(false); - getChildView("Light Checkbox Ctrl")->setEnabled(false);; - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch) - { - LightColorSwatch->setEnabled( FALSE ); - LightColorSwatch->setValid( FALSE ); - } - LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); - if(LightTextureCtrl) - { - LightTextureCtrl->setEnabled( FALSE ); - LightTextureCtrl->setValid( FALSE ); - } - - getChildView("Light Intensity")->setEnabled(false); - getChildView("Light Radius")->setEnabled(false); - getChildView("Light Falloff")->setEnabled(false); + LLPanel::clearCtrls(); + + getChildView("select_single")->setEnabled(false); + getChildView("select_single")->setVisible(true); + getChildView("edit_object")->setEnabled(false); + getChildView("edit_object")->setVisible(false); + getChildView("Light Checkbox Ctrl")->setEnabled(false);; + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch) + { + LightColorSwatch->setEnabled( FALSE ); + LightColorSwatch->setValid( FALSE ); + } + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if(LightTextureCtrl) + { + LightTextureCtrl->setEnabled( FALSE ); + LightTextureCtrl->setValid( FALSE ); + } + + getChildView("Light Intensity")->setEnabled(false); + getChildView("Light Radius")->setEnabled(false); + getChildView("Light Falloff")->setEnabled(false); getChildView("Reflection Probe")->setEnabled(false);; getChildView("Probe Volume Type")->setEnabled(false); @@ -738,22 +738,22 @@ void LLPanelVolume::clearCtrls() getChildView("Probe Ambiance")->setEnabled(false); getChildView("Probe Near Clip")->setEnabled(false); getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false); - getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); - getChildView("FlexNumSections")->setEnabled(false); - getChildView("FlexGravity")->setEnabled(false); - getChildView("FlexTension")->setEnabled(false); - getChildView("FlexFriction")->setEnabled(false); - getChildView("FlexWind")->setEnabled(false); - getChildView("FlexForceX")->setEnabled(false); - getChildView("FlexForceY")->setEnabled(false); - getChildView("FlexForceZ")->setEnabled(false); - - mSpinPhysicsGravity->setEnabled(FALSE); - mSpinPhysicsFriction->setEnabled(FALSE); - mSpinPhysicsDensity->setEnabled(FALSE); - mSpinPhysicsRestitution->setEnabled(FALSE); - - mComboMaterial->setEnabled( FALSE ); + getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); + getChildView("FlexNumSections")->setEnabled(false); + getChildView("FlexGravity")->setEnabled(false); + getChildView("FlexTension")->setEnabled(false); + getChildView("FlexFriction")->setEnabled(false); + getChildView("FlexWind")->setEnabled(false); + getChildView("FlexForceX")->setEnabled(false); + getChildView("FlexForceY")->setEnabled(false); + getChildView("FlexForceZ")->setEnabled(false); + + mSpinPhysicsGravity->setEnabled(FALSE); + mSpinPhysicsFriction->setEnabled(FALSE); + mSpinPhysicsDensity->setEnabled(FALSE); + mSpinPhysicsRestitution->setEnabled(FALSE); + + mComboMaterial->setEnabled( FALSE ); } // @@ -762,16 +762,16 @@ void LLPanelVolume::clearCtrls() void LLPanelVolume::sendIsLight() { - LLViewerObject* objectp = mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - BOOL value = getChild("Light Checkbox Ctrl")->getValue(); - volobjp->setIsLight(value); - LL_INFOS() << "update light sent" << LL_ENDL; + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + BOOL value = getChild("Light Checkbox Ctrl")->getValue(); + volobjp->setIsLight(value); + LL_INFOS() << "update light sent" << LL_ENDL; } void notify_cant_select_reflection_probe() @@ -857,97 +857,97 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS void LLPanelVolume::sendIsFlexible() { - LLViewerObject* objectp = mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - BOOL is_flexible = getChild("Flexible1D Checkbox Ctrl")->getValue(); - //BOOL is_flexible = mCheckFlexible1D->get(); - - if (is_flexible) - { - //LLFirstUse::useFlexible(); - - if (objectp->getClickAction() == CLICK_ACTION_SIT) - { - LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE); - } - - } - - if (volobjp->setIsFlexible(is_flexible)) - { - mObject->sendShapeUpdate(); - LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); - } - - LL_INFOS() << "update flexible sent" << LL_ENDL; + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + BOOL is_flexible = getChild("Flexible1D Checkbox Ctrl")->getValue(); + //BOOL is_flexible = mCheckFlexible1D->get(); + + if (is_flexible) + { + //LLFirstUse::useFlexible(); + + if (objectp->getClickAction() == CLICK_ACTION_SIT) + { + LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE); + } + + } + + if (volobjp->setIsFlexible(is_flexible)) + { + mObject->sendShapeUpdate(); + LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); + } + + LL_INFOS() << "update flexible sent" << LL_ENDL; } void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) { - U8 type = ctrl->getValue().asInteger(); - LLSelectMgr::getInstance()->selectionSetPhysicsType(type); + U8 type = ctrl->getValue().asInteger(); + LLSelectMgr::getInstance()->selectionSetPhysicsType(type); - refreshCost(); + refreshCost(); } void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata) { - F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstance()->selectionSetGravity(val); + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetGravity(val); } void LLPanelVolume::sendPhysicsFriction(LLUICtrl* ctrl, void* userdata) { - F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstance()->selectionSetFriction(val); + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetFriction(val); } void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata) { - F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstance()->selectionSetRestitution(val); + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetRestitution(val); } void LLPanelVolume::sendPhysicsDensity(LLUICtrl* ctrl, void* userdata) { - F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstance()->selectionSetDensity(val); + F32 val = ctrl->getValue().asReal(); + LLSelectMgr::getInstance()->selectionSetDensity(val); } void LLPanelVolume::refreshCost() { - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - - if (obj) - { - obj->getObjectCost(); - } + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + + if (obj) + { + obj->getObjectCost(); + } } void LLPanelVolume::onLightCancelColor(const LLSD& data) { - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch) - { - LightColorSwatch->setColor(mLightSavedColor); - } - onLightSelectColor(data); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch) + { + LightColorSwatch->setColor(mLightSavedColor); + } + onLightSelectColor(data); } void LLPanelVolume::onLightCancelTexture(const LLSD& data) { - LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); - LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); - if (volobjp && LightTextureCtrl) - { - // Cancel the light texture as requested - // NORSPEC-292 + if (volobjp && LightTextureCtrl) + { + // Cancel the light texture as requested + // NORSPEC-292 // // Texture picker triggers cancel both in case of actual cancel and in case of // selection of "None" texture. @@ -962,44 +962,44 @@ void LLPanelVolume::onLightCancelTexture(const LLSD& data) getChild("Light Focus")->setValue(spot_params.mV[1]); getChild("Light Ambiance")->setValue(spot_params.mV[2]); } - } + } } void LLPanelVolume::onLightSelectColor(const LLSD& data) { - LLViewerObject* objectp = mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - - LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); - if(LightColorSwatch) - { - LLColor4 clr = LightColorSwatch->get(); - LLColor3 clr3( clr ); - volobjp->setLightSRGBColor(clr3); - mLightSavedColor = clr; - } + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); + if(LightColorSwatch) + { + LLColor4 clr = LightColorSwatch->get(); + LLColor3 clr3( clr ); + volobjp->setLightSRGBColor(clr3); + mLightSavedColor = clr; + } } void LLPanelVolume::onLightSelectTexture(const LLSD& data) { - if (mObject.isNull() || (mObject->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); - - - LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); - if(LightTextureCtrl) - { - LLUUID id = LightTextureCtrl->getImageAssetID(); - setLightTextureID(id, LightTextureCtrl->getImageItemID(), volobjp); - } + if (mObject.isNull() || (mObject->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); + + + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + setLightTextureID(id, LightTextureCtrl->getImageItemID(), volobjp); + } } void LLPanelVolume::onCopyFeatures() @@ -1323,100 +1323,100 @@ bool LLPanelVolume::menuEnableItem(const LLSD& userdata) // static void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) { - LLPanelVolume* self = (LLPanelVolume*)userdata; - LLComboBox* box = (LLComboBox*) ctrl; - - if (box) - { - // apply the currently selected material to the object - const std::string& material_name = box->getSimple(); - std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); - if (material_name != LEGACY_FULLBRIGHT_DESC) - { - U8 material_code = LLMaterialTable::basic.getMCode(material_name); - if (self) - { - LLViewerObject* objectp = self->mObject; - if (objectp) - { - objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER); - objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code)); - //currently density is always set to 1000 serverside regardless of chosen material, - //actual material density should be used here, if this behavior change - objectp->setPhysicsDensity(DEFAULT_DENSITY); - objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code)); - } - } - LLSelectMgr::getInstance()->selectionSetMaterial(material_code); - } - } + LLPanelVolume* self = (LLPanelVolume*)userdata; + LLComboBox* box = (LLComboBox*) ctrl; + + if (box) + { + // apply the currently selected material to the object + const std::string& material_name = box->getSimple(); + std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); + if (material_name != LEGACY_FULLBRIGHT_DESC) + { + U8 material_code = LLMaterialTable::basic.getMCode(material_name); + if (self) + { + LLViewerObject* objectp = self->mObject; + if (objectp) + { + objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER); + objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code)); + //currently density is always set to 1000 serverside regardless of chosen material, + //actual material density should be used here, if this behavior change + objectp->setPhysicsDensity(DEFAULT_DENSITY); + objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code)); + } + } + LLSelectMgr::getInstance()->selectionSetMaterial(material_code); + } + } } // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { - LLPanelVolume* self = (LLPanelVolume*) userdata; - LLViewerObject* objectp = self->mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - - volobjp->setLightIntensity((F32)self->getChild("Light Intensity")->getValue().asReal()); - volobjp->setLightRadius((F32)self->getChild("Light Radius")->getValue().asReal()); - volobjp->setLightFalloff((F32)self->getChild("Light Falloff")->getValue().asReal()); - - LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); - if(LightColorSwatch) - { - LLColor4 clr = LightColorSwatch->get(); - volobjp->setLightSRGBColor(LLColor3(clr)); - } - - LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); - if(LightTextureCtrl) - { - LLUUID id = LightTextureCtrl->getImageAssetID(); + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLViewerObject* objectp = self->mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + + volobjp->setLightIntensity((F32)self->getChild("Light Intensity")->getValue().asReal()); + volobjp->setLightRadius((F32)self->getChild("Light Radius")->getValue().asReal()); + volobjp->setLightFalloff((F32)self->getChild("Light Falloff")->getValue().asReal()); + + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); + if(LightColorSwatch) + { + LLColor4 clr = LightColorSwatch->get(); + volobjp->setLightSRGBColor(LLColor3(clr)); + } + + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); LLUUID item_id = LightTextureCtrl->getImageItemID(); - if (id.notNull()) - { - if (!volobjp->isLightSpotlight()) - { //this commit is making this a spot light, set UI to default params + if (id.notNull()) + { + if (!volobjp->isLightSpotlight()) + { //this commit is making this a spot light, set UI to default params setLightTextureID(id, item_id, volobjp); - LLVector3 spot_params = volobjp->getSpotLightParams(); - self->getChild("Light FOV")->setValue(spot_params.mV[0]); - self->getChild("Light Focus")->setValue(spot_params.mV[1]); - self->getChild("Light Ambiance")->setValue(spot_params.mV[2]); - } - else - { //modifying existing params, this time volobjp won't change params on its own. + LLVector3 spot_params = volobjp->getSpotLightParams(); + self->getChild("Light FOV")->setValue(spot_params.mV[0]); + self->getChild("Light Focus")->setValue(spot_params.mV[1]); + self->getChild("Light Ambiance")->setValue(spot_params.mV[2]); + } + else + { //modifying existing params, this time volobjp won't change params on its own. if (volobjp->getLightTextureID() != id) { setLightTextureID(id, item_id, volobjp); } - LLVector3 spot_params; - spot_params.mV[0] = (F32) self->getChild("Light FOV")->getValue().asReal(); - spot_params.mV[1] = (F32) self->getChild("Light Focus")->getValue().asReal(); - spot_params.mV[2] = (F32) self->getChild("Light Ambiance")->getValue().asReal(); - volobjp->setSpotLightParams(spot_params); - } - } - else if (volobjp->isLightSpotlight()) - { //no longer a spot light - setLightTextureID(id, item_id, volobjp); - //self->getChildView("Light FOV")->setEnabled(FALSE); - //self->getChildView("Light Focus")->setEnabled(FALSE); - //self->getChildView("Light Ambiance")->setEnabled(FALSE); - } - } - - + LLVector3 spot_params; + spot_params.mV[0] = (F32) self->getChild("Light FOV")->getValue().asReal(); + spot_params.mV[1] = (F32) self->getChild("Light Focus")->getValue().asReal(); + spot_params.mV[2] = (F32) self->getChild("Light Ambiance")->getValue().asReal(); + volobjp->setSpotLightParams(spot_params); + } + } + else if (volobjp->isLightSpotlight()) + { //no longer a spot light + setLightTextureID(id, item_id, volobjp); + //self->getChildView("Light FOV")->setEnabled(FALSE); + //self->getChildView("Light Focus")->setEnabled(FALSE); + //self->getChildView("Light Ambiance")->setEnabled(FALSE); + } + } + + } -//static +//static void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*)userdata; @@ -1432,9 +1432,9 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) std::string update_type = self->getChild("Probe Update Type")->getValue().asString(); - bool is_mirror = update_type.find("Mirror") != std::string::npos; + bool is_mirror = update_type.find("Mirror") != std::string::npos; - volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos); + volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos); volobjp->setReflectionProbeIsMirror(is_mirror); self->getChildView("Probe Ambiance")->setEnabled(!is_mirror); @@ -1469,7 +1469,7 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) profile = LL_PCODE_PROFILE_SQUARE; path = LL_PCODE_PATH_LINE; } - + LLVolumeParams params; params.getProfileParams().setCurveType(profile); params.getPathParams().setCurveType(path); @@ -1481,8 +1481,8 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) // static void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata ) { - LLPanelVolume* self = (LLPanelVolume*) userdata; - self->sendIsLight(); + LLPanelVolume* self = (LLPanelVolume*) userdata; + self->sendIsLight(); } // static @@ -1507,7 +1507,7 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) { LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); - } + } volobjp->setLightTextureID(asset_id); } } @@ -1525,47 +1525,47 @@ void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata) // static void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata ) { - LLPanelVolume* self = (LLPanelVolume*) userdata; - LLViewerObject* objectp = self->mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - - LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - if (attributes) - { - LLFlexibleObjectData new_attributes; - new_attributes = *attributes; - - - new_attributes.setSimulateLOD(self->getChild("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get()); - new_attributes.setGravity((F32)self->getChild("FlexGravity")->getValue().asReal()); - new_attributes.setTension((F32)self->getChild("FlexTension")->getValue().asReal()); - new_attributes.setAirFriction((F32)self->getChild("FlexFriction")->getValue().asReal()); - new_attributes.setWindSensitivity((F32)self->getChild("FlexWind")->getValue().asReal()); - F32 fx = (F32)self->getChild("FlexForceX")->getValue().asReal(); - F32 fy = (F32)self->getChild("FlexForceY")->getValue().asReal(); - F32 fz = (F32)self->getChild("FlexForceZ")->getValue().asReal(); - LLVector3 force(fx,fy,fz); - - new_attributes.setUserForce(force); - objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); - } - - // Values may fail validation - self->refresh(); + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLViewerObject* objectp = self->mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + + LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + if (attributes) + { + LLFlexibleObjectData new_attributes; + new_attributes = *attributes; + + + new_attributes.setSimulateLOD(self->getChild("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get()); + new_attributes.setGravity((F32)self->getChild("FlexGravity")->getValue().asReal()); + new_attributes.setTension((F32)self->getChild("FlexTension")->getValue().asReal()); + new_attributes.setAirFriction((F32)self->getChild("FlexFriction")->getValue().asReal()); + new_attributes.setWindSensitivity((F32)self->getChild("FlexWind")->getValue().asReal()); + F32 fx = (F32)self->getChild("FlexForceX")->getValue().asReal(); + F32 fy = (F32)self->getChild("FlexForceY")->getValue().asReal(); + F32 fz = (F32)self->getChild("FlexForceZ")->getValue().asReal(); + LLVector3 force(fx,fy,fz); + + new_attributes.setUserForce(force); + objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); + } + + // Values may fail validation + self->refresh(); } void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*) { - LLViewerObject* objectp = mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - BOOL animated_mesh = getChild("Animated Mesh Checkbox Ctrl")->getValue(); + LLVOVolume *volobjp = (LLVOVolume *)objectp; + BOOL animated_mesh = getChild("Animated Mesh Checkbox Ctrl")->getValue(); U32 flags = volobjp->getExtendedMeshFlags(); U32 new_flags = flags; if (animated_mesh) @@ -1581,49 +1581,49 @@ void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*) volobjp->setExtendedMeshFlags(new_flags); } - //refresh any bakes - if (volobjp) - { - volobjp->refreshBakeTexture(); - - LLViewerObject::const_child_list_t& child_list = volobjp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* objectp = *iter; - if (objectp) - { - objectp->refreshBakeTexture(); - } - } - - if (gAgentAvatarp) - { - gAgentAvatarp->updateMeshVisibility(); - } - } + //refresh any bakes + if (volobjp) + { + volobjp->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = volobjp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + if (gAgentAvatarp) + { + gAgentAvatarp->updateMeshVisibility(); + } + } } void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*) { - if (mObject->flagObjectPermanent()) - { - LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2)); - } - else - { - sendIsFlexible(); - } + if (mObject->flagObjectPermanent()) + { + LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2)); + } + else + { + sendIsFlexible(); + } } void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse) { - if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) - { - sendIsFlexible(); - } - else - { - getChild("Flexible1D Checkbox Ctrl")->setValue(FALSE); - } + if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) + { + sendIsFlexible(); + } + else + { + getChild("Flexible1D Checkbox Ctrl")->setValue(FALSE); + } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 20b00974e1..f602dee0cb 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llselectmgr.cpp * @brief A manager for selected objects and faces. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -120,13 +120,13 @@ const S32 MAX_CHILDREN_PER_TASK = 255; BOOL LLSelectMgr::sRectSelectInclusive = TRUE; BOOL LLSelectMgr::sRenderHiddenSelections = TRUE; BOOL LLSelectMgr::sRenderLightRadius = FALSE; -F32 LLSelectMgr::sHighlightThickness = 0.f; -F32 LLSelectMgr::sHighlightUScale = 0.f; -F32 LLSelectMgr::sHighlightVScale = 0.f; -F32 LLSelectMgr::sHighlightAlpha = 0.f; -F32 LLSelectMgr::sHighlightAlphaTest = 0.f; -F32 LLSelectMgr::sHighlightUAnim = 0.f; -F32 LLSelectMgr::sHighlightVAnim = 0.f; +F32 LLSelectMgr::sHighlightThickness = 0.f; +F32 LLSelectMgr::sHighlightUScale = 0.f; +F32 LLSelectMgr::sHighlightVScale = 0.f; +F32 LLSelectMgr::sHighlightAlpha = 0.f; +F32 LLSelectMgr::sHighlightAlphaTest = 0.f; +F32 LLSelectMgr::sHighlightUAnim = 0.f; +F32 LLSelectMgr::sHighlightVAnim = 0.f; LLColor4 LLSelectMgr::sSilhouetteParentColor; LLColor4 LLSelectMgr::sSilhouetteChildColor; LLColor4 LLSelectMgr::sHighlightInspectColor; @@ -137,15 +137,15 @@ LLColor4 LLSelectMgr::sContextSilhouetteColor; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // struct LLDeRezInfo // -// Used to keep track of important derez info. +// Used to keep track of important derez info. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ struct LLDeRezInfo { - EDeRezDestination mDestination; - LLUUID mDestinationID; - LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) : - mDestination(dest), mDestinationID(dest_id) {} + EDeRezDestination mDestination; + LLUUID mDestinationID; + LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) : + mDestination(dest), mDestinationID(dest_id) {} }; // @@ -206,7 +206,7 @@ LLSelectionCallbackData::LLSelectionCallbackData() void LLSelectMgr::cleanupGlobals() { - LLSelectMgr::getInstance()->clearSelections(); + LLSelectMgr::getInstance()->clearSelections(); } //----------------------------------------------------------------------------- @@ -218,38 +218,38 @@ LLSelectMgr::LLSelectMgr() mAllowSelectAvatar( LLCachedControl(gSavedSettings, "AllowSelectAvatar", FALSE)), mDebugSelectMgr(LLCachedControl(gSavedSettings, "DebugSelectMgr", FALSE)) { - mTEMode = FALSE; - mTextureChannel = LLRender::DIFFUSE_MAP; - mLastCameraPos.clearVec(); + mTEMode = FALSE; + mTextureChannel = LLRender::DIFFUSE_MAP; + mLastCameraPos.clearVec(); - sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness"); - sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale"); - sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale"); - sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha") * 2; - sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest"); - sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim"); - sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim"); + sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness"); + sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale"); + sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale"); + sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha") * 2; + sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest"); + sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim"); + sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim"); - sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor"); - sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor"); - sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor"); - sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor"); - sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor"); - sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f; + sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor"); + sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor"); + sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor"); + sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor"); + sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor"); + sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f; - sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); - - mRenderSilhouettes = TRUE; + sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); - mGridMode = GRID_MODE_WORLD; - gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD); + mRenderSilhouettes = TRUE; - mSelectedObjects = new LLObjectSelection(); - mHoverObjects = new LLObjectSelection(); - mHighlightedObjects = new LLObjectSelection(); + mGridMode = GRID_MODE_WORLD; + gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD); - mForceSelection = FALSE; - mShowSelection = FALSE; + mSelectedObjects = new LLObjectSelection(); + mHoverObjects = new LLObjectSelection(); + mHighlightedObjects = new LLObjectSelection(); + + mForceSelection = FALSE; + mShowSelection = FALSE; } @@ -258,47 +258,47 @@ LLSelectMgr::LLSelectMgr() //----------------------------------------------------------------------------- LLSelectMgr::~LLSelectMgr() { - clearSelections(); + clearSelections(); } void LLSelectMgr::clearSelections() { - mHoverObjects->deleteAllNodes(); - mSelectedObjects->deleteAllNodes(); - mHighlightedObjects->deleteAllNodes(); - mRectSelectedObjects.clear(); - mGridObjects.deleteAllNodes(); + mHoverObjects->deleteAllNodes(); + mSelectedObjects->deleteAllNodes(); + mHighlightedObjects->deleteAllNodes(); + mRectSelectedObjects.clear(); + mGridObjects.deleteAllNodes(); - LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP); + LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP); } void LLSelectMgr::update() { - mSelectedObjects->cleanupNodes(); + mSelectedObjects->cleanupNodes(); } void LLSelectMgr::updateEffects() { - //keep reference grid objects active - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - LLDrawable* drawable = object->mDrawable; - if (drawable) - { - gPipeline.markMoved(drawable); - } - return true; - } - } func; - mGridObjects.applyToObjects(&func); - - if (mEffectsTimer.getElapsedTimeF32() > 1.f) - { - mSelectedObjects->updateEffects(); - mEffectsTimer.reset(); - } + //keep reference grid objects active + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + gPipeline.markMoved(drawable); + } + return true; + } + } func; + mGridObjects.applyToObjects(&func); + + if (mEffectsTimer.getElapsedTimeF32() > 1.f) + { + mSelectedObjects->updateEffects(); + mEffectsTimer.reset(); + } } void LLSelectMgr::resetObjectOverrides() @@ -339,31 +339,31 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle) void LLSelectMgr::overrideObjectUpdates() { - //override any position updates from simulator on objects being edited - struct f : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* selectNode) - { - LLViewerObject* object = selectNode->getObject(); - if (object && object->permMove() && !object->isPermanentEnforced()) - { - if (!selectNode->mLastPositionLocal.isExactlyZero()) - { - object->setPosition(selectNode->mLastPositionLocal); - } - if (selectNode->mLastRotation != LLQuaternion()) - { - object->setRotation(selectNode->mLastRotation); - } - if (!selectNode->mLastScale.isExactlyZero()) - { - object->setScale(selectNode->mLastScale); - } - } - return true; - } - } func; - getSelection()->applyToNodes(&func); + //override any position updates from simulator on objects being edited + struct f : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* selectNode) + { + LLViewerObject* object = selectNode->getObject(); + if (object && object->permMove() && !object->isPermanentEnforced()) + { + if (!selectNode->mLastPositionLocal.isExactlyZero()) + { + object->setPosition(selectNode->mLastPositionLocal); + } + if (selectNode->mLastRotation != LLQuaternion()) + { + object->setRotation(selectNode->mLastRotation); + } + if (!selectNode->mLastScale.isExactlyZero()) + { + object->setScale(selectNode->mLastScale); + } + } + return true; + } + } func; + getSelection()->applyToNodes(&func); } void LLSelectMgr::resetAvatarOverrides() @@ -397,7 +397,7 @@ void LLSelectMgr::overrideAvatarUpdates() } // remove selected avatars from this list, - // but set object overrides to make sure avatar won't snap back + // but set object overrides to make sure avatar won't snap back struct f : public LLSelectedNodeFunctor { f(LLSelectMgr* p) : mManager(p) {} @@ -458,62 +458,62 @@ void LLSelectMgr::overrideAvatarUpdates() //----------------------------------------------------------------------------- LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face, S32 gltf_node, S32 gltf_primitive) { - llassert( object ); - - //remember primary object - mSelectedObjects->mPrimaryObject = object; - - // Don't add an object that is already in the list - if (object->isSelected() ) { - // make sure point at position is updated - updatePointAt(); - gEditMenuHandler = this; - return NULL; - } - - if (!canSelectObject(object)) - { - //make_ui_sound("UISndInvalidOp"); - return NULL; - } - - // LL_INFOS() << "Adding object to selected object list" << LL_ENDL; - - // Place it in the list and tag it. - // This will refresh dialogs. - addAsIndividual(object, face, TRUE, gltf_node, gltf_primitive); - - // Stop the object from moving (this anticipates changes on the - // simulator in LLTask::userSelect) - // *FIX: shouldn't zero out these either - object->setVelocity(LLVector3::zero); - object->setAcceleration(LLVector3::zero); - //object->setAngularVelocity(LLVector3::zero); - object->resetRot(); - - // Always send to simulator, so you get a copy of the - // permissions structure back. - gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); - LLViewerRegion* regionp = object->getRegion(); - gMessageSystem->sendReliable( regionp->getHost()); - - updatePointAt(); - updateSelectionCenter(); - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - - // have selection manager handle edit menu immediately after - // user selects an object - if (mSelectedObjects->getObjectCount()) - { - gEditMenuHandler = this; - } - - return mSelectedObjects; + llassert( object ); + + //remember primary object + mSelectedObjects->mPrimaryObject = object; + + // Don't add an object that is already in the list + if (object->isSelected() ) { + // make sure point at position is updated + updatePointAt(); + gEditMenuHandler = this; + return NULL; + } + + if (!canSelectObject(object)) + { + //make_ui_sound("UISndInvalidOp"); + return NULL; + } + + // LL_INFOS() << "Adding object to selected object list" << LL_ENDL; + + // Place it in the list and tag it. + // This will refresh dialogs. + addAsIndividual(object, face, TRUE, gltf_node, gltf_primitive); + + // Stop the object from moving (this anticipates changes on the + // simulator in LLTask::userSelect) + // *FIX: shouldn't zero out these either + object->setVelocity(LLVector3::zero); + object->setAcceleration(LLVector3::zero); + //object->setAngularVelocity(LLVector3::zero); + object->resetRot(); + + // Always send to simulator, so you get a copy of the + // permissions structure back. + gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); + LLViewerRegion* regionp = object->getRegion(); + gMessageSystem->sendReliable( regionp->getHost()); + + updatePointAt(); + updateSelectionCenter(); + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + + // have selection manager handle edit menu immediately after + // user selects an object + if (mSelectedObjects->getObjectCount()) + { + gEditMenuHandler = this; + } + + return mSelectedObjects; } //----------------------------------------------------------------------------- @@ -521,149 +521,149 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S3 //----------------------------------------------------------------------------- LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, BOOL add_to_end, BOOL ignore_select_owned) { - llassert( obj ); - - //remember primary object - mSelectedObjects->mPrimaryObject = obj; - - // This may be incorrect if things weren't family selected before... - djs 07/08/02 - // Don't add an object that is already in the list - if (obj->isSelected() ) - { - // make sure pointat position is updated - updatePointAt(); - gEditMenuHandler = this; - return NULL; - } - - if (!canSelectObject(obj,ignore_select_owned)) - { - //make_ui_sound("UISndInvalidOp"); - return NULL; - } - - // Since we're selecting a family, start at the root, but - // don't include an avatar. - LLViewerObject* root = obj; - - while(!root->isAvatar() && root->getParent()) - { - LLViewerObject* parent = (LLViewerObject*)root->getParent(); - if (parent->isAvatar()) - { - break; - } - root = parent; - } - - // Collect all of the objects - std::vector objects; - - root->addThisAndNonJointChildren(objects); - addAsFamily(objects, add_to_end); - - updateSelectionCenter(); - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - updatePointAt(); - - dialog_refresh_all(); - - // Always send to simulator, so you get a copy of the permissions - // structure back. - sendSelect(); - - // Stop the object from moving (this anticipates changes on the - // simulator in LLTask::userSelect) - root->setVelocity(LLVector3::zero); - root->setAcceleration(LLVector3::zero); - //root->setAngularVelocity(LLVector3::zero); - root->resetRot(); - - // leave component mode - if (gSavedSettings.getBOOL("EditLinkedParts")) - { - gSavedSettings.setBOOL("EditLinkedParts", FALSE); - promoteSelectionToRoot(); - } - - // have selection manager handle edit menu immediately after - // user selects an object - if (mSelectedObjects->getObjectCount()) - { - gEditMenuHandler = this; - } - - return mSelectedObjects; + llassert( obj ); + + //remember primary object + mSelectedObjects->mPrimaryObject = obj; + + // This may be incorrect if things weren't family selected before... - djs 07/08/02 + // Don't add an object that is already in the list + if (obj->isSelected() ) + { + // make sure pointat position is updated + updatePointAt(); + gEditMenuHandler = this; + return NULL; + } + + if (!canSelectObject(obj,ignore_select_owned)) + { + //make_ui_sound("UISndInvalidOp"); + return NULL; + } + + // Since we're selecting a family, start at the root, but + // don't include an avatar. + LLViewerObject* root = obj; + + while(!root->isAvatar() && root->getParent()) + { + LLViewerObject* parent = (LLViewerObject*)root->getParent(); + if (parent->isAvatar()) + { + break; + } + root = parent; + } + + // Collect all of the objects + std::vector objects; + + root->addThisAndNonJointChildren(objects); + addAsFamily(objects, add_to_end); + + updateSelectionCenter(); + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + updatePointAt(); + + dialog_refresh_all(); + + // Always send to simulator, so you get a copy of the permissions + // structure back. + sendSelect(); + + // Stop the object from moving (this anticipates changes on the + // simulator in LLTask::userSelect) + root->setVelocity(LLVector3::zero); + root->setAcceleration(LLVector3::zero); + //root->setAngularVelocity(LLVector3::zero); + root->resetRot(); + + // leave component mode + if (gSavedSettings.getBOOL("EditLinkedParts")) + { + gSavedSettings.setBOOL("EditLinkedParts", FALSE); + promoteSelectionToRoot(); + } + + // have selection manager handle edit menu immediately after + // user selects an object + if (mSelectedObjects->getObjectCount()) + { + gEditMenuHandler = this; + } + + return mSelectedObjects; } //----------------------------------------------------------------------------- // Select the object, parents and children. //----------------------------------------------------------------------------- LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector& object_list, - BOOL send_to_sim) -{ - // Collect all of the objects, children included - std::vector objects; - - //clear primary object (no primary object) - mSelectedObjects->mPrimaryObject = NULL; - - if (object_list.size() < 1) - { - return NULL; - } - - // NOTE -- we add the objects in REVERSE ORDER - // to preserve the order in the mSelectedObjects list - for (std::vector::const_reverse_iterator riter = object_list.rbegin(); - riter != object_list.rend(); ++riter) - { - LLViewerObject *object = *riter; - - llassert( object ); - - if (!canSelectObject(object)) continue; - - object->addThisAndNonJointChildren(objects); - addAsFamily(objects); - - // Stop the object from moving (this anticipates changes on the - // simulator in LLTask::userSelect) - object->setVelocity(LLVector3::zero); - object->setAcceleration(LLVector3::zero); - //object->setAngularVelocity(LLVector3::zero); - object->resetRot(); - } - - updateSelectionCenter(); - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - updatePointAt(); - dialog_refresh_all(); - - // Almost always send to simulator, so you get a copy of the permissions - // structure back. - // JC: The one case where you don't want to do this is if you're selecting - // all the objects on a sim. - if (send_to_sim) - { - sendSelect(); - } - - // leave component mode - if (gSavedSettings.getBOOL("EditLinkedParts")) - { - gSavedSettings.setBOOL("EditLinkedParts", FALSE); - promoteSelectionToRoot(); - } - - // have selection manager handle edit menu immediately after - // user selects an object - if (mSelectedObjects->getObjectCount()) - { - gEditMenuHandler = this; - } - - return mSelectedObjects; + BOOL send_to_sim) +{ + // Collect all of the objects, children included + std::vector objects; + + //clear primary object (no primary object) + mSelectedObjects->mPrimaryObject = NULL; + + if (object_list.size() < 1) + { + return NULL; + } + + // NOTE -- we add the objects in REVERSE ORDER + // to preserve the order in the mSelectedObjects list + for (std::vector::const_reverse_iterator riter = object_list.rbegin(); + riter != object_list.rend(); ++riter) + { + LLViewerObject *object = *riter; + + llassert( object ); + + if (!canSelectObject(object)) continue; + + object->addThisAndNonJointChildren(objects); + addAsFamily(objects); + + // Stop the object from moving (this anticipates changes on the + // simulator in LLTask::userSelect) + object->setVelocity(LLVector3::zero); + object->setAcceleration(LLVector3::zero); + //object->setAngularVelocity(LLVector3::zero); + object->resetRot(); + } + + updateSelectionCenter(); + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + updatePointAt(); + dialog_refresh_all(); + + // Almost always send to simulator, so you get a copy of the permissions + // structure back. + // JC: The one case where you don't want to do this is if you're selecting + // all the objects on a sim. + if (send_to_sim) + { + sendSelect(); + } + + // leave component mode + if (gSavedSettings.getBOOL("EditLinkedParts")) + { + gSavedSettings.setBOOL("EditLinkedParts", FALSE); + promoteSelectionToRoot(); + } + + // have selection manager handle edit menu immediately after + // user selects an object + if (mSelectedObjects->getObjectCount()) + { + gEditMenuHandler = this; + } + + return mSelectedObjects; } // Use for when the simulator kills an object. This version also @@ -672,138 +672,138 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vectorgetCurrentTool(); - - // It's possible that the tool is editing an object that is not selected - LLViewerObject* tool_editing_object = tool->getEditingObject(); - if( tool_editing_object && tool_editing_object->mID == id) - { - tool->stopEditing(); - object_found = TRUE; - } - - // Iterate through selected objects list and kill the object - if( !object_found ) - { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); ) - { - LLObjectSelection::iterator curiter = iter++; - LLViewerObject* object = (*curiter)->getObject(); - if (object->mID == id) - { - if (tool) - { - tool->stopEditing(); - } - - // lose the selection, don't tell simulator, it knows - deselectObjectAndFamily(object, FALSE); - object_found = TRUE; - break; // must break here, may have removed multiple objects from list - } - else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id) - { - // It's possible the item being removed has an avatar sitting on it - // So remove the avatar that is sitting on the object. - deselectObjectAndFamily(object, FALSE); - break; // must break here, may have removed multiple objects from list - } - } - } - - return object_found; + BOOL object_found = FALSE; + LLTool *tool = NULL; + + tool = LLToolMgr::getInstance()->getCurrentTool(); + + // It's possible that the tool is editing an object that is not selected + LLViewerObject* tool_editing_object = tool->getEditingObject(); + if( tool_editing_object && tool_editing_object->mID == id) + { + tool->stopEditing(); + object_found = TRUE; + } + + // Iterate through selected objects list and kill the object + if( !object_found ) + { + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ) + { + LLObjectSelection::iterator curiter = iter++; + LLViewerObject* object = (*curiter)->getObject(); + if (object->mID == id) + { + if (tool) + { + tool->stopEditing(); + } + + // lose the selection, don't tell simulator, it knows + deselectObjectAndFamily(object, FALSE); + object_found = TRUE; + break; // must break here, may have removed multiple objects from list + } + else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id) + { + // It's possible the item being removed has an avatar sitting on it + // So remove the avatar that is sitting on the object. + deselectObjectAndFamily(object, FALSE); + break; // must break here, may have removed multiple objects from list + } + } + } + + return object_found; } bool LLSelectMgr::linkObjects() { - if (!LLSelectMgr::getInstance()->selectGetAllRootsValid()) - { - LLNotificationsUtil::add("UnableToLinkWhileDownloading"); - return true; - } - - S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - if (object_count > MAX_CHILDREN_PER_TASK + 1) - { - LLSD args; - args["COUNT"] = llformat("%d", object_count); - int max = MAX_CHILDREN_PER_TASK+1; - args["MAX"] = llformat("%d", max); - LLNotificationsUtil::add("UnableToLinkObjects", args); - return true; - } - - if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) - { - LLNotificationsUtil::add("CannotLinkIncompleteSet"); - return true; - } - - if (!LLSelectMgr::getInstance()->selectGetRootsModify()) - { - LLNotificationsUtil::add("CannotLinkModify"); - return true; - } - - if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) - { - LLNotificationsUtil::add("CannotLinkPermanent"); - return true; - } - - LLUUID owner_id; - std::string owner_name; - if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) - { - // we don't actually care if you're the owner, but novices are - // the most likely to be stumped by this one, so offer the - // easiest and most likely solution. - LLNotificationsUtil::add("CannotLinkDifferentOwners"); - return true; - } - - if (!LLSelectMgr::getInstance()->selectGetSameRegion()) - { - LLNotificationsUtil::add("CannotLinkAcrossRegions"); - return true; - } - - LLSelectMgr::getInstance()->sendLink(); - - return true; + if (!LLSelectMgr::getInstance()->selectGetAllRootsValid()) + { + LLNotificationsUtil::add("UnableToLinkWhileDownloading"); + return true; + } + + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (object_count > MAX_CHILDREN_PER_TASK + 1) + { + LLSD args; + args["COUNT"] = llformat("%d", object_count); + int max = MAX_CHILDREN_PER_TASK+1; + args["MAX"] = llformat("%d", max); + LLNotificationsUtil::add("UnableToLinkObjects", args); + return true; + } + + if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) + { + LLNotificationsUtil::add("CannotLinkIncompleteSet"); + return true; + } + + if (!LLSelectMgr::getInstance()->selectGetRootsModify()) + { + LLNotificationsUtil::add("CannotLinkModify"); + return true; + } + + if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + { + LLNotificationsUtil::add("CannotLinkPermanent"); + return true; + } + + LLUUID owner_id; + std::string owner_name; + if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) + { + // we don't actually care if you're the owner, but novices are + // the most likely to be stumped by this one, so offer the + // easiest and most likely solution. + LLNotificationsUtil::add("CannotLinkDifferentOwners"); + return true; + } + + if (!LLSelectMgr::getInstance()->selectGetSameRegion()) + { + LLNotificationsUtil::add("CannotLinkAcrossRegions"); + return true; + } + + LLSelectMgr::getInstance()->sendLink(); + + return true; } bool LLSelectMgr::unlinkObjects() { - S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm"); - S32 unlink_object_count = mSelectedObjects->getObjectCount(); // clears out nodes with NULL objects - if (unlink_object_count >= min_objects_for_confirm - && unlink_object_count > mSelectedObjects->getRootObjectCount()) - { - // total count > root count means that there are childer inside and that there are linksets that will be unlinked - LLNotificationsUtil::add("ConfirmUnlink", LLSD(), LLSD(), boost::bind(&LLSelectMgr::confirmUnlinkObjects, this, _1, _2)); - return true; - } + S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm"); + S32 unlink_object_count = mSelectedObjects->getObjectCount(); // clears out nodes with NULL objects + if (unlink_object_count >= min_objects_for_confirm + && unlink_object_count > mSelectedObjects->getRootObjectCount()) + { + // total count > root count means that there are childer inside and that there are linksets that will be unlinked + LLNotificationsUtil::add("ConfirmUnlink", LLSD(), LLSD(), boost::bind(&LLSelectMgr::confirmUnlinkObjects, this, _1, _2)); + return true; + } - LLSelectMgr::getInstance()->sendDelink(); - return true; + LLSelectMgr::getInstance()->sendDelink(); + return true; } void LLSelectMgr::confirmUnlinkObjects(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - // if Cancel pressed - if (option == 1) - { - return; - } + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } - LLSelectMgr::getInstance()->sendDelink(); - return; + LLSelectMgr::getInstance()->sendDelink(); + return; } // in order to link, all objects must have the same owner, and the @@ -820,158 +820,158 @@ void LLSelectMgr::confirmUnlinkObjects(const LLSD& notification, const LLSD& res // triangle count cannot exceed the designated limit. bool LLSelectMgr::enableLinkObjects() { - bool new_value = false; - // check if there are at least 2 objects selected, and that the - // user can modify at least one of the selected objects. - - // in component mode, can't link - if (!gSavedSettings.getBOOL("EditLinkedParts")) - { - if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2) - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit(); - return object->permModify() && !object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()); - } - } func; - const bool firstonly = true; - new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); - } - } + bool new_value = false; + // check if there are at least 2 objects selected, and that the + // user can modify at least one of the selected objects. + + // in component mode, can't link + if (!gSavedSettings.getBOOL("EditLinkedParts")) + { + if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit(); + return object->permModify() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()); + } + } func; + const bool firstonly = true; + new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); + } + } if (!LLSelectMgr::getInstance()->getSelection()->checkAnimatedObjectLinkable()) { new_value = false; } - return new_value; + return new_value; } bool LLSelectMgr::enableUnlinkObjects() { - LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject(); - LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit(); + LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject(); + LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit(); - bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && - first_editable_object && - !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()); + bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && + first_editable_object && + !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()); - return new_value; + return new_value; } void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object) { - // bail if nothing selected or if object wasn't selected in the first place - if(!object) return; - if(!object->isSelected()) return; - - // Collect all of the objects, and remove them - std::vector objects; - - if (include_entire_object) - { - // Since we're selecting a family, start at the root, but - // don't include an avatar. - LLViewerObject* root = object; - - while(!root->isAvatar() && root->getParent()) - { - LLViewerObject* parent = (LLViewerObject*)root->getParent(); - if (parent->isAvatar()) - { - break; - } - root = parent; - } - - object = root; - } - else - { - object = (LLViewerObject*)object->getRoot(); - } - - object->addThisAndAllChildren(objects); - remove(objects); - - if (!send_to_sim) return; - - //----------------------------------------------------------- - // Inform simulator of deselection - //----------------------------------------------------------- - LLViewerRegion* regionp = object->getRegion(); - - BOOL start_new_message = TRUE; - S32 select_count = 0; - - LLMessageSystem* msg = gMessageSystem; - for (U32 i = 0; i < objects.size(); i++) - { - if (start_new_message) - { - msg->newMessageFast(_PREHASH_ObjectDeselect); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - select_count++; - start_new_message = FALSE; - } - - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID()); - select_count++; - - // Zap the angular velocity, as the sim will set it to zero - objects[i]->setAngularVelocity( 0,0,0 ); - objects[i]->setVelocity( 0,0,0 ); - - if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) - { - msg->sendReliable(regionp->getHost() ); - select_count = 0; - start_new_message = TRUE; - } - } - - if (!start_new_message) - { - msg->sendReliable(regionp->getHost() ); - } - - updatePointAt(); - updateSelectionCenter(); + // bail if nothing selected or if object wasn't selected in the first place + if(!object) return; + if(!object->isSelected()) return; + + // Collect all of the objects, and remove them + std::vector objects; + + if (include_entire_object) + { + // Since we're selecting a family, start at the root, but + // don't include an avatar. + LLViewerObject* root = object; + + while(!root->isAvatar() && root->getParent()) + { + LLViewerObject* parent = (LLViewerObject*)root->getParent(); + if (parent->isAvatar()) + { + break; + } + root = parent; + } + + object = root; + } + else + { + object = (LLViewerObject*)object->getRoot(); + } + + object->addThisAndAllChildren(objects); + remove(objects); + + if (!send_to_sim) return; + + //----------------------------------------------------------- + // Inform simulator of deselection + //----------------------------------------------------------- + LLViewerRegion* regionp = object->getRegion(); + + BOOL start_new_message = TRUE; + S32 select_count = 0; + + LLMessageSystem* msg = gMessageSystem; + for (U32 i = 0; i < objects.size(); i++) + { + if (start_new_message) + { + msg->newMessageFast(_PREHASH_ObjectDeselect); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + select_count++; + start_new_message = FALSE; + } + + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID()); + select_count++; + + // Zap the angular velocity, as the sim will set it to zero + objects[i]->setAngularVelocity( 0,0,0 ); + objects[i]->setVelocity( 0,0,0 ); + + if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) + { + msg->sendReliable(regionp->getHost() ); + select_count = 0; + start_new_message = TRUE; + } + } + + if (!start_new_message) + { + msg->sendReliable(regionp->getHost() ); + } + + updatePointAt(); + updateSelectionCenter(); } void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim) { - // bail if nothing selected or if object wasn't selected in the first place - if (!object) return; - if (!object->isSelected() ) return; + // bail if nothing selected or if object wasn't selected in the first place + if (!object) return; + if (!object->isSelected() ) return; - // Zap the angular velocity, as the sim will set it to zero - object->setAngularVelocity( 0,0,0 ); - object->setVelocity( 0,0,0 ); + // Zap the angular velocity, as the sim will set it to zero + object->setAngularVelocity( 0,0,0 ); + object->setVelocity( 0,0,0 ); - if (send_to_sim) - { - LLViewerRegion* region = object->getRegion(); - gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); - gMessageSystem->sendReliable(region->getHost()); - } + if (send_to_sim) + { + LLViewerRegion* region = object->getRegion(); + gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); + gMessageSystem->sendReliable(region->getHost()); + } - // This will refresh dialogs. - remove( object ); + // This will refresh dialogs. + remove( object ); - updatePointAt(); - updateSelectionCenter(); + updatePointAt(); + updateSelectionCenter(); } @@ -981,53 +981,53 @@ void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim) void LLSelectMgr::addAsFamily(std::vector& objects, BOOL add_to_end) { - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) - { - LLViewerObject* objectp = *iter; - - // Can't select yourself - if (objectp->mID == gAgentID - && !mAllowSelectAvatar) - { - continue; - } - - if (!objectp->isSelected()) - { - LLSelectNode *nodep = new LLSelectNode(objectp, TRUE); - if (add_to_end) - { - mSelectedObjects->addNodeAtEnd(nodep); - } - else - { - mSelectedObjects->addNode(nodep); - } - objectp->setSelected(TRUE); - - if (objectp->getNumTEs() > 0) - { - nodep->selectAllTEs(TRUE); - objectp->setAllTESelected(true); - } - else - { - // object has no faces, so don't mess with faces - } - } - else - { - // we want this object to be selected for real - // so clear transient flag - LLSelectNode* select_node = mSelectedObjects->findNode(objectp); - if (select_node) - { - select_node->setTransient(FALSE); - } - } - } - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + + // Can't select yourself + if (objectp->mID == gAgentID + && !mAllowSelectAvatar) + { + continue; + } + + if (!objectp->isSelected()) + { + LLSelectNode *nodep = new LLSelectNode(objectp, TRUE); + if (add_to_end) + { + mSelectedObjects->addNodeAtEnd(nodep); + } + else + { + mSelectedObjects->addNode(nodep); + } + objectp->setSelected(TRUE); + + if (objectp->getNumTEs() > 0) + { + nodep->selectAllTEs(TRUE); + objectp->setAllTESelected(true); + } + else + { + // object has no faces, so don't mess with faces + } + } + else + { + // we want this object to be selected for real + // so clear transient flag + LLSelectNode* select_node = mSelectedObjects->findNode(objectp); + if (select_node) + { + select_node->setTransient(FALSE); + } + } + } + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); } //----------------------------------------------------------------------------- @@ -1035,454 +1035,454 @@ void LLSelectMgr::addAsFamily(std::vector& objects, BOOL add_to //----------------------------------------------------------------------------- void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable, S32 gltf_node, S32 gltf_primitive) { - // check to see if object is already in list - LLSelectNode *nodep = mSelectedObjects->findNode(objectp); - - // if not in list, add it - if (!nodep) - { - nodep = new LLSelectNode(objectp, TRUE); - mSelectedObjects->addNode(nodep); - llassert_always(nodep->getObject()); - } - else - { - // make this a full-fledged selection - nodep->setTransient(FALSE); - // Move it to the front of the list - mSelectedObjects->moveNodeToFront(nodep); - } - - // Make sure the object is tagged as selected - objectp->setSelected( TRUE ); - - // And make sure we don't consider it as part of a family - nodep->mIndividualSelection = TRUE; - - // Handle face selection - if (objectp->getNumTEs() <= 0) - { - // object has no faces, so don't do anything - } - else if (face == SELECT_ALL_TES) - { - nodep->selectAllTEs(TRUE); - objectp->setAllTESelected(true); - } - else if (0 <= face && face < SELECT_MAX_TES) - { - nodep->selectTE(face, TRUE); - objectp->setTESelected(face, true); - } - else - { - LL_ERRS() << "LLSelectMgr::add face " << face << " out-of-range" << LL_ENDL; - return; - } + // check to see if object is already in list + LLSelectNode *nodep = mSelectedObjects->findNode(objectp); + + // if not in list, add it + if (!nodep) + { + nodep = new LLSelectNode(objectp, TRUE); + mSelectedObjects->addNode(nodep); + llassert_always(nodep->getObject()); + } + else + { + // make this a full-fledged selection + nodep->setTransient(FALSE); + // Move it to the front of the list + mSelectedObjects->moveNodeToFront(nodep); + } + + // Make sure the object is tagged as selected + objectp->setSelected( TRUE ); + + // And make sure we don't consider it as part of a family + nodep->mIndividualSelection = TRUE; + + // Handle face selection + if (objectp->getNumTEs() <= 0) + { + // object has no faces, so don't do anything + } + else if (face == SELECT_ALL_TES) + { + nodep->selectAllTEs(TRUE); + objectp->setAllTESelected(true); + } + else if (0 <= face && face < SELECT_MAX_TES) + { + nodep->selectTE(face, TRUE); + objectp->setTESelected(face, true); + } + else + { + LL_ERRS() << "LLSelectMgr::add face " << face << " out-of-range" << LL_ENDL; + return; + } // Handle glTF node selection if (gltf_node >= 0) { nodep->selectGLTFNode(gltf_node, gltf_primitive, TRUE); - + } - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - updateSelectionCenter(); - dialog_refresh_all(); + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + updateSelectionCenter(); + dialog_refresh_all(); } LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face) { - if (!objectp) - { - mHoverObjects->deleteAllNodes(); - return NULL; - } - - // Can't select yourself - if (objectp->mID == gAgentID) - { - mHoverObjects->deleteAllNodes(); - return NULL; - } - - // Can't select land - if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) - { - mHoverObjects->deleteAllNodes(); - return NULL; - } - - mHoverObjects->mPrimaryObject = objectp; - - objectp = objectp->getRootEdit(); - - // is the requested object the same as the existing hover object root? - // NOTE: there is only ever one linked set in mHoverObjects - if (mHoverObjects->getFirstRootObject() != objectp) - { - - // Collect all of the objects - std::vector objects; - objectp = objectp->getRootEdit(); - objectp->addThisAndNonJointChildren(objects); - - mHoverObjects->deleteAllNodes(); - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) - { - LLViewerObject* cur_objectp = *iter; - if(!cur_objectp || cur_objectp->isDead()) - { - continue; - } - LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); - nodep->selectTE(face, TRUE); - mHoverObjects->addNodeAtEnd(nodep); - } - - requestObjectPropertiesFamily(objectp); - } - - return mHoverObjects; + if (!objectp) + { + mHoverObjects->deleteAllNodes(); + return NULL; + } + + // Can't select yourself + if (objectp->mID == gAgentID) + { + mHoverObjects->deleteAllNodes(); + return NULL; + } + + // Can't select land + if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) + { + mHoverObjects->deleteAllNodes(); + return NULL; + } + + mHoverObjects->mPrimaryObject = objectp; + + objectp = objectp->getRootEdit(); + + // is the requested object the same as the existing hover object root? + // NOTE: there is only ever one linked set in mHoverObjects + if (mHoverObjects->getFirstRootObject() != objectp) + { + + // Collect all of the objects + std::vector objects; + objectp = objectp->getRootEdit(); + objectp->addThisAndNonJointChildren(objects); + + mHoverObjects->deleteAllNodes(); + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) + { + LLViewerObject* cur_objectp = *iter; + if(!cur_objectp || cur_objectp->isDead()) + { + continue; + } + LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); + nodep->selectTE(face, TRUE); + mHoverObjects->addNodeAtEnd(nodep); + } + + requestObjectPropertiesFamily(objectp); + } + + return mHoverObjects; } LLSelectNode *LLSelectMgr::getHoverNode() { - return mHoverObjects->getFirstRootNode(); + return mHoverObjects->getFirstRootNode(); } LLSelectNode *LLSelectMgr::getPrimaryHoverNode() { - return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject]; + return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject]; } void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) { - if (!objectp) - { - return; - } + if (!objectp) + { + return; + } + + if (objectp->getPCode() != LL_PCODE_VOLUME) + { + return; + } - if (objectp->getPCode() != LL_PCODE_VOLUME) - { - return; - } - if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced()))) - { - // only select my own objects - return; - } + { + // only select my own objects + return; + } - mRectSelectedObjects.insert(objectp); + mRectSelectedObjects.insert(objectp); } void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp) { - if (!objectp) - { - return; - } + if (!objectp) + { + return; + } - LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); + LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); - highlightObjectOnly(root_obj); + highlightObjectOnly(root_obj); - LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - highlightObjectOnly(child); - } + LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + highlightObjectOnly(child); + } } // Note that this ignores the "select owned only" flag // It's also more efficient than calling the single-object version over and over. void LLSelectMgr::highlightObjectAndFamily(const std::vector& objects) { - for (std::vector::const_iterator iter1 = objects.begin(); - iter1 != objects.end(); ++iter1) - { - LLViewerObject* object = *iter1; - - if (!object) - { - continue; - } - if (object->getPCode() != LL_PCODE_VOLUME) - { - continue; - } - - LLViewerObject* root = (LLViewerObject*)object->getRoot(); - mRectSelectedObjects.insert(root); - - LLViewerObject::const_child_list_t& child_list = root->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin(); - iter2 != child_list.end(); iter2++) - { - LLViewerObject* child = *iter2; - mRectSelectedObjects.insert(child); - } - } + for (std::vector::const_iterator iter1 = objects.begin(); + iter1 != objects.end(); ++iter1) + { + LLViewerObject* object = *iter1; + + if (!object) + { + continue; + } + if (object->getPCode() != LL_PCODE_VOLUME) + { + continue; + } + + LLViewerObject* root = (LLViewerObject*)object->getRoot(); + mRectSelectedObjects.insert(root); + + LLViewerObject::const_child_list_t& child_list = root->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin(); + iter2 != child_list.end(); iter2++) + { + LLViewerObject* child = *iter2; + mRectSelectedObjects.insert(child); + } + } } void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp) { - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } - mRectSelectedObjects.erase(objectp); + mRectSelectedObjects.erase(objectp); } void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp) { - if (!objectp) - { - return; - } + if (!objectp) + { + return; + } - LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); + LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); - unhighlightObjectOnly(root_obj); + unhighlightObjectOnly(root_obj); - LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - unhighlightObjectOnly(child); - } + LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + unhighlightObjectOnly(child); + } } void LLSelectMgr::unhighlightAll() { - mRectSelectedObjects.clear(); - mHighlightedObjects->deleteAllNodes(); + mRectSelectedObjects.clear(); + mHighlightedObjects->deleteAllNodes(); } LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects() { - if (!mHighlightedObjects->getNumNodes()) - { - return NULL; - } + if (!mHighlightedObjects->getNumNodes()) + { + return NULL; + } + + //clear primary object + mSelectedObjects->mPrimaryObject = NULL; - //clear primary object - mSelectedObjects->mPrimaryObject = NULL; + for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin(); + iter != getHighlightedObjects()->end(); ) + { + LLObjectSelection::iterator curiter = iter++; - for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin(); - iter != getHighlightedObjects()->end(); ) - { - LLObjectSelection::iterator curiter = iter++; - - LLSelectNode *nodep = *curiter; - LLViewerObject* objectp = nodep->getObject(); + LLSelectNode *nodep = *curiter; + LLViewerObject* objectp = nodep->getObject(); - if (!canSelectObject(objectp)) - { - continue; - } + if (!canSelectObject(objectp)) + { + continue; + } - // already selected - if (objectp->isSelected()) - { - continue; - } + // already selected + if (objectp->isSelected()) + { + continue; + } - LLSelectNode* new_nodep = new LLSelectNode(*nodep); - mSelectedObjects->addNode(new_nodep); + LLSelectNode* new_nodep = new LLSelectNode(*nodep); + mSelectedObjects->addNode(new_nodep); - // flag this object as selected - objectp->setSelected(TRUE); - objectp->setAllTESelected(true); + // flag this object as selected + objectp->setSelected(TRUE); + objectp->setAllTESelected(true); - mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); + mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); - // request properties on root objects - if (objectp->isRootEdit()) - { - requestObjectPropertiesFamily(objectp); - } - } + // request properties on root objects + if (objectp->isRootEdit()) + { + requestObjectPropertiesFamily(objectp); + } + } - // pack up messages to let sim know these objects are selected - sendSelect(); - unhighlightAll(); - updateSelectionCenter(); - saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - updatePointAt(); + // pack up messages to let sim know these objects are selected + sendSelect(); + unhighlightAll(); + updateSelectionCenter(); + saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + updatePointAt(); - if (mSelectedObjects->getObjectCount()) - { - gEditMenuHandler = this; - } + if (mSelectedObjects->getObjectCount()) + { + gEditMenuHandler = this; + } - return mSelectedObjects; + return mSelectedObjects; } void LLSelectMgr::deselectHighlightedObjects() { - BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - for (std::set >::iterator iter = mRectSelectedObjects.begin(); - iter != mRectSelectedObjects.end(); iter++) - { - LLViewerObject *objectp = *iter; - if (!select_linked_set) - { - deselectObjectOnly(objectp); - } - else - { - LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot(); - if (root_object->isSelected()) - { - deselectObjectAndFamily(root_object); - } - } - } - - unhighlightAll(); + BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + for (std::set >::iterator iter = mRectSelectedObjects.begin(); + iter != mRectSelectedObjects.end(); iter++) + { + LLViewerObject *objectp = *iter; + if (!select_linked_set) + { + deselectObjectOnly(objectp); + } + else + { + LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot(); + if (root_object->isSelected()) + { + deselectObjectAndFamily(root_object); + } + } + } + + unhighlightAll(); } void LLSelectMgr::addGridObject(LLViewerObject* objectp) { - LLSelectNode* nodep = new LLSelectNode(objectp, FALSE); - mGridObjects.addNodeAtEnd(nodep); + LLSelectNode* nodep = new LLSelectNode(objectp, FALSE); + mGridObjects.addNodeAtEnd(nodep); - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - nodep = new LLSelectNode(child, FALSE); - mGridObjects.addNodeAtEnd(nodep); - } + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + nodep = new LLSelectNode(child, FALSE); + mGridObjects.addNodeAtEnd(nodep); + } } void LLSelectMgr::clearGridObjects() { - mGridObjects.deleteAllNodes(); + mGridObjects.deleteAllNodes(); } void LLSelectMgr::setGridMode(EGridMode mode) { - mGridMode = mode; - gSavedSettings.setS32("GridMode", mode); - updateSelectionCenter(); + mGridMode = mode; + gSavedSettings.setS32("GridMode", mode); + updateSelectionCenter(); } void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale, bool for_snap_guides) { - mGridObjects.cleanupNodes(); - - LLViewerObject* first_grid_object = mGridObjects.getFirstObject(); - - if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) - { - //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject()); - mGridOrigin = mSavedSelectionBBox.getCenterAgent(); - mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; - - // DEV-12570 Just taking the saved selection box rotation prevents - // wild rotations of linked sets while in local grid mode - //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull()) - { - mGridRotation = mSavedSelectionBBox.getRotation(); - } - /*else //set to the root object - { - mGridRotation = root->getRenderRotation(); - }*/ - } - else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull()) - { - LLSelectNode *node = mSelectedObjects->findNode(first_grid_object); - if (!for_snap_guides && node) - { - mGridRotation = node->mSavedRotation; - } - else - { - mGridRotation = first_grid_object->getRenderRotation(); - } - - LLVector4a min_extents(F32_MAX); - LLVector4a max_extents(-F32_MAX); - BOOL grid_changed = FALSE; - for (LLObjectSelection::iterator iter = mGridObjects.begin(); - iter != mGridObjects.end(); ++iter) - { - LLViewerObject* object = (*iter)->getObject(); - LLDrawable* drawable = object->mDrawable; - if (drawable) - { - const LLVector4a* ext = drawable->getSpatialExtents(); - update_min_max(min_extents, max_extents, ext[0]); - update_min_max(min_extents, max_extents, ext[1]); - grid_changed = TRUE; - } - } - if (grid_changed) - { - LLVector4a center, size; - center.setAdd(min_extents, max_extents); - center.mul(0.5f); - size.setSub(max_extents, min_extents); - size.mul(0.5f); - - mGridOrigin.set(center.getF32ptr()); - LLDrawable* drawable = first_grid_object->mDrawable; - if (drawable && drawable->isActive()) - { - mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); - } - mGridScale.set(size.getF32ptr()); - } - } - else // GRID_MODE_WORLD or just plain default - { - const BOOL non_root_ok = TRUE; - LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok); - - mGridOrigin.clearVec(); - mGridRotation.loadIdentity(); - - mSelectedObjects->mSelectType = getSelectTypeForObject( first_object ); - - switch (mSelectedObjects->mSelectType) - { - case SELECT_TYPE_ATTACHMENT: - if (first_object && first_object->getRootEdit()->mDrawable.notNull()) - { - // this means this object *has* to be an attachment - LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent(); - mGridOrigin = attachment_point_xform->getWorldPosition(); - mGridRotation = attachment_point_xform->getWorldRotation(); - mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); - } - break; - case SELECT_TYPE_HUD: - mGridScale = LLVector3(1.f, 1.f, 1.f) * llmin(gSavedSettings.getF32("GridResolution"), 0.5f); - break; - case SELECT_TYPE_WORLD: - mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); - break; - } - } - llassert(mGridOrigin.isFinite()); - - origin = mGridOrigin; - rotation = mGridRotation; - scale = mGridScale; + mGridObjects.cleanupNodes(); + + LLViewerObject* first_grid_object = mGridObjects.getFirstObject(); + + if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) + { + //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject()); + mGridOrigin = mSavedSelectionBBox.getCenterAgent(); + mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; + + // DEV-12570 Just taking the saved selection box rotation prevents + // wild rotations of linked sets while in local grid mode + //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull()) + { + mGridRotation = mSavedSelectionBBox.getRotation(); + } + /*else //set to the root object + { + mGridRotation = root->getRenderRotation(); + }*/ + } + else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull()) + { + LLSelectNode *node = mSelectedObjects->findNode(first_grid_object); + if (!for_snap_guides && node) + { + mGridRotation = node->mSavedRotation; + } + else + { + mGridRotation = first_grid_object->getRenderRotation(); + } + + LLVector4a min_extents(F32_MAX); + LLVector4a max_extents(-F32_MAX); + BOOL grid_changed = FALSE; + for (LLObjectSelection::iterator iter = mGridObjects.begin(); + iter != mGridObjects.end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + const LLVector4a* ext = drawable->getSpatialExtents(); + update_min_max(min_extents, max_extents, ext[0]); + update_min_max(min_extents, max_extents, ext[1]); + grid_changed = TRUE; + } + } + if (grid_changed) + { + LLVector4a center, size; + center.setAdd(min_extents, max_extents); + center.mul(0.5f); + size.setSub(max_extents, min_extents); + size.mul(0.5f); + + mGridOrigin.set(center.getF32ptr()); + LLDrawable* drawable = first_grid_object->mDrawable; + if (drawable && drawable->isActive()) + { + mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); + } + mGridScale.set(size.getF32ptr()); + } + } + else // GRID_MODE_WORLD or just plain default + { + const BOOL non_root_ok = TRUE; + LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok); + + mGridOrigin.clearVec(); + mGridRotation.loadIdentity(); + + mSelectedObjects->mSelectType = getSelectTypeForObject( first_object ); + + switch (mSelectedObjects->mSelectType) + { + case SELECT_TYPE_ATTACHMENT: + if (first_object && first_object->getRootEdit()->mDrawable.notNull()) + { + // this means this object *has* to be an attachment + LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent(); + mGridOrigin = attachment_point_xform->getWorldPosition(); + mGridRotation = attachment_point_xform->getWorldRotation(); + mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); + } + break; + case SELECT_TYPE_HUD: + mGridScale = LLVector3(1.f, 1.f, 1.f) * llmin(gSavedSettings.getF32("GridResolution"), 0.5f); + break; + case SELECT_TYPE_WORLD: + mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); + break; + } + } + llassert(mGridOrigin.isFinite()); + + origin = mGridOrigin; + rotation = mGridRotation; + scale = mGridScale; } //----------------------------------------------------------------------------- @@ -1491,20 +1491,20 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & void LLSelectMgr::remove(std::vector& objects) { - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) - { - LLViewerObject* objectp = *iter; - LLSelectNode* nodep = mSelectedObjects->findNode(objectp); - if (nodep) - { - objectp->setSelected(FALSE); - mSelectedObjects->removeNode(nodep); - nodep = NULL; - } - } - updateSelectionCenter(); - dialog_refresh_all(); + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + LLSelectNode* nodep = mSelectedObjects->findNode(objectp); + if (nodep) + { + objectp->setSelected(FALSE); + mSelectedObjects->removeNode(nodep); + nodep = NULL; + } + } + updateSelectionCenter(); + dialog_refresh_all(); } @@ -1513,59 +1513,59 @@ void LLSelectMgr::remove(std::vector& objects) //----------------------------------------------------------------------------- void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) { - // get object node (and verify it is in the selected list) - LLSelectNode *nodep = mSelectedObjects->findNode(objectp); - if (!nodep) - { - return; - } - - // if face = all, remove object from list - if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES)) - { - // Remove all faces (or the object doesn't have faces) so remove the node - mSelectedObjects->removeNode(nodep); - nodep = NULL; - objectp->setSelected( FALSE ); - } - else if (0 <= te && te < SELECT_MAX_TES) - { - // ...valid face, check to see if it was on - if (nodep->isTESelected(te)) - { - nodep->selectTE(te, FALSE); - objectp->setTESelected(te, false); - } - else - { - LL_ERRS() << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << LL_ENDL; - return; - } - - // ...check to see if this operation turned off all faces - BOOL found = FALSE; - for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++) - { - found = found || nodep->isTESelected(i); - } - - // ...all faces now turned off, so remove - if (!found) - { - mSelectedObjects->removeNode(nodep); - nodep = NULL; - objectp->setSelected( FALSE ); - // *FIXME: Doesn't update simulator that object is no longer selected - } - } - else - { - // ...out of range face - LL_ERRS() << "LLSelectMgr::remove - TE " << te << " out of range" << LL_ENDL; - } - - updateSelectionCenter(); - dialog_refresh_all(); + // get object node (and verify it is in the selected list) + LLSelectNode *nodep = mSelectedObjects->findNode(objectp); + if (!nodep) + { + return; + } + + // if face = all, remove object from list + if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES)) + { + // Remove all faces (or the object doesn't have faces) so remove the node + mSelectedObjects->removeNode(nodep); + nodep = NULL; + objectp->setSelected( FALSE ); + } + else if (0 <= te && te < SELECT_MAX_TES) + { + // ...valid face, check to see if it was on + if (nodep->isTESelected(te)) + { + nodep->selectTE(te, FALSE); + objectp->setTESelected(te, false); + } + else + { + LL_ERRS() << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << LL_ENDL; + return; + } + + // ...check to see if this operation turned off all faces + BOOL found = FALSE; + for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++) + { + found = found || nodep->isTESelected(i); + } + + // ...all faces now turned off, so remove + if (!found) + { + mSelectedObjects->removeNode(nodep); + nodep = NULL; + objectp->setSelected( FALSE ); + // *FIXME: Doesn't update simulator that object is no longer selected + } + } + else + { + // ...out of range face + LL_ERRS() << "LLSelectMgr::remove - TE " << te << " out of range" << LL_ENDL; + } + + updateSelectionCenter(); + dialog_refresh_all(); } @@ -1574,17 +1574,17 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) //----------------------------------------------------------------------------- void LLSelectMgr::removeAll() { - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); - iter != mSelectedObjects->end(); iter++ ) - { - LLViewerObject *objectp = (*iter)->getObject(); - objectp->setSelected( FALSE ); - } + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) + { + LLViewerObject *objectp = (*iter)->getObject(); + objectp->setSelected( FALSE ); + } - mSelectedObjects->deleteAllNodes(); - - updateSelectionCenter(); - dialog_refresh_all(); + mSelectedObjects->deleteAllNodes(); + + updateSelectionCenter(); + dialog_refresh_all(); } //----------------------------------------------------------------------------- @@ -1592,41 +1592,41 @@ void LLSelectMgr::removeAll() //----------------------------------------------------------------------------- void LLSelectMgr::promoteSelectionToRoot() { - std::set selection_set; + std::set selection_set; + + BOOL selection_changed = FALSE; - BOOL selection_changed = FALSE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ) + { + LLObjectSelection::iterator curiter = iter++; + LLSelectNode* nodep = *curiter; + LLViewerObject* object = nodep->getObject(); - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); ) - { - LLObjectSelection::iterator curiter = iter++; - LLSelectNode* nodep = *curiter; - LLViewerObject* object = nodep->getObject(); + if (nodep->mIndividualSelection) + { + selection_changed = TRUE; + } - if (nodep->mIndividualSelection) - { - selection_changed = TRUE; - } + LLViewerObject* parentp = object; + while(parentp->getParent() && !(parentp->isRootEdit())) + { + parentp = (LLViewerObject*)parentp->getParent(); + } - LLViewerObject* parentp = object; - while(parentp->getParent() && !(parentp->isRootEdit())) - { - parentp = (LLViewerObject*)parentp->getParent(); - } - - selection_set.insert(parentp); - } + selection_set.insert(parentp); + } - if (selection_changed) - { - deselectAll(); + if (selection_changed) + { + deselectAll(); - std::set::iterator set_iter; - for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter) - { - selectObjectAndFamily(*set_iter); - } - } + std::set::iterator set_iter; + for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter) + { + selectObjectAndFamily(*set_iter); + } + } } //----------------------------------------------------------------------------- @@ -1634,25 +1634,25 @@ void LLSelectMgr::promoteSelectionToRoot() //----------------------------------------------------------------------------- void LLSelectMgr::demoteSelectionToIndividuals() { - std::vector objects; + std::vector objects; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++) - { - LLViewerObject* object = (*iter)->getObject(); - object->addThisAndNonJointChildren(objects); - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + LLViewerObject* object = (*iter)->getObject(); + object->addThisAndNonJointChildren(objects); + } - if (!objects.empty()) - { - deselectAll(); - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) - { - LLViewerObject* objectp = *iter; - selectObjectOnly(objectp); - } - } + if (!objects.empty()) + { + deselectAll(); + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + selectObjectOnly(objectp); + } + } } //----------------------------------------------------------------------------- @@ -1660,49 +1660,49 @@ void LLSelectMgr::demoteSelectionToIndividuals() //----------------------------------------------------------------------------- void LLSelectMgr::dump() { - LL_INFOS() << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << LL_ENDL; - - LL_INFOS() << "TE mode " << mTEMode << LL_ENDL; - - S32 count = 0; - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLViewerObject* objectp = (*iter)->getObject(); - LL_INFOS() << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << LL_ENDL; - LL_INFOS() << " hasLSL " << objectp->flagScripted() << LL_ENDL; - LL_INFOS() << " hasTouch " << objectp->flagHandleTouch() << LL_ENDL; - LL_INFOS() << " hasMoney " << objectp->flagTakesMoney() << LL_ENDL; - LL_INFOS() << " getposition " << objectp->getPosition() << LL_ENDL; - LL_INFOS() << " getpositionAgent " << objectp->getPositionAgent() << LL_ENDL; - LL_INFOS() << " getpositionRegion " << objectp->getPositionRegion() << LL_ENDL; - LL_INFOS() << " getpositionGlobal " << objectp->getPositionGlobal() << LL_ENDL; - LLDrawable* drawablep = objectp->mDrawable; - LL_INFOS() << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << LL_ENDL; - LL_INFOS() << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << LL_ENDL; - count++; - } - - // Face iterator - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; - for (S32 te = 0; te < objectp->getNumTEs(); ++te ) - { - if (node->isTESelected(te)) - { - LL_INFOS() << "Object " << objectp << " te " << te << LL_ENDL; - } - } - } - - LL_INFOS() << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << LL_ENDL; - - LL_INFOS() << "Center global " << mSelectionCenterGlobal << LL_ENDL; + LL_INFOS() << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << LL_ENDL; + + LL_INFOS() << "TE mode " << mTEMode << LL_ENDL; + + S32 count = 0; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLViewerObject* objectp = (*iter)->getObject(); + LL_INFOS() << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << LL_ENDL; + LL_INFOS() << " hasLSL " << objectp->flagScripted() << LL_ENDL; + LL_INFOS() << " hasTouch " << objectp->flagHandleTouch() << LL_ENDL; + LL_INFOS() << " hasMoney " << objectp->flagTakesMoney() << LL_ENDL; + LL_INFOS() << " getposition " << objectp->getPosition() << LL_ENDL; + LL_INFOS() << " getpositionAgent " << objectp->getPositionAgent() << LL_ENDL; + LL_INFOS() << " getpositionRegion " << objectp->getPositionRegion() << LL_ENDL; + LL_INFOS() << " getpositionGlobal " << objectp->getPositionGlobal() << LL_ENDL; + LLDrawable* drawablep = objectp->mDrawable; + LL_INFOS() << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << LL_ENDL; + LL_INFOS() << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << LL_ENDL; + count++; + } + + // Face iterator + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; + for (S32 te = 0; te < objectp->getNumTEs(); ++te ) + { + if (node->isTESelected(te)) + { + LL_INFOS() << "Object " << objectp << " te " << te << LL_ENDL; + } + } + } + + LL_INFOS() << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << LL_ENDL; + + LL_INFOS() << "Center global " << mSelectionCenterGlobal << LL_ENDL; } //----------------------------------------------------------------------------- @@ -1710,7 +1710,7 @@ void LLSelectMgr::dump() //----------------------------------------------------------------------------- void LLSelectMgr::cleanup() { - mSilhouetteImagep = NULL; + mSilhouetteImagep = NULL; } @@ -1720,54 +1720,54 @@ void LLSelectMgr::cleanup() struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor { - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - return true; - } + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } }; void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) { - if (!item) - { - return; - } - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); - - for (iterator iter = begin(); iter != end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = (*iter)->getObject(); - if (!object) - { - continue; - } - - S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); - bool texture_copied = false; + if (!item) + { + return; + } + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); + + for (iterator iter = begin(); iter != end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = (*iter)->getObject(); + if (!object) + { + continue; + } + + S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); + bool texture_copied = false; bool updated = false; - for (S32 te = 0; te < num_tes; ++te) - { - if (node->isTESelected(te)) - { - //(no-copy) textures must be moved to the object's inventory only once - // without making any copies - if (!texture_copied) - { - LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); - texture_copied = true; - } - - // apply texture for the selected faces - add(LLStatViewer::EDIT_TEXTURE, 1); - object->setTEImage(te, image); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + //(no-copy) textures must be moved to the object's inventory only once + // without making any copies + if (!texture_copied) + { + LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); + texture_copied = true; + } + + // apply texture for the selected faces + add(LLStatViewer::EDIT_TEXTURE, 1); + object->setTEImage(te, image); updated = true; - } - } + } + } if (updated) // not nessesary? sendTEUpdate update supposed to be done by sendfunc { @@ -1776,7 +1776,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) // send the update to the simulator object->sendTEUpdate(); } - } + } } bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item) @@ -1818,7 +1818,7 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i if (!material_copied) { // Applying the material is not possible for this object given the current inventory - material_copied_all_faces = false; + material_copied_all_faces = false; break; } @@ -1842,30 +1842,30 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i // *TODO: re-arch texture applying out of lltooldraganddrop bool LLSelectMgr::selectionSetImage(const LLUUID& imageid) { - // First for (no copy) textures and multiple object selection - LLViewerInventoryItem* item = gInventory.getItem(imageid); - if(item - && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) - && (mSelectedObjects->getNumNodes() > 1) ) - { + // First for (no copy) textures and multiple object selection + LLViewerInventoryItem* item = gInventory.getItem(imageid); + if(item + && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) + && (mSelectedObjects->getNumNodes() > 1) ) + { LL_DEBUGS() << "Attempted to apply no-copy texture " << imageid << " to multiple objects" << LL_ENDL; LLNotificationsUtil::add("FailedToApplyTextureNoCopyToMultiple"); return false; - } - - struct f : public LLSelectedTEFunctor - { - LLViewerInventoryItem* mItem; - LLUUID mImageID; - f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {} - bool apply(LLViewerObject* objectp, S32 te) - { - if(!objectp || !objectp->permModify()) - { - return false; - } + } + + struct f : public LLSelectedTEFunctor + { + LLViewerInventoryItem* mItem; + LLUUID mImageID; + f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {} + bool apply(LLViewerObject* objectp, S32 te) + { + if(!objectp || !objectp->permModify()) + { + return false; + } // Might be better to run willObjectAcceptInventory if (mItem && objectp->isAttachment()) @@ -1880,58 +1880,58 @@ bool LLSelectMgr::selectionSetImage(const LLUUID& imageid) } } - if (mItem) - { + if (mItem) + { LLToolDragAndDrop::dropTextureOneFace(objectp, te, mItem, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, false); - } - else // not an inventory item - { - // Texture picker defaults aren't inventory items - // * Don't need to worry about permissions for them - // * Can just apply the texture and be done with it. - objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); - } - - return true; - } - }; - - if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) - { - getSelection()->applyNoCopyTextureToTEs(item); - } - else - { - f setfunc(item, imageid); - getSelection()->applyToTEs(&setfunc); - } - - - struct g : public LLSelectedObjectFunctor - { - LLViewerInventoryItem* mItem; - g(LLViewerInventoryItem* item) : mItem(item) {} - virtual bool apply(LLViewerObject* object) - { - if (!mItem) - { - object->sendTEUpdate(); - // 1 particle effect per object - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(object); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - } - return true; - } - } sendfunc(item); - getSelection()->applyToObjects(&sendfunc); + } + else // not an inventory item + { + // Texture picker defaults aren't inventory items + // * Don't need to worry about permissions for them + // * Can just apply the texture and be done with it. + objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + } + + return true; + } + }; + + if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + { + getSelection()->applyNoCopyTextureToTEs(item); + } + else + { + f setfunc(item, imageid); + getSelection()->applyToTEs(&setfunc); + } + + + struct g : public LLSelectedObjectFunctor + { + LLViewerInventoryItem* mItem; + g(LLViewerInventoryItem* item) : mItem(item) {} + virtual bool apply(LLViewerObject* object) + { + if (!mItem) + { + object->sendTEUpdate(); + // 1 particle effect per object + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(object); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } + return true; + } + } sendfunc(item); + getSelection()->applyToObjects(&sendfunc); return true; } @@ -2035,7 +2035,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) if (!mItem) { - // 1 particle effect per object + // 1 particle effect per object LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); effectp->setSourceObject(gAgentAvatarp); effectp->setTargetObject(object); @@ -2060,23 +2060,23 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetColor(const LLColor4 &color) { - struct f : public LLSelectedTEFunctor - { - LLColor4 mColor; - f(const LLColor4& c) : mColor(c) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - object->setTEColor(te, mColor); - } - return true; - } - } setfunc(color); - getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedTEFunctor + { + LLColor4 mColor; + f(const LLColor4& c) : mColor(c) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + object->setTEColor(te, mColor); + } + return true; + } + } setfunc(color); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } //----------------------------------------------------------------------------- @@ -2084,152 +2084,152 @@ void LLSelectMgr::selectionSetColor(const LLColor4 &color) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color) { - struct f : public LLSelectedTEFunctor - { - LLColor4 mColor; - f(const LLColor4& c) : mColor(c) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - LLColor4 prev_color = object->getTE(te)->getColor(); - mColor.mV[VALPHA] = prev_color.mV[VALPHA]; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, mColor); - } - return true; - } - } setfunc(color); - getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); -} - + struct f : public LLSelectedTEFunctor + { + LLColor4 mColor; + f(const LLColor4& c) : mColor(c) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + LLColor4 prev_color = object->getTE(te)->getColor(); + mColor.mV[VALPHA] = prev_color.mV[VALPHA]; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, mColor); + } + return true; + } + } setfunc(color); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); +} + //----------------------------------------------------------------------------- // selectionSetAlphaOnly() //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha) { - struct f : public LLSelectedTEFunctor - { - F32 mAlpha; - f(const F32& a) : mAlpha(a) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - LLColor4 prev_color = object->getTE(te)->getColor(); - prev_color.mV[VALPHA] = mAlpha; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, prev_color); - } - return true; - } - } setfunc(alpha); - getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedTEFunctor + { + F32 mAlpha; + f(const F32& a) : mAlpha(a) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + LLColor4 prev_color = object->getTE(te)->getColor(); + prev_color.mV[VALPHA] = mAlpha; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, prev_color); + } + return true; + } + } setfunc(alpha); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionRevertColors() { - struct f : public LLSelectedTEFunctor - { - LLObjectSelectionHandle mSelectedObjects; - f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedColors.size()) - { - LLColor4 color = nodep->mSavedColors[te]; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, color); - } - } - return true; - } - } setfunc(mSelectedObjects); - getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedTEFunctor + { + LLObjectSelectionHandle mSelectedObjects; + f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + LLSelectNode* nodep = mSelectedObjects->findNode(object); + if (nodep && te < (S32)nodep->mSavedColors.size()) + { + LLColor4 color = nodep->mSavedColors[te]; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, color); + } + } + return true; + } + } setfunc(mSelectedObjects); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionRevertShinyColors() { - struct f : public LLSelectedTEFunctor - { - LLObjectSelectionHandle mSelectedObjects; - f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedShinyColors.size()) - { - LLColor4 color = nodep->mSavedShinyColors[te]; - // update viewer side color in anticipation of update from simulator - LLMaterialPtr old_mat = object->getTE(te)->getMaterialParams(); - if (!old_mat.isNull()) - { - LLMaterialPtr new_mat = gFloaterTools->getPanelFace()->createDefaultMaterial(old_mat); - new_mat->setSpecularLightColor(color); - object->getTE(te)->setMaterialParams(new_mat); - LLMaterialMgr::getInstance()->put(object->getID(), te, *new_mat); - } - } - } - return true; - } - } setfunc(mSelectedObjects); - getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedTEFunctor + { + LLObjectSelectionHandle mSelectedObjects; + f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + LLSelectNode* nodep = mSelectedObjects->findNode(object); + if (nodep && te < (S32)nodep->mSavedShinyColors.size()) + { + LLColor4 color = nodep->mSavedShinyColors[te]; + // update viewer side color in anticipation of update from simulator + LLMaterialPtr old_mat = object->getTE(te)->getMaterialParams(); + if (!old_mat.isNull()) + { + LLMaterialPtr new_mat = gFloaterTools->getPanelFace()->createDefaultMaterial(old_mat); + new_mat->setSpecularLightColor(color); + object->getTE(te)->setMaterialParams(new_mat); + LLMaterialMgr::getInstance()->put(object->getID(), te, *new_mat); + } + } + } + return true; + } + } setfunc(mSelectedObjects); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } BOOL LLSelectMgr::selectionRevertTextures() { - struct f : public LLSelectedTEFunctor - { - LLObjectSelectionHandle mSelectedObjects; - f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedTextures.size()) - { - LLUUID id = nodep->mSavedTextures[te]; - // update textures on viewer side - if (id.isNull()) - { - // this was probably a no-copy texture, leave image as-is - return FALSE; - } - else - { - object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); - - } - } - } - return true; - } - } setfunc(mSelectedObjects); - BOOL revert_successful = getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); - - return revert_successful; + struct f : public LLSelectedTEFunctor + { + LLObjectSelectionHandle mSelectedObjects; + f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + LLSelectNode* nodep = mSelectedObjects->findNode(object); + if (nodep && te < (S32)nodep->mSavedTextures.size()) + { + LLUUID id = nodep->mSavedTextures[te]; + // update textures on viewer side + if (id.isNull()) + { + // this was probably a no-copy texture, leave image as-is + return FALSE; + } + else + { + object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + + } + } + } + return true; + } + } setfunc(mSelectedObjects); + BOOL revert_successful = getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); + + return revert_successful; } void LLSelectMgr::selectionRevertGLTFMaterials() @@ -2260,7 +2260,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials() { // Restore overrides and base material LLGLTFMaterialList::queueApply(objectp, te, asset_id, nodep->mSavedGLTFOverrideMaterials[te]); - } + } else { //blank override out @@ -2276,23 +2276,23 @@ void LLSelectMgr::selectionRevertGLTFMaterials() void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id) { - struct f : public LLSelectedTEFunctor - { - U8 mBump; - f(const U8& b) : mBump(b) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEBumpmap(te, mBump); - } - return true; - } - } setfunc(bumpmap); + struct f : public LLSelectedTEFunctor + { + U8 mBump; + f(const U8& b) : mBump(b) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEBumpmap(te, mBump); + } + return true; + } + } setfunc(bumpmap); LLViewerInventoryItem* item = gInventory.getItem(image_id); - if(item + if(item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && (mSelectedObjects->getNumNodes() > 1) ) { @@ -2318,53 +2318,53 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id) LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); } getSelection()->applyToTEs(&setfunc); - - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetTexGen(U8 texgen) { - struct f : public LLSelectedTEFunctor - { - U8 mTexgen; - f(const U8& t) : mTexgen(t) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTETexGen(te, mTexgen); - } - return true; - } - } setfunc(texgen); - getSelection()->applyToTEs(&setfunc); + struct f : public LLSelectedTEFunctor + { + U8 mTexgen; + f(const U8& t) : mTexgen(t) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTETexGen(te, mTexgen); + } + return true; + } + } setfunc(texgen); + getSelection()->applyToTEs(&setfunc); - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id) { - struct f : public LLSelectedTEFunctor - { - U8 mShiny; - f(const U8& t) : mShiny(t) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEShiny(te, mShiny); - } - return true; - } - } setfunc(shiny); + struct f : public LLSelectedTEFunctor + { + U8 mShiny; + f(const U8& t) : mShiny(t) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEShiny(te, mShiny); + } + return true; + } + } setfunc(shiny); LLViewerInventoryItem* item = gInventory.getItem(image_id); - if(item + if(item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && (mSelectedObjects->getNumNodes() > 1) ) { @@ -2391,235 +2391,235 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id) } getSelection()->applyToTEs(&setfunc); - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetFullbright(U8 fullbright) { - struct f : public LLSelectedTEFunctor - { - U8 mFullbright; - f(const U8& t) : mFullbright(t) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEFullbright(te, mFullbright); - } - return true; - } - } setfunc(fullbright); - getSelection()->applyToTEs(&setfunc); - - struct g : public LLSelectedObjectFunctor - { - U8 mFullbright; - g(const U8& t) : mFullbright(t) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - if (mFullbright) - { - U8 material = object->getMaterial(); - U8 mcode = material & LL_MCODE_MASK; - if (mcode == LL_MCODE_LIGHT) - { - mcode = LL_MCODE_GLASS; - material = (material & ~LL_MCODE_MASK) | mcode; - object->setMaterial(material); - object->sendMaterialUpdate(); - } - } - } - return true; - } - } sendfunc(fullbright); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedTEFunctor + { + U8 mFullbright; + f(const U8& t) : mFullbright(t) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEFullbright(te, mFullbright); + } + return true; + } + } setfunc(fullbright); + getSelection()->applyToTEs(&setfunc); + + struct g : public LLSelectedObjectFunctor + { + U8 mFullbright; + g(const U8& t) : mFullbright(t) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + if (mFullbright) + { + U8 material = object->getMaterial(); + U8 mcode = material & LL_MCODE_MASK; + if (mcode == LL_MCODE_LIGHT) + { + mcode = LL_MCODE_GLASS; + material = (material & ~LL_MCODE_MASK) | mcode; + object->setMaterial(material); + object->sendMaterialUpdate(); + } + } + } + return true; + } + } sendfunc(fullbright); + getSelection()->applyToObjects(&sendfunc); } // This function expects media_data to be a map containing relevant // media data name/value pairs (e.g. home_url, etc.) void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) -{ - struct f : public LLSelectedTEFunctor - { - U8 mMediaFlags; - const LLSD &mMediaData; - f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {} - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - // If we are adding media, then check the current state of the - // media data on this face. - // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this - // face. - // - If it does not have media, and we ARE setting the HOME URL, add media to this face. - // - If it does already have media, add/update media to/on this face - // If we are removing media, just do it (ignore the passed-in LLSD). - if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA) - { - llassert(mMediaData.isMap()); - const LLTextureEntry *texture_entry = object->getTE(te); - if (!mMediaData.isMap() || - ((NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY))) - { - // skip adding/updating media - } - else { - // Add/update media - object->setTEMediaFlags(te, mMediaFlags); - LLVOVolume *vo = dynamic_cast(object); - llassert(NULL != vo); - if (NULL != vo) - { - vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/); - } - } - } - else - { - // delete media (or just set the flags) - object->setTEMediaFlags(te, mMediaFlags); - } - } - return true; - } - } setfunc(media_type, media_data); - getSelection()->applyToTEs(&setfunc); - - struct f2 : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - LLVOVolume *vo = dynamic_cast(object); - llassert(NULL != vo); - // It's okay to skip this object if hasMedia() is false... - // the sendTEUpdate() above would remove all media data if it were - // there. +{ + struct f : public LLSelectedTEFunctor + { + U8 mMediaFlags; + const LLSD &mMediaData; + f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // If we are adding media, then check the current state of the + // media data on this face. + // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this + // face. + // - If it does not have media, and we ARE setting the HOME URL, add media to this face. + // - If it does already have media, add/update media to/on this face + // If we are removing media, just do it (ignore the passed-in LLSD). + if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA) + { + llassert(mMediaData.isMap()); + const LLTextureEntry *texture_entry = object->getTE(te); + if (!mMediaData.isMap() || + ((NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY))) + { + // skip adding/updating media + } + else { + // Add/update media + object->setTEMediaFlags(te, mMediaFlags); + LLVOVolume *vo = dynamic_cast(object); + llassert(NULL != vo); + if (NULL != vo) + { + vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/); + } + } + } + else + { + // delete media (or just set the flags) + object->setTEMediaFlags(te, mMediaFlags); + } + } + return true; + } + } setfunc(media_type, media_data); + getSelection()->applyToTEs(&setfunc); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + LLVOVolume *vo = dynamic_cast(object); + llassert(NULL != vo); + // It's okay to skip this object if hasMedia() is false... + // the sendTEUpdate() above would remove all media data if it were + // there. if (NULL != vo && vo->hasMedia()) { // Send updated media data FOR THE ENTIRE OBJECT vo->sendMediaDataUpdate(); } - } - return true; - } - } func2; - mSelectedObjects->applyToObjects( &func2 ); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); } void LLSelectMgr::selectionSetGlow(F32 glow) { - struct f1 : public LLSelectedTEFunctor - { - F32 mGlow; - f1(F32 glow) : mGlow(glow) {}; - bool apply(LLViewerObject* object, S32 face) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEGlow(face, mGlow); - } - return true; - } - } func1(glow); - mSelectedObjects->applyToTEs( &func1 ); - - struct f2 : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - return true; - } - } func2; - mSelectedObjects->applyToObjects( &func2 ); + struct f1 : public LLSelectedTEFunctor + { + F32 mGlow; + f1(F32 glow) : mGlow(glow) {}; + bool apply(LLViewerObject* object, S32 face) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEGlow(face, mGlow); + } + return true; + } + } func1(glow); + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); } void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int te) { - struct f1 : public LLSelectedTEFunctor - { - LLMaterialPtr mMaterial; - f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {} + struct f1 : public LLSelectedTEFunctor + { + LLMaterialPtr mMaterial; + f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {} - bool apply(LLViewerObject* object, S32 te) - { + bool apply(LLViewerObject* object, S32 te) + { if (_specific_te == -1 || (te == _specific_te)) { - if (object && object->permModify() && _material_func) - { - LLTextureEntry* tep = object->getTE(te); - if (tep) - { - LLMaterialPtr current_material = tep->getMaterialParams(); - _material_func->apply(object, te, tep, current_material); - } - } + if (object && object->permModify() && _material_func) + { + LLTextureEntry* tep = object->getTE(te); + if (tep) + { + LLMaterialPtr current_material = tep->getMaterialParams(); + _material_func->apply(object, te, tep, current_material); + } + } } - return true; - } + return true; + } - LLSelectedTEMaterialFunctor* _material_func; + LLSelectedTEMaterialFunctor* _material_func; int _specific_te; - } func1(material_func, te); - mSelectedObjects->applyToTEs( &func1 ); - - struct f2 : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - return true; - } - } func2; - mSelectedObjects->applyToObjects( &func2 ); + } func1(material_func, te); + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); } void LLSelectMgr::selectionRemoveMaterial() { - struct f1 : public LLSelectedTEFunctor - { - bool apply(LLViewerObject* object, S32 face) - { - if (object->permModify()) - { - LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; - LLMaterialMgr::getInstance()->remove(object->getID(),face); - object->setTEMaterialParams(face, NULL); - } - return true; - } - } func1; - mSelectedObjects->applyToTEs( &func1 ); - - struct f2 : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - return true; - } - } func2; - mSelectedObjects->applyToObjects( &func2 ); + struct f1 : public LLSelectedTEFunctor + { + bool apply(LLViewerObject* object, S32 face) + { + if (object->permModify()) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + object->setTEMaterialParams(face, NULL); + } + return true; + } + } func1; + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); } @@ -2628,17 +2628,17 @@ void LLSelectMgr::selectionRemoveMaterial() //----------------------------------------------------------------------------- LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) { - for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); - iter != getSelection()->valid_end(); iter++ ) - { - LLSelectNode* nodep = *iter; - if (nodep->getObject() == object) - { - return nodep->mPermissions; - } - } + for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); + iter != getSelection()->valid_end(); iter++ ) + { + LLSelectNode* nodep = *iter; + if (nodep->getObject() == object) + { + return nodep->mPermissions; + } + } - return NULL; + return NULL; } @@ -2647,115 +2647,115 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectionGetGlow(F32 *glow) { - BOOL identical; - F32 lglow = 0.f; - struct f1 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->getGlow(); - } - } func; - identical = mSelectedObjects->getSelectedTEValue( &func, lglow ); + BOOL identical; + F32 lglow = 0.f; + struct f1 : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + return object->getTE(face)->getGlow(); + } + } func; + identical = mSelectedObjects->getSelectedTEValue( &func, lglow ); - *glow = lglow; - return identical; + *glow = lglow; + return identical; } void LLSelectMgr::selectionSetPhysicsType(U8 type) { - struct f : public LLSelectedObjectFunctor - { - U8 mType; - f(const U8& t) : mType(t) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->setPhysicsShapeType(mType); - object->updateFlags(TRUE); - } - return true; - } - } sendfunc(type); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + U8 mType; + f(const U8& t) : mType(t) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsShapeType(mType); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(type); + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetFriction(F32 friction) { - struct f : public LLSelectedObjectFunctor - { - F32 mFriction; - f(const F32& friction) : mFriction(friction) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->setPhysicsFriction(mFriction); - object->updateFlags(TRUE); - } - return true; - } - } sendfunc(friction); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + F32 mFriction; + f(const F32& friction) : mFriction(friction) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsFriction(mFriction); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(friction); + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetGravity(F32 gravity ) { - struct f : public LLSelectedObjectFunctor - { - F32 mGravity; - f(const F32& gravity) : mGravity(gravity) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->setPhysicsGravity(mGravity); - object->updateFlags(TRUE); - } - return true; - } - } sendfunc(gravity); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + F32 mGravity; + f(const F32& gravity) : mGravity(gravity) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsGravity(mGravity); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(gravity); + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetDensity(F32 density ) { - struct f : public LLSelectedObjectFunctor - { - F32 mDensity; - f(const F32& density ) : mDensity(density) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->setPhysicsDensity(mDensity); - object->updateFlags(TRUE); - } - return true; - } - } sendfunc(density); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + F32 mDensity; + f(const F32& density ) : mDensity(density) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsDensity(mDensity); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(density); + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetRestitution(F32 restitution) { - struct f : public LLSelectedObjectFunctor - { - F32 mRestitution; - f(const F32& restitution ) : mRestitution(restitution) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->setPhysicsRestitution(mRestitution); - object->updateFlags(TRUE); - } - return true; - } - } sendfunc(restitution); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + F32 mRestitution; + f(const F32& restitution ) : mRestitution(restitution) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->setPhysicsRestitution(mRestitution); + object->updateFlags(TRUE); + } + return true; + } + } sendfunc(restitution); + getSelection()->applyToObjects(&sendfunc); } @@ -2764,136 +2764,136 @@ void LLSelectMgr::selectionSetRestitution(F32 restitution) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetMaterial(U8 material) { - struct f : public LLSelectedObjectFunctor - { - U8 mMaterial; - f(const U8& t) : mMaterial(t) {} - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - U8 cur_material = object->getMaterial(); - U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK); - object->setMaterial(material); - object->sendMaterialUpdate(); - } - return true; - } - } sendfunc(material); - getSelection()->applyToObjects(&sendfunc); + struct f : public LLSelectedObjectFunctor + { + U8 mMaterial; + f(const U8& t) : mMaterial(t) {} + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + U8 cur_material = object->getMaterial(); + U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK); + object->setMaterial(material); + object->sendMaterialUpdate(); + } + return true; + } + } sendfunc(material); + getSelection()->applyToObjects(&sendfunc); } // TRUE if all selected objects have this PCode BOOL LLSelectMgr::selectionAllPCode(LLPCode code) { - struct f : public LLSelectedObjectFunctor - { - LLPCode mCode; - f(const LLPCode& t) : mCode(t) {} - virtual bool apply(LLViewerObject* object) - { - if (object->getPCode() != mCode) - { - return FALSE; - } - return true; - } - } func(code); - BOOL res = getSelection()->applyToObjects(&func); - return res; + struct f : public LLSelectedObjectFunctor + { + LLPCode mCode; + f(const LLPCode& t) : mCode(t) {} + virtual bool apply(LLViewerObject* object) + { + if (object->getPCode() != mCode) + { + return FALSE; + } + return true; + } + } func(code); + BOOL res = getSelection()->applyToObjects(&func); + return res; } bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out) { - LLViewerObject *object = mSelectedObjects->getFirstRootObject(); - if (!object) return FALSE; + LLViewerObject *object = mSelectedObjects->getFirstRootObject(); + if (!object) return FALSE; - bool include_in_search = object->getIncludeInSearch(); + bool include_in_search = object->getIncludeInSearch(); - bool identical = true; + bool identical = true; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++) - { - LLViewerObject* object = (*iter)->getObject(); + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + LLViewerObject* object = (*iter)->getObject(); - if ( include_in_search != object->getIncludeInSearch()) - { - identical = false; - break; - } - } + if ( include_in_search != object->getIncludeInSearch()) + { + identical = false; + break; + } + } - *include_in_search_out = include_in_search; - return identical; + *include_in_search_out = include_in_search; + return identical; } void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search) { - LLViewerObject* object = NULL; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++) - { - object = (*iter)->getObject(); - object->setIncludeInSearch(include_in_search); - } - sendListToRegions( - "ObjectIncludeInSearch", - packAgentAndSessionID, - packObjectIncludeInSearch, + LLViewerObject* object = NULL; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + object = (*iter)->getObject(); + object->setIncludeInSearch(include_in_search); + } + sendListToRegions( + "ObjectIncludeInSearch", + packAgentAndSessionID, + packObjectIncludeInSearch, logNoOp, - &include_in_search, - SEND_ONLY_ROOTS); + &include_in_search, + SEND_ONLY_ROOTS); } BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action) { - LLViewerObject *object = mSelectedObjects->getFirstObject(); - if (!object) - { - return FALSE; - } - - U8 action = object->getClickAction(); - *out_action = action; - - struct f : public LLSelectedObjectFunctor - { - U8 mAction; - f(const U8& t) : mAction(t) {} - virtual bool apply(LLViewerObject* object) - { - if ( mAction != object->getClickAction()) - { - return false; - } - return true; - } - } func(action); - BOOL res = getSelection()->applyToObjects(&func); - return res; -} - -void LLSelectMgr::selectionSetClickAction(U8 action) + LLViewerObject *object = mSelectedObjects->getFirstObject(); + if (!object) + { + return FALSE; + } + + U8 action = object->getClickAction(); + *out_action = action; + + struct f : public LLSelectedObjectFunctor + { + U8 mAction; + f(const U8& t) : mAction(t) {} + virtual bool apply(LLViewerObject* object) + { + if ( mAction != object->getClickAction()) + { + return false; + } + return true; + } + } func(action); + BOOL res = getSelection()->applyToObjects(&func); + return res; +} + +void LLSelectMgr::selectionSetClickAction(U8 action) { - struct f : public LLSelectedObjectFunctor - { - U8 mAction; - f(const U8& t) : mAction(t) {} - virtual bool apply(LLViewerObject* object) - { - object->setClickAction(mAction); - return true; - } - } func(action); - getSelection()->applyToObjects(&func); - - sendListToRegions("ObjectClickAction", - packAgentAndSessionID, - packObjectClickAction, + struct f : public LLSelectedObjectFunctor + { + U8 mAction; + f(const U8& t) : mAction(t) {} + virtual bool apply(LLViewerObject* object) + { + object->setClickAction(mAction); + return true; + } + } func(action); + getSelection()->applyToObjects(&func); + + sendListToRegions("ObjectClickAction", + packAgentAndSessionID, + packObjectClickAction, logNoOp, - &action, - SEND_INDIVIDUALS); + &action, + SEND_INDIVIDUALS); } @@ -2905,54 +2905,54 @@ typedef std::pair godlike_request_t; void LLSelectMgr::sendGodlikeRequest(const std::string& request, const std::string& param) { - // If the agent is neither godlike nor an estate owner, the server - // will reject the request. - std::string message_type; - if (gAgent.isGodlike()) - { - message_type = "GodlikeMessage"; - } - else - { - message_type = "EstateOwnerMessage"; - } - - godlike_request_t data(request, param); - if(!mSelectedObjects->getRootObjectCount()) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessage(message_type.c_str()); - LLSelectMgr::packGodlikeHead(&data); - gAgent.sendReliableMessage(); - } - else - { - sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, logNoOp, &data, SEND_ONLY_ROOTS); - } + // If the agent is neither godlike nor an estate owner, the server + // will reject the request. + std::string message_type; + if (gAgent.isGodlike()) + { + message_type = "GodlikeMessage"; + } + else + { + message_type = "EstateOwnerMessage"; + } + + godlike_request_t data(request, param); + if(!mSelectedObjects->getRootObjectCount()) + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessage(message_type.c_str()); + LLSelectMgr::packGodlikeHead(&data); + gAgent.sendReliableMessage(); + } + else + { + sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, logNoOp, &data, SEND_ONLY_ROOTS); + } } void LLSelectMgr::packGodlikeHead(void* user_data) { - LLMessageSystem* msg = gMessageSystem; - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUID("TransactionID", LLUUID::null); - godlike_request_t* data = (godlike_request_t*)user_data; - msg->nextBlock("MethodData"); - msg->addString("Method", data->first); - msg->addUUID("Invoice", LLUUID::null); - - // The parameters used to be restricted to either string or - // integer. This mimics that behavior under the new 'string-only' - // parameter list by not packing a string if there wasn't one - // specified. The object ids will be packed in the - // packObjectIDAsParam() method. - if(data->second.size() > 0) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", data->second); - } + LLMessageSystem* msg = gMessageSystem; + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID("TransactionID", LLUUID::null); + godlike_request_t* data = (godlike_request_t*)user_data; + msg->nextBlock("MethodData"); + msg->addString("Method", data->first); + msg->addUUID("Invoice", LLUUID::null); + + // The parameters used to be restricted to either string or + // integer. This mimics that behavior under the new 'string-only' + // parameter list by not packing a string if there wasn't one + // specified. The object ids will be packed in the + // packObjectIDAsParam() method. + if(data->second.size() > 0) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", data->second); + } } // static @@ -2975,9 +2975,9 @@ void LLSelectMgr::logDetachRequest(LLSelectNode* node, void *) // static void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *) { - std::string buf = llformat("%u", node->getObject()->getLocalID()); - gMessageSystem->nextBlock("ParamList"); - gMessageSystem->addString("Parameter", buf); + std::string buf = llformat("%u", node->getObject()->getLocalID()); + gMessageSystem->nextBlock("ParamList"); + gMessageSystem->addString("Parameter", buf); } //----------------------------------------------------------------------------- @@ -2985,34 +2985,34 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *) //----------------------------------------------------------------------------- void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter) { - struct f : public LLSelectedTEFunctor - { - F32 mRepeatsPerMeter; - f(const F32& t) : mRepeatsPerMeter(t) {} - bool apply(LLViewerObject* object, S32 te) - { - - if (object->permModify()) - { - // Compute S,T to axis mapping - U32 s_axis, t_axis; - if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) - { - return TRUE; - } + struct f : public LLSelectedTEFunctor + { + F32 mRepeatsPerMeter; + f(const F32& t) : mRepeatsPerMeter(t) {} + bool apply(LLViewerObject* object, S32 te) + { + + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + { + return TRUE; + } - F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; - F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; - object->setTEScale(te, new_s, new_t); - } - return true; - } - } setfunc(repeats_per_meter); - getSelection()->applyToTEs(&setfunc); + object->setTEScale(te, new_s, new_t); + } + return true; + } + } setfunc(repeats_per_meter); + getSelection()->applyToTEs(&setfunc); - LLSelectMgrSendFunctor sendfunc; - getSelection()->applyToObjects(&sendfunc); + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } @@ -3025,113 +3025,113 @@ void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter) //----------------------------------------------------------------------------- void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++) - { - LLSelectNode* selectNode = *iter; - LLViewerObject* object = selectNode->getObject(); - - if (!object) - { - continue; - } - - if (!object->permModify()) - { - continue; - } - - if (object->getNumTEs() == 0) - { - continue; - } - - BOOL send = FALSE; - - for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++) - { - const LLTextureEntry* tep = object->getTE(te_num); - - BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR; - if (planar == stretch) - { - // Figure out how S,T changed with scale operation - U32 s_axis, t_axis; - if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis)) - { - continue; - } - - LLVector3 object_scale = object->getScale(); - LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num]; - - // We like these to track together. NORSPEC-96 - // - LLVector3 normal_scale_ratio = diffuse_scale_ratio; - LLVector3 specular_scale_ratio = diffuse_scale_ratio; - - // Apply new scale to face - if (planar) - { - F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; - F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; - - F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; - F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; - - F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; - F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; - - object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t); - - LLTextureEntry* tep = object->getTE(te_num); - - if (tep && !tep->getMaterialParams().isNull()) - { - LLMaterialPtr orig = tep->getMaterialParams(); - LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); - p->setNormalRepeat(normal_scale_s, normal_scale_t); - p->setSpecularRepeat(specular_scale_s, specular_scale_t); - - LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); - } - } - else - { - - F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; - F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; - - F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; - F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; - - F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; - F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; - - object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t); - - LLTextureEntry* tep = object->getTE(te_num); - - if (tep && !tep->getMaterialParams().isNull()) - { - LLMaterialPtr orig = tep->getMaterialParams(); - LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); - - p->setNormalRepeat(normal_scale_s, normal_scale_t); - p->setSpecularRepeat(specular_scale_s, specular_scale_t); - - LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); - } - } - send = send_to_sim; - } - } - - if (send) - { - object->sendTEUpdate(); - } - } + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) + { + LLSelectNode* selectNode = *iter; + LLViewerObject* object = selectNode->getObject(); + + if (!object) + { + continue; + } + + if (!object->permModify()) + { + continue; + } + + if (object->getNumTEs() == 0) + { + continue; + } + + BOOL send = FALSE; + + for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++) + { + const LLTextureEntry* tep = object->getTE(te_num); + + BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR; + if (planar == stretch) + { + // Figure out how S,T changed with scale operation + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis)) + { + continue; + } + + LLVector3 object_scale = object->getScale(); + LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num]; + + // We like these to track together. NORSPEC-96 + // + LLVector3 normal_scale_ratio = diffuse_scale_ratio; + LLVector3 specular_scale_ratio = diffuse_scale_ratio; + + // Apply new scale to face + if (planar) + { + F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t); + + LLTextureEntry* tep = object->getTE(te_num); + + if (tep && !tep->getMaterialParams().isNull()) + { + LLMaterialPtr orig = tep->getMaterialParams(); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); + p->setNormalRepeat(normal_scale_s, normal_scale_t); + p->setSpecularRepeat(specular_scale_s, specular_scale_t); + + LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); + } + } + else + { + + F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t); + + LLTextureEntry* tep = object->getTE(te_num); + + if (tep && !tep->getMaterialParams().isNull()) + { + LLMaterialPtr orig = tep->getMaterialParams(); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); + + p->setNormalRepeat(normal_scale_s, normal_scale_t); + p->setSpecularRepeat(specular_scale_s, specular_scale_t); + + LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); + } + } + send = send_to_sim; + } + } + + if (send) + { + object->sendTEUpdate(); + } + } } //----------------------------------------------------------------------------- @@ -3140,16 +3140,16 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetAllRootsValid() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); ++iter ) - { - LLSelectNode* node = *iter; - if( !node->mValid ) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); ++iter ) + { + LLSelectNode* node = *iter; + if( !node->mValid ) + { + return FALSE; + } + } + return TRUE; } @@ -3159,16 +3159,16 @@ BOOL LLSelectMgr::selectGetAllRootsValid() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetAllValid() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); ++iter ) - { - LLSelectNode* node = *iter; - if( !node->mValid ) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ++iter ) + { + LLSelectNode* node = *iter; + if( !node->mValid ) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3179,17 +3179,17 @@ BOOL LLSelectMgr::selectGetAllValid() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetAllValidAndObjectsFound() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3198,21 +3198,21 @@ BOOL LLSelectMgr::selectGetAllValidAndObjectsFound() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetModify() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( !object->permModify() ) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->permModify() ) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3221,22 +3221,22 @@ BOOL LLSelectMgr::selectGetModify() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsModify() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( !object->permModify() ) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( !object->permModify() ) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3275,21 +3275,21 @@ BOOL LLSelectMgr::selectGetSameRegion() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetNonPermanentEnforced() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( object->isPermanentEnforced()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->isPermanentEnforced()) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3298,22 +3298,22 @@ BOOL LLSelectMgr::selectGetNonPermanentEnforced() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( object->isPermanentEnforced()) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( object->isPermanentEnforced()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3321,21 +3321,21 @@ BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetPermanent() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( !object->flagObjectPermanent()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->flagObjectPermanent()) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3344,22 +3344,22 @@ BOOL LLSelectMgr::selectGetPermanent() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsPermanent() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( !object->flagObjectPermanent()) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( !object->flagObjectPermanent()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3367,21 +3367,21 @@ BOOL LLSelectMgr::selectGetRootsPermanent() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetCharacter() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( !object->flagCharacter()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->flagCharacter()) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3390,22 +3390,22 @@ BOOL LLSelectMgr::selectGetCharacter() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsCharacter() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( !object->flagCharacter()) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( !object->flagCharacter()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3413,21 +3413,21 @@ BOOL LLSelectMgr::selectGetRootsCharacter() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetNonPathfinding() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( object->flagObjectPermanent() || object->flagCharacter()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent() || object->flagCharacter()) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3436,22 +3436,22 @@ BOOL LLSelectMgr::selectGetNonPathfinding() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsNonPathfinding() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( object->flagObjectPermanent() || object->flagCharacter()) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent() || object->flagCharacter()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3459,45 +3459,45 @@ BOOL LLSelectMgr::selectGetRootsNonPathfinding() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetNonPermanent() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( object->flagObjectPermanent()) - { - return FALSE; - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// selectGetRootsNonPermanent() - return TRUE if all root objects are not -// permanent -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetRootsNonPermanent() -{ - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( object->flagObjectPermanent()) - { - return FALSE; - } - } + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent()) + { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsNonPermanent() - return TRUE if all root objects are not +// permanent +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetRootsNonPermanent() +{ + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( object->flagObjectPermanent()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -3505,45 +3505,45 @@ BOOL LLSelectMgr::selectGetRootsNonPermanent() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetNonCharacter() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( object->flagCharacter()) - { - return FALSE; - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// selectGetRootsNonCharacter() - return TRUE if all root objects are not + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( object->flagCharacter()) + { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// selectGetRootsNonCharacter() - return TRUE if all root objects are not // character //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsNonCharacter() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if( object->flagCharacter()) - { - return FALSE; - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if( object->flagCharacter()) + { + return FALSE; + } + } - return TRUE; + return TRUE; } @@ -3553,30 +3553,30 @@ BOOL LLSelectMgr::selectGetRootsNonCharacter() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetEditableLinksets() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if (object->flagUsePhysics() || - object->flagTemporaryOnRez() || - object->flagCharacter() || - object->flagVolumeDetect() || - object->flagAnimSource() || - (object->getRegion() != gAgent.getRegion()) || - (!gAgent.isGodlike() && - !gAgent.canManageEstate() && - !object->permYouOwner() && - !object->permMove())) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if (object->flagUsePhysics() || + object->flagTemporaryOnRez() || + object->flagCharacter() || + object->flagVolumeDetect() || + object->flagAnimSource() || + (object->getRegion() != gAgent.getRegion()) || + (!gAgent.isGodlike() && + !gAgent.canManageEstate() && + !object->permYouOwner() && + !object->permMove())) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3585,22 +3585,22 @@ BOOL LLSelectMgr::selectGetEditableLinksets() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetViewableCharacters() { - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !object || !node->mValid ) - { - return FALSE; - } - if( !object->flagCharacter() || - (object->getRegion() != gAgent.getRegion())) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + if( !object->flagCharacter() || + (object->getRegion() != gAgent.getRegion())) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3609,21 +3609,21 @@ BOOL LLSelectMgr::selectGetViewableCharacters() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsTransfer() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if(!object->permTransfer()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if(!object->permTransfer()) + { + return FALSE; + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -3632,88 +3632,88 @@ BOOL LLSelectMgr::selectGetRootsTransfer() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsCopy() { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if( !node->mValid ) - { - return FALSE; - } - if(!object->permCopy()) - { - return FALSE; - } - } - return TRUE; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) + { + return FALSE; + } + if(!object->permCopy()) + { + return FALSE; + } + } + return TRUE; } struct LLSelectGetFirstTest { - LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { } - virtual ~LLSelectGetFirstTest() { } - - // returns false to break out of the iteration. - bool checkMatchingNode(LLSelectNode* node) - { - if (!node || !node->mValid) - { - return false; - } - - if (mFirst) - { - mFirstValue = getValueFromNode(node); - mFirst = false; - } - else - { - if ( mFirstValue != getValueFromNode(node) ) - { - mIdentical = false; - // stop testing once we know not all selected are identical. - return false; - } - } - // continue testing. - return true; - } - - bool mIdentical; - LLUUID mFirstValue; + LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { } + virtual ~LLSelectGetFirstTest() { } + + // returns false to break out of the iteration. + bool checkMatchingNode(LLSelectNode* node) + { + if (!node || !node->mValid) + { + return false; + } + + if (mFirst) + { + mFirstValue = getValueFromNode(node); + mFirst = false; + } + else + { + if ( mFirstValue != getValueFromNode(node) ) + { + mIdentical = false; + // stop testing once we know not all selected are identical. + return false; + } + } + // continue testing. + return true; + } + + bool mIdentical; + LLUUID mFirstValue; protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0; + virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0; private: - bool mFirst; + bool mFirst; }; void LLSelectMgr::getFirst(LLSelectGetFirstTest* test) { - if (gSavedSettings.getBOOL("EditLinkedParts")) - { - for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); - iter != getSelection()->valid_end(); ++iter ) - { - if (!test->checkMatchingNode(*iter)) - { - break; - } - } - } - else - { - for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); - iter != getSelection()->root_object_end(); ++iter ) - { - if (!test->checkMatchingNode(*iter)) - { - break; - } - } - } + if (gSavedSettings.getBOOL("EditLinkedParts")) + { + for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); + iter != getSelection()->valid_end(); ++iter ) + { + if (!test->checkMatchingNode(*iter)) + { + break; + } + } + } + else + { + for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); + iter != getSelection()->root_object_end(); ++iter ) + { + if (!test->checkMatchingNode(*iter)) + { + break; + } + } + } } //----------------------------------------------------------------------------- @@ -3723,35 +3723,35 @@ void LLSelectMgr::getFirst(LLSelectGetFirstTest* test) struct LLSelectGetFirstCreator : public LLSelectGetFirstTest { protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { - return node->mPermissions->getCreator(); - } + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + return node->mPermissions->getCreator(); + } }; BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) { - LLSelectGetFirstCreator test; - getFirst(&test); + LLSelectGetFirstCreator test; + getFirst(&test); + + if (test.mFirstValue.isNull()) + { + name = LLTrans::getString("AvatarNameNobody"); + return FALSE; + } + + result_id = test.mFirstValue; - if (test.mFirstValue.isNull()) - { - name = LLTrans::getString("AvatarNameNobody"); - return FALSE; - } - - result_id = test.mFirstValue; - - if (test.mIdentical) - { - name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); - } - else - { - name = LLTrans::getString("AvatarNameMultiple"); - } + if (test.mIdentical) + { + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); + } + else + { + name = LLTrans::getString("AvatarNameMultiple"); + } - return test.mIdentical; + return test.mIdentical; } //----------------------------------------------------------------------------- @@ -3761,44 +3761,44 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) struct LLSelectGetFirstOwner : public LLSelectGetFirstTest { protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { - // Don't use 'getOwnership' since we return a reference, not a copy. - // Will return LLUUID::null if unowned (which is not allowed and should never happen.) - return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); - } + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + // Don't use 'getOwnership' since we return a reference, not a copy. + // Will return LLUUID::null if unowned (which is not allowed and should never happen.) + return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); + } }; BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) { - LLSelectGetFirstOwner test; - getFirst(&test); - - if (test.mFirstValue.isNull()) - { - return FALSE; - } - - result_id = test.mFirstValue; - - if (test.mIdentical) - { - bool group_owned = selectIsGroupOwned(); - if (group_owned) - { - name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString(); - } - else - { - name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); - } - } - else - { - name = LLTrans::getString("AvatarNameMultiple"); - } - - return test.mIdentical; + LLSelectGetFirstOwner test; + getFirst(&test); + + if (test.mFirstValue.isNull()) + { + return FALSE; + } + + result_id = test.mFirstValue; + + if (test.mIdentical) + { + bool group_owned = selectIsGroupOwned(); + if (group_owned) + { + name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString(); + } + else + { + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); + } + } + else + { + name = LLTrans::getString("AvatarNameMultiple"); + } + + return test.mIdentical; } //----------------------------------------------------------------------------- @@ -3808,34 +3808,34 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest { protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { - return node->mPermissions->getLastOwner(); - } + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + return node->mPermissions->getLastOwner(); + } }; BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) { - LLSelectGetFirstLastOwner test; - getFirst(&test); + LLSelectGetFirstLastOwner test; + getFirst(&test); - if (test.mFirstValue.isNull()) - { - return FALSE; - } + if (test.mFirstValue.isNull()) + { + return FALSE; + } + + result_id = test.mFirstValue; - result_id = test.mFirstValue; - - if (test.mIdentical) - { - name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); - } - else - { - name.assign( "" ); - } + if (test.mIdentical) + { + name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); + } + else + { + name.assign( "" ); + } - return test.mIdentical; + return test.mIdentical; } //----------------------------------------------------------------------------- @@ -3845,45 +3845,45 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) struct LLSelectGetFirstGroup : public LLSelectGetFirstTest { protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { - return node->mPermissions->getGroup(); - } + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + return node->mPermissions->getGroup(); + } }; BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id) { - LLSelectGetFirstGroup test; - getFirst(&test); + LLSelectGetFirstGroup test; + getFirst(&test); - result_id = test.mFirstValue; - return test.mIdentical; + result_id = test.mFirstValue; + return test.mIdentical; } //----------------------------------------------------------------------------- // selectIsGroupOwned() -// Only operates on root nodes unless editing linked parts. +// Only operates on root nodes unless editing linked parts. // Returns TRUE if the first selected is group owned. //----------------------------------------------------------------------------- struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest { protected: - virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { - if (node->mPermissions->isGroupOwned()) - { - return node->mPermissions->getGroup(); - } - return LLUUID::null; - } + virtual const LLUUID& getValueFromNode(LLSelectNode* node) + { + if (node->mPermissions->isGroupOwned()) + { + return node->mPermissions->getGroup(); + } + return LLUUID::null; + } }; BOOL LLSelectMgr::selectIsGroupOwned() { - LLSelectGetFirstGroupOwner test; - getFirst(&test); + LLSelectGetFirstGroupOwner test; + getFirst(&test); - return test.mFirstValue.notNull() ? TRUE : FALSE; + return test.mFirstValue.notNull() ? TRUE : FALSE; } //----------------------------------------------------------------------------- @@ -3897,439 +3897,439 @@ BOOL LLSelectMgr::selectIsGroupOwned() //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off) { - U32 mask; - U32 mask_and = 0xffffffff; - U32 mask_or = 0x00000000; - BOOL all_valid = FALSE; - - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - - if (!node->mValid) - { - all_valid = FALSE; - break; - } - - all_valid = TRUE; - - switch( which_perm ) - { - case PERM_BASE: - mask = node->mPermissions->getMaskBase(); - break; - case PERM_OWNER: - mask = node->mPermissions->getMaskOwner(); - break; - case PERM_GROUP: - mask = node->mPermissions->getMaskGroup(); - break; - case PERM_EVERYONE: - mask = node->mPermissions->getMaskEveryone(); - break; - case PERM_NEXT_OWNER: - mask = node->mPermissions->getMaskNextOwner(); - break; - default: - mask = 0x0; - break; - } - mask_and &= mask; - mask_or |= mask; - } - - if (all_valid) - { - // ...TRUE through all ANDs means all TRUE - *mask_on = mask_and; - - // ...FALSE through all ORs means all FALSE - *mask_off = ~mask_or; - return TRUE; - } - else - { - *mask_on = 0; - *mask_off = 0; - return FALSE; - } -} - - - -BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm) -{ - BOOL first = TRUE; - LLPermissions perm; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } + U32 mask; + U32 mask_and = 0xffffffff; + U32 mask_or = 0x00000000; + BOOL all_valid = FALSE; - if (first) - { - perm = *(node->mPermissions); - first = FALSE; - } - else - { - perm.accumulate(*(node->mPermissions)); - } - } + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; - result_perm = perm; + if (!node->mValid) + { + all_valid = FALSE; + break; + } - return TRUE; -} + all_valid = TRUE; + switch( which_perm ) + { + case PERM_BASE: + mask = node->mPermissions->getMaskBase(); + break; + case PERM_OWNER: + mask = node->mPermissions->getMaskOwner(); + break; + case PERM_GROUP: + mask = node->mPermissions->getMaskGroup(); + break; + case PERM_EVERYONE: + mask = node->mPermissions->getMaskEveryone(); + break; + case PERM_NEXT_OWNER: + mask = node->mPermissions->getMaskNextOwner(); + break; + default: + mask = 0x0; + break; + } + mask_and &= mask; + mask_or |= mask; + } -void LLSelectMgr::selectDelete() -{ - S32 deleteable_count = 0; - - BOOL locked_but_deleteable_object = FALSE; - BOOL no_copy_but_deleteable_object = FALSE; - BOOL all_owned_by_you = TRUE; - - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++) - { - LLViewerObject* obj = (*iter)->getObject(); - - if( obj->isAttachment() ) - { - continue; - } - - deleteable_count++; - - // Check to see if you can delete objects which are locked. - if(!obj->permMove()) - { - locked_but_deleteable_object = TRUE; - } - if(!obj->permCopy()) - { - no_copy_but_deleteable_object = TRUE; - } - if(!obj->permYouOwner()) - { - all_owned_by_you = FALSE; - } - } - - if( 0 == deleteable_count ) - { - make_ui_sound("UISndInvalidOp"); - return; - } - - LLNotification::Params params("ConfirmObjectDeleteLock"); - params.functor.function(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection())); - - if(locked_but_deleteable_object || - no_copy_but_deleteable_object || - !all_owned_by_you) - { - // convert any transient pie-menu selections to full selection so this operation - // has some context - // NOTE: if user cancels delete operation, this will potentially leave objects selected outside of build mode - // but this is ok, if not ideal - convertTransient(); - - //This is messy, but needed to get all english our of the UI. - if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you) - { - //Locked only - params.name("ConfirmObjectDeleteLock"); - } - else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you) - { - //No Copy only - params.name("ConfirmObjectDeleteNoCopy"); - } - else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you) - { - //not owned only - params.name("ConfirmObjectDeleteNoOwn"); - } - else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you) - { - //locked and no copy - params.name("ConfirmObjectDeleteLockNoCopy"); - } - else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you) - { - //locked and not owned - params.name("ConfirmObjectDeleteLockNoOwn"); - } - else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you) - { - //no copy and not owned - params.name("ConfirmObjectDeleteNoCopyNoOwn"); - } - else - { - //locked, no copy and not owned - params.name("ConfirmObjectDeleteLockNoCopyNoOwn"); - } - - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } -} + if (all_valid) + { + // ...TRUE through all ANDs means all TRUE + *mask_on = mask_and; -// static -bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (!handle->getObjectCount()) - { - LL_WARNS() << "Nothing to delete!" << LL_ENDL; - return false; - } - - switch(option) - { - case 0: - { - // TODO: Make sure you have delete permissions on all of them. - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - // attempt to derez into the trash. - LLDeRezInfo info(DRD_TRASH, trash_id); - LLSelectMgr::getInstance()->sendListToRegions("DeRezObject", - packDeRezHeader, - packObjectLocalID, - logNoOp, - (void*) &info, - SEND_ONLY_ROOTS); - // VEFFECT: Delete Object - one effect for all deletes - if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD) - { - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); - effectp->setPositionGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal() ); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - F32 duration = 0.5f; - duration += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount() / 64.f; - effectp->setDuration(duration); - } - - gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); - - // Keep track of how many objects have been deleted. - add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); - } - break; - case 1: - default: - break; - } - return false; + // ...FALSE through all ORs means all FALSE + *mask_off = ~mask_or; + return TRUE; + } + else + { + *mask_on = 0; + *mask_off = 0; + return FALSE; + } } -void LLSelectMgr::selectForceDelete() -{ - sendListToRegions( - "ObjectDelete", - packDeleteHeader, - packObjectLocalID, - logNoOp, - (void*)TRUE, - SEND_ONLY_ROOTS); -} -BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify) +BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm) { - move = true; - modify = true; - bool selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - - for (LLObjectSelection::iterator iter = getSelection()->begin(); - iter != getSelection()->end(); iter++) + BOOL first = TRUE; + LLPermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - LLSelectNode* nodep = *iter; - LLViewerObject* object = nodep->getObject(); - if (!object || !nodep->mValid) + LLSelectNode* node = *iter; + if (!node->mValid) { - move = false; - modify = false; return FALSE; } - LLViewerObject *root_object = object->getRootEdit(); - bool this_object_movable = false; - if (object->permMove() && !object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (object->permModify() || selecting_linked_set)) + if (first) { - this_object_movable = true; + perm = *(node->mPermissions); + first = FALSE; + } + else + { + perm.accumulate(*(node->mPermissions)); } - move = move && this_object_movable; - modify = modify && object->permModify(); } + result_perm = perm; + return TRUE; } -void LLSelectMgr::selectGetAggregateSaleInfo(U32 &num_for_sale, - BOOL &is_for_sale_mixed, - BOOL &is_sale_price_mixed, - S32 &total_sale_price, - S32 &individual_sale_price) -{ - num_for_sale = 0; - is_for_sale_mixed = FALSE; - is_sale_price_mixed = FALSE; - total_sale_price = 0; - individual_sale_price = 0; - - - // Empty set. - if (getSelection()->root_begin() == getSelection()->root_end()) - return; - - LLSelectNode *node = *(getSelection()->root_begin()); - const BOOL first_node_for_sale = node->mSaleInfo.isForSale(); - const S32 first_node_sale_price = node->mSaleInfo.getSalePrice(); - - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - const BOOL node_for_sale = node->mSaleInfo.isForSale(); - const S32 node_sale_price = node->mSaleInfo.getSalePrice(); - - // Set mixed if the fields don't match the first node's fields. - if (node_for_sale != first_node_for_sale) - is_for_sale_mixed = TRUE; - if (node_sale_price != first_node_sale_price) - is_sale_price_mixed = TRUE; - - if (node_for_sale) - { - total_sale_price += node_sale_price; - num_for_sale ++; - } - } - - individual_sale_price = first_node_sale_price; - if (is_for_sale_mixed) - { - is_sale_price_mixed = TRUE; - individual_sale_price = 0; - } -} -// returns TRUE if all nodes are valid. method also stores an -// accumulated sale info. -BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info) +void LLSelectMgr::selectDelete() { - BOOL first = TRUE; - LLSaleInfo sale_info; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } - - if (first) - { - sale_info = node->mSaleInfo; - first = FALSE; - } - else - { - sale_info.accumulate(node->mSaleInfo); - } - } - - result_sale_info = sale_info; - - return TRUE; -} + S32 deleteable_count = 0; -BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm) -{ - BOOL first = TRUE; - LLAggregatePermissions perm; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } - - if (first) - { - perm = node->mAggregatePerm; - first = FALSE; - } - else - { - perm.aggregate(node->mAggregatePerm); - } - } - - result_perm = perm; - - return TRUE; + BOOL locked_but_deleteable_object = FALSE; + BOOL no_copy_but_deleteable_object = FALSE; + BOOL all_owned_by_you = TRUE; + + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) + { + LLViewerObject* obj = (*iter)->getObject(); + + if( obj->isAttachment() ) + { + continue; + } + + deleteable_count++; + + // Check to see if you can delete objects which are locked. + if(!obj->permMove()) + { + locked_but_deleteable_object = TRUE; + } + if(!obj->permCopy()) + { + no_copy_but_deleteable_object = TRUE; + } + if(!obj->permYouOwner()) + { + all_owned_by_you = FALSE; + } + } + + if( 0 == deleteable_count ) + { + make_ui_sound("UISndInvalidOp"); + return; + } + + LLNotification::Params params("ConfirmObjectDeleteLock"); + params.functor.function(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection())); + + if(locked_but_deleteable_object || + no_copy_but_deleteable_object || + !all_owned_by_you) + { + // convert any transient pie-menu selections to full selection so this operation + // has some context + // NOTE: if user cancels delete operation, this will potentially leave objects selected outside of build mode + // but this is ok, if not ideal + convertTransient(); + + //This is messy, but needed to get all english our of the UI. + if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you) + { + //Locked only + params.name("ConfirmObjectDeleteLock"); + } + else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you) + { + //No Copy only + params.name("ConfirmObjectDeleteNoCopy"); + } + else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you) + { + //not owned only + params.name("ConfirmObjectDeleteNoOwn"); + } + else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you) + { + //locked and no copy + params.name("ConfirmObjectDeleteLockNoCopy"); + } + else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you) + { + //locked and not owned + params.name("ConfirmObjectDeleteLockNoOwn"); + } + else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you) + { + //no copy and not owned + params.name("ConfirmObjectDeleteNoCopyNoOwn"); + } + else + { + //locked, no copy and not owned + params.name("ConfirmObjectDeleteLockNoCopyNoOwn"); + } + + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (!handle->getObjectCount()) + { + LL_WARNS() << "Nothing to delete!" << LL_ENDL; + return false; + } + + switch(option) + { + case 0: + { + // TODO: Make sure you have delete permissions on all of them. + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + // attempt to derez into the trash. + LLDeRezInfo info(DRD_TRASH, trash_id); + LLSelectMgr::getInstance()->sendListToRegions("DeRezObject", + packDeRezHeader, + packObjectLocalID, + logNoOp, + (void*) &info, + SEND_ONLY_ROOTS); + // VEFFECT: Delete Object - one effect for all deletes + if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD) + { + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); + effectp->setPositionGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal() ); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + F32 duration = 0.5f; + duration += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount() / 64.f; + effectp->setDuration(duration); + } + + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + + // Keep track of how many objects have been deleted. + add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); + } + break; + case 1: + default: + break; + } + return false; +} + + +void LLSelectMgr::selectForceDelete() +{ + sendListToRegions( + "ObjectDelete", + packDeleteHeader, + packObjectLocalID, + logNoOp, + (void*)TRUE, + SEND_ONLY_ROOTS); +} + +BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify) +{ + move = true; + modify = true; + bool selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) + { + LLSelectNode* nodep = *iter; + LLViewerObject* object = nodep->getObject(); + if (!object || !nodep->mValid) + { + move = false; + modify = false; + return FALSE; + } + + LLViewerObject *root_object = object->getRootEdit(); + bool this_object_movable = false; + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->permModify() || selecting_linked_set)) + { + this_object_movable = true; + } + move = move && this_object_movable; + modify = modify && object->permModify(); + } + + return TRUE; +} + +void LLSelectMgr::selectGetAggregateSaleInfo(U32 &num_for_sale, + BOOL &is_for_sale_mixed, + BOOL &is_sale_price_mixed, + S32 &total_sale_price, + S32 &individual_sale_price) +{ + num_for_sale = 0; + is_for_sale_mixed = FALSE; + is_sale_price_mixed = FALSE; + total_sale_price = 0; + individual_sale_price = 0; + + + // Empty set. + if (getSelection()->root_begin() == getSelection()->root_end()) + return; + + LLSelectNode *node = *(getSelection()->root_begin()); + const BOOL first_node_for_sale = node->mSaleInfo.isForSale(); + const S32 first_node_sale_price = node->mSaleInfo.getSalePrice(); + + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + const BOOL node_for_sale = node->mSaleInfo.isForSale(); + const S32 node_sale_price = node->mSaleInfo.getSalePrice(); + + // Set mixed if the fields don't match the first node's fields. + if (node_for_sale != first_node_for_sale) + is_for_sale_mixed = TRUE; + if (node_sale_price != first_node_sale_price) + is_sale_price_mixed = TRUE; + + if (node_for_sale) + { + total_sale_price += node_sale_price; + num_for_sale ++; + } + } + + individual_sale_price = first_node_sale_price; + if (is_for_sale_mixed) + { + is_sale_price_mixed = TRUE; + individual_sale_price = 0; + } +} + +// returns TRUE if all nodes are valid. method also stores an +// accumulated sale info. +BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info) +{ + BOOL first = TRUE; + LLSaleInfo sale_info; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + if (!node->mValid) + { + return FALSE; + } + + if (first) + { + sale_info = node->mSaleInfo; + first = FALSE; + } + else + { + sale_info.accumulate(node->mSaleInfo); + } + } + + result_sale_info = sale_info; + + return TRUE; +} + +BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm) +{ + BOOL first = TRUE; + LLAggregatePermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + if (!node->mValid) + { + return FALSE; + } + + if (first) + { + perm = node->mAggregatePerm; + first = FALSE; + } + else + { + perm.aggregate(node->mAggregatePerm); + } + } + + result_perm = perm; + + return TRUE; } BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& result_perm) { - BOOL first = TRUE; - LLAggregatePermissions perm; - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (!node->mValid) - { - return FALSE; - } - - LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm; - if (first) - { - perm = t_perm; - first = FALSE; - } - else - { - perm.aggregate(t_perm); - } - } - - result_perm = perm; - - return TRUE; + BOOL first = TRUE; + LLAggregatePermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + if (!node->mValid) + { + return FALSE; + } + + LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm; + if (first) + { + perm = t_perm; + first = FALSE; + } + else + { + perm.aggregate(t_perm); + } + } + + result_perm = perm; + + return TRUE; } BOOL LLSelectMgr::isMovableAvatarSelected() { - if (mAllowSelectAvatar && getSelection()->getObjectCount() == 1) - { + if (mAllowSelectAvatar && getSelection()->getObjectCount() == 1) + { // nothing but avatar should be selected, so check that // there is only one selected object and it is a root LLViewerObject* obj = getSelection()->getFirstRootObject(); - return obj && obj->isAvatar() && getSelection()->getFirstMoveableNode(TRUE); - } - return FALSE; + return obj && obj->isAvatar() && getSelection()->getFirstMoveableNode(TRUE); + } + return FALSE; } //-------------------------------------------------------------------- @@ -4341,119 +4341,119 @@ BOOL LLSelectMgr::isMovableAvatarSelected() // messages. struct LLDuplicateData { - LLVector3 offset; - U32 flags; + LLVector3 offset; + U32 flags; }; void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy) { - if (mSelectedObjects->isAttachment()) - { - //RN: do not duplicate attachments - make_ui_sound("UISndInvalidOp"); - return; - } - if (!canDuplicate()) - { - LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true); - if (node) - { - LLSD args; - args["OBJ_NAME"] = node->mName; - LLNotificationsUtil::add("NoCopyPermsNoObject", args); - return; - } - } - LLDuplicateData data; - - data.offset = offset; - data.flags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0); - - sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS); - - if (select_copy) - { - // the new copy will be coming in selected - deselectAll(); - } - else - { - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - node->mDuplicated = TRUE; - node->mDuplicatePos = node->getObject()->getPositionGlobal(); - node->mDuplicateRot = node->getObject()->getRotation(); - } - } + if (mSelectedObjects->isAttachment()) + { + //RN: do not duplicate attachments + make_ui_sound("UISndInvalidOp"); + return; + } + if (!canDuplicate()) + { + LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true); + if (node) + { + LLSD args; + args["OBJ_NAME"] = node->mName; + LLNotificationsUtil::add("NoCopyPermsNoObject", args); + return; + } + } + LLDuplicateData data; + + data.offset = offset; + data.flags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0); + + sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS); + + if (select_copy) + { + // the new copy will be coming in selected + deselectAll(); + } + else + { + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + node->mDuplicated = TRUE; + node->mDuplicatePos = node->getObject()->getPositionGlobal(); + node->mDuplicateRot = node->getObject()->getRotation(); + } + } } void LLSelectMgr::repeatDuplicate() { - if (mSelectedObjects->isAttachment()) - { - //RN: do not duplicate attachments - make_ui_sound("UISndInvalidOp"); - return; - } - - std::vector non_duplicated_objects; - - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (!node->mDuplicated) - { - non_duplicated_objects.push_back(node->getObject()); - } - } - - // make sure only previously duplicated objects are selected - for (std::vector::iterator iter = non_duplicated_objects.begin(); - iter != non_duplicated_objects.end(); ++iter) - { - LLViewerObject* objectp = *iter; - deselectObjectAndFamily(objectp); - } - - // duplicate objects in place - LLDuplicateData data; - - data.offset = LLVector3::zero; - data.flags = 0x0; - - sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS); - - // move current selection based on delta from duplication position and update duplication position - for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); - iter != getSelection()->root_end(); iter++ ) - { - LLSelectNode* node = *iter; - if (node->mDuplicated) - { - LLQuaternion cur_rot = node->getObject()->getRotation(); - LLQuaternion rot_delta = (~node->mDuplicateRot * cur_rot); - LLQuaternion new_rot = cur_rot * rot_delta; - LLVector3d cur_pos = node->getObject()->getPositionGlobal(); - LLVector3d new_pos = cur_pos + ((cur_pos - node->mDuplicatePos) * rot_delta); - - node->mDuplicatePos = node->getObject()->getPositionGlobal(); - node->mDuplicateRot = node->getObject()->getRotation(); - node->getObject()->setPositionGlobal(new_pos); - node->getObject()->setRotation(new_rot); - } - } - - sendMultipleUpdate(UPD_ROTATION | UPD_POSITION); -} - -// static + if (mSelectedObjects->isAttachment()) + { + //RN: do not duplicate attachments + make_ui_sound("UISndInvalidOp"); + return; + } + + std::vector non_duplicated_objects; + + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + if (!node->mDuplicated) + { + non_duplicated_objects.push_back(node->getObject()); + } + } + + // make sure only previously duplicated objects are selected + for (std::vector::iterator iter = non_duplicated_objects.begin(); + iter != non_duplicated_objects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + deselectObjectAndFamily(objectp); + } + + // duplicate objects in place + LLDuplicateData data; + + data.offset = LLVector3::zero; + data.flags = 0x0; + + sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS); + + // move current selection based on delta from duplication position and update duplication position + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) + { + LLSelectNode* node = *iter; + if (node->mDuplicated) + { + LLQuaternion cur_rot = node->getObject()->getRotation(); + LLQuaternion rot_delta = (~node->mDuplicateRot * cur_rot); + LLQuaternion new_rot = cur_rot * rot_delta; + LLVector3d cur_pos = node->getObject()->getPositionGlobal(); + LLVector3d new_pos = cur_pos + ((cur_pos - node->mDuplicatePos) * rot_delta); + + node->mDuplicatePos = node->getObject()->getPositionGlobal(); + node->mDuplicateRot = node->getObject()->getRotation(); + node->getObject()->setPositionGlobal(new_pos); + node->getObject()->setRotation(new_rot); + } + } + + sendMultipleUpdate(UPD_ROTATION | UPD_POSITION); +} + +// static void LLSelectMgr::packDuplicate( LLSelectNode* node, void *duplicate_data ) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); } @@ -4465,71 +4465,71 @@ void LLSelectMgr::packDuplicate( LLSelectNode* node, void *duplicate_data ) // ray. struct LLDuplicateOnRayData { - LLVector3 mRayStartRegion; - LLVector3 mRayEndRegion; - BOOL mBypassRaycast; - BOOL mRayEndIsIntersection; - LLUUID mRayTargetID; - BOOL mCopyCenters; - BOOL mCopyRotates; - U32 mFlags; + LLVector3 mRayStartRegion; + LLVector3 mRayEndRegion; + BOOL mBypassRaycast; + BOOL mRayEndIsIntersection; + LLUUID mRayTargetID; + BOOL mCopyCenters; + BOOL mCopyRotates; + U32 mFlags; }; void LLSelectMgr::selectDuplicateOnRay(const LLVector3 &ray_start_region, - const LLVector3 &ray_end_region, - BOOL bypass_raycast, - BOOL ray_end_is_intersection, - const LLUUID &ray_target_id, - BOOL copy_centers, - BOOL copy_rotates, - BOOL select_copy) -{ - if (mSelectedObjects->isAttachment()) - { - // do not duplicate attachments - make_ui_sound("UISndInvalidOp"); - return; - } - - LLDuplicateOnRayData data; - - data.mRayStartRegion = ray_start_region; - data.mRayEndRegion = ray_end_region; - data.mBypassRaycast = bypass_raycast; - data.mRayEndIsIntersection = ray_end_is_intersection; - data.mRayTargetID = ray_target_id; - data.mCopyCenters = copy_centers; - data.mCopyRotates = copy_rotates; - data.mFlags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0); - - sendListToRegions("ObjectDuplicateOnRay", + const LLVector3 &ray_end_region, + BOOL bypass_raycast, + BOOL ray_end_is_intersection, + const LLUUID &ray_target_id, + BOOL copy_centers, + BOOL copy_rotates, + BOOL select_copy) +{ + if (mSelectedObjects->isAttachment()) + { + // do not duplicate attachments + make_ui_sound("UISndInvalidOp"); + return; + } + + LLDuplicateOnRayData data; + + data.mRayStartRegion = ray_start_region; + data.mRayEndRegion = ray_end_region; + data.mBypassRaycast = bypass_raycast; + data.mRayEndIsIntersection = ray_end_is_intersection; + data.mRayTargetID = ray_target_id; + data.mCopyCenters = copy_centers; + data.mCopyRotates = copy_rotates; + data.mFlags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0); + + sendListToRegions("ObjectDuplicateOnRay", packDuplicateOnRayHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS); - if (select_copy) - { - // the new copy will be coming in selected - deselectAll(); - } + if (select_copy) + { + // the new copy will be coming in selected + deselectAll(); + } } // static void LLSelectMgr::packDuplicateOnRayHead(void *user_data) { - LLMessageSystem *msg = gMessageSystem; - LLDuplicateOnRayData *data = (LLDuplicateOnRayData *)user_data; + LLMessageSystem *msg = gMessageSystem; + LLDuplicateOnRayData *data = (LLDuplicateOnRayData *)user_data; - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() ); - msg->addVector3Fast(_PREHASH_RayStart, data->mRayStartRegion ); - msg->addVector3Fast(_PREHASH_RayEnd, data->mRayEndRegion ); - msg->addBOOLFast(_PREHASH_BypassRaycast, data->mBypassRaycast ); - msg->addBOOLFast(_PREHASH_RayEndIsIntersection, data->mRayEndIsIntersection ); - msg->addBOOLFast(_PREHASH_CopyCenters, data->mCopyCenters ); - msg->addBOOLFast(_PREHASH_CopyRotates, data->mCopyRotates ); - msg->addUUIDFast(_PREHASH_RayTargetID, data->mRayTargetID ); - msg->addU32Fast(_PREHASH_DuplicateFlags, data->mFlags ); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() ); + msg->addVector3Fast(_PREHASH_RayStart, data->mRayStartRegion ); + msg->addVector3Fast(_PREHASH_RayEnd, data->mRayEndRegion ); + msg->addBOOLFast(_PREHASH_BypassRaycast, data->mBypassRaycast ); + msg->addBOOLFast(_PREHASH_RayEndIsIntersection, data->mRayEndIsIntersection ); + msg->addBOOLFast(_PREHASH_CopyCenters, data->mCopyCenters ); + msg->addBOOLFast(_PREHASH_CopyRotates, data->mCopyRotates ); + msg->addUUIDFast(_PREHASH_RayTargetID, data->mRayTargetID ); + msg->addU32Fast(_PREHASH_DuplicateFlags, data->mFlags ); } @@ -4540,61 +4540,61 @@ void LLSelectMgr::packDuplicateOnRayHead(void *user_data) void LLSelectMgr::sendMultipleUpdate(U32 type) { - if (type == UPD_NONE) return; - // send individual updates when selecting textures or individual objects - ESendType send_type = (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) ? SEND_ONLY_ROOTS : SEND_ROOTS_FIRST; - if (send_type == SEND_ONLY_ROOTS) - { - // tell simulator to apply to whole linked sets - type |= UPD_LINKED_SETS; - } - - sendListToRegions( - "MultipleObjectUpdate", - packAgentAndSessionID, - packMultipleUpdate, + if (type == UPD_NONE) return; + // send individual updates when selecting textures or individual objects + ESendType send_type = (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) ? SEND_ONLY_ROOTS : SEND_ROOTS_FIRST; + if (send_type == SEND_ONLY_ROOTS) + { + // tell simulator to apply to whole linked sets + type |= UPD_LINKED_SETS; + } + + sendListToRegions( + "MultipleObjectUpdate", + packAgentAndSessionID, + packMultipleUpdate, logNoOp, - &type, - send_type); + &type, + send_type); } // static void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data) { - LLViewerObject* object = node->getObject(); - U32 *type32 = (U32 *)user_data; - U8 type = (U8)*type32; - U8 data[256]; - - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); - gMessageSystem->addU8Fast(_PREHASH_Type, type ); - - S32 offset = 0; - - // JC: You MUST pack the data in this order. The receiving - // routine process_multiple_update_message on simulator will - // extract them in this order. - - if (type & UPD_POSITION) - { - htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12); - offset += 12; - } - if (type & UPD_ROTATION) - { - LLQuaternion quat = object->getRotation(); - LLVector3 vec = quat.packToVector3(); - htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12); - offset += 12; - } - if (type & UPD_SCALE) - { - //LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL; - htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12); - offset += 12; - } - gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); + LLViewerObject* object = node->getObject(); + U32 *type32 = (U32 *)user_data; + U8 type = (U8)*type32; + U8 data[256]; + + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); + gMessageSystem->addU8Fast(_PREHASH_Type, type ); + + S32 offset = 0; + + // JC: You MUST pack the data in this order. The receiving + // routine process_multiple_update_message on simulator will + // extract them in this order. + + if (type & UPD_POSITION) + { + htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12); + offset += 12; + } + if (type & UPD_ROTATION) + { + LLQuaternion quat = object->getRotation(); + LLVector3 vec = quat.packToVector3(); + htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12); + offset += 12; + } + if (type & UPD_SCALE) + { + //LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL; + htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12); + offset += 12; + } + gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); } //------------------------------------------------------------------------ @@ -4602,36 +4602,36 @@ void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data) //------------------------------------------------------------------------ struct LLOwnerData { - LLUUID owner_id; - LLUUID group_id; - BOOL override; + LLUUID owner_id; + LLUUID group_id; + BOOL override; }; void LLSelectMgr::sendOwner(const LLUUID& owner_id, - const LLUUID& group_id, - BOOL override) + const LLUUID& group_id, + BOOL override) { - LLOwnerData data; + LLOwnerData data; - data.owner_id = owner_id; - data.group_id = group_id; - data.override = override; + data.owner_id = owner_id; + data.group_id = group_id; + data.override = override; - sendListToRegions("ObjectOwner", packOwnerHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS); + sendListToRegions("ObjectOwner", packOwnerHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS); } // static void LLSelectMgr::packOwnerHead(void *user_data) { - LLOwnerData *data = (LLOwnerData *)user_data; + LLOwnerData *data = (LLOwnerData *)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - gMessageSystem->nextBlockFast(_PREHASH_HeaderData); - gMessageSystem->addBOOLFast(_PREHASH_Override, data->override); - gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + gMessageSystem->nextBlockFast(_PREHASH_HeaderData); + gMessageSystem->addBOOLFast(_PREHASH_Override, data->override); + gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id); } //------------------------------------------------------------------------ @@ -4640,8 +4640,8 @@ void LLSelectMgr::packOwnerHead(void *user_data) void LLSelectMgr::sendGroup(const LLUUID& group_id) { - LLUUID local_group_id(group_id); - sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, logNoOp, &local_group_id, SEND_ONLY_ROOTS); + LLUUID local_group_id(group_id); + sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, logNoOp, &local_group_id, SEND_ONLY_ROOTS); } @@ -4651,9 +4651,9 @@ void LLSelectMgr::sendGroup(const LLUUID& group_id) struct LLBuyData { - std::vector mObjectsSent; - LLUUID mCategoryID; - LLSaleInfo mSaleInfo; + std::vector mObjectsSent; + LLUUID mCategoryID; + LLSaleInfo mSaleInfo; }; // *NOTE: does not work for multiple object buy, which UI does not @@ -4662,26 +4662,26 @@ struct LLBuyData // info -as displayed in the UI- for every item. void LLSelectMgr::sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info) { - LLBuyData buy; - buy.mCategoryID = category_id; - buy.mSaleInfo = sale_info; - sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, logNoOp, &buy, SEND_ONLY_ROOTS); + LLBuyData buy; + buy.mCategoryID = category_id; + buy.mSaleInfo = sale_info; + sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, logNoOp, &buy, SEND_ONLY_ROOTS); } // static void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data) { - LLBuyData* buy = (LLBuyData*)data; + LLBuyData* buy = (LLBuyData*)data; - LLViewerObject* object = node->getObject(); - if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end()) - { - buy->mObjectsSent.push_back(object); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); - gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType()); - gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice()); - } + LLViewerObject* object = node->getObject(); + if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end()) + { + buy->mObjectsSent.push_back(object); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); + gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType()); + gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice()); + } } //------------------------------------------------------------------------ @@ -4690,37 +4690,37 @@ void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data) struct LLPermData { - U8 mField; - BOOL mSet; - U32 mMask; - BOOL mOverride; + U8 mField; + BOOL mSet; + U32 mMask; + BOOL mOverride; }; // TODO: Make this able to fail elegantly. void LLSelectMgr::selectionSetObjectPermissions(U8 field, - BOOL set, - U32 mask, - BOOL override) + BOOL set, + U32 mask, + BOOL override) { - LLPermData data; + LLPermData data; - data.mField = field; - data.mSet = set; - data.mMask = mask; - data.mOverride = override; + data.mField = field; + data.mSet = set; + data.mMask = mask; + data.mOverride = override; - sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, logNoOp, &data, SEND_ONLY_ROOTS); + sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, logNoOp, &data, SEND_ONLY_ROOTS); } void LLSelectMgr::packPermissionsHead(void* user_data) { - LLPermData* data = (LLPermData*)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_HeaderData); - gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride); -} + LLPermData* data = (LLPermData*)user_data; + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_HeaderData); + gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride); +} // Now that you've added a bunch of objects, send a select message @@ -4728,204 +4728,204 @@ void LLSelectMgr::packPermissionsHead(void* user_data) /* void LLSelectMgr::sendSelect() { - LL_ERRS() << "Not implemented" << LL_ENDL; + LL_ERRS() << "Not implemented" << LL_ENDL; } */ void LLSelectMgr::deselectAll() { - if (!mSelectedObjects->getNumNodes()) - { - return; - } - - // Zap the angular velocity, as the sim will set it to zero - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); - iter != mSelectedObjects->end(); iter++ ) - { - LLViewerObject *objectp = (*iter)->getObject(); - objectp->setAngularVelocity( 0,0,0 ); - objectp->setVelocity( 0,0,0 ); - } - - sendListToRegions( - "ObjectDeselect", - packAgentAndSessionID, - packObjectLocalID, - logNoOp, - NULL, - SEND_INDIVIDUALS); + if (!mSelectedObjects->getNumNodes()) + { + return; + } + + // Zap the angular velocity, as the sim will set it to zero + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) + { + LLViewerObject *objectp = (*iter)->getObject(); + objectp->setAngularVelocity( 0,0,0 ); + objectp->setVelocity( 0,0,0 ); + } + + sendListToRegions( + "ObjectDeselect", + packAgentAndSessionID, + packObjectLocalID, + logNoOp, + NULL, + SEND_INDIVIDUALS); + + removeAll(); - removeAll(); - - mLastSentSelectionCenterGlobal.clearVec(); + mLastSentSelectionCenterGlobal.clearVec(); - updatePointAt(); + updatePointAt(); } void LLSelectMgr::deselectAllForStandingUp() { - /* - This function is similar deselectAll() except for the first if statement - which was removed. This is needed as a workaround for DEV-2854 - */ - - // Zap the angular velocity, as the sim will set it to zero - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); - iter != mSelectedObjects->end(); iter++ ) - { - LLViewerObject *objectp = (*iter)->getObject(); - objectp->setAngularVelocity( 0,0,0 ); - objectp->setVelocity( 0,0,0 ); - } - - sendListToRegions( - "ObjectDeselect", - packAgentAndSessionID, - packObjectLocalID, + /* + This function is similar deselectAll() except for the first if statement + which was removed. This is needed as a workaround for DEV-2854 + */ + + // Zap the angular velocity, as the sim will set it to zero + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) + { + LLViewerObject *objectp = (*iter)->getObject(); + objectp->setAngularVelocity( 0,0,0 ); + objectp->setVelocity( 0,0,0 ); + } + + sendListToRegions( + "ObjectDeselect", + packAgentAndSessionID, + packObjectLocalID, logNoOp, - NULL, - SEND_INDIVIDUALS); + NULL, + SEND_INDIVIDUALS); + + removeAll(); - removeAll(); - - mLastSentSelectionCenterGlobal.clearVec(); + mLastSentSelectionCenterGlobal.clearVec(); - updatePointAt(); + updatePointAt(); } void LLSelectMgr::deselectUnused() { - // no more outstanding references to this selection - if (mSelectedObjects->getNumRefs() == 1) - { - deselectAll(); - } + // no more outstanding references to this selection + if (mSelectedObjects->getNumRefs() == 1) + { + deselectAll(); + } } void LLSelectMgr::convertTransient() { - LLObjectSelection::iterator node_it; - for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it) - { - LLSelectNode *nodep = *node_it; - nodep->setTransient(FALSE); - } + LLObjectSelection::iterator node_it; + for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it) + { + LLSelectNode *nodep = *node_it; + nodep->setTransient(FALSE); + } } void LLSelectMgr::deselectAllIfTooFar() { - if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD) - { - return; - } - - // HACK: Don't deselect when we're navigating to rate an object's - // owner or creator. JC - if (gMenuObject->getVisible()) - { - return; - } - - LLVector3d selectionCenter = getSelectionCenterGlobal(); - if (gSavedSettings.getBOOL("LimitSelectDistance") - && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar()) - && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject()) - && !mSelectedObjects->isAttachment() - && !selectionCenter.isExactlyZero()) - { - F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance"); - F32 deselect_dist_sq = deselect_dist * deselect_dist; - - LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter; - F32 select_dist_sq = (F32) select_delta.magVecSquared(); - - if (select_dist_sq > deselect_dist_sq) - { - if (mDebugSelectMgr) - { - LL_INFOS() << "Selection manager: auto-deselecting, select_dist = " << (F32) sqrt(select_dist_sq) << LL_ENDL; - LL_INFOS() << "agent pos global = " << gAgent.getPositionGlobal() << LL_ENDL; - LL_INFOS() << "selection pos global = " << selectionCenter << LL_ENDL; - } - - deselectAll(); - } - } + if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD) + { + return; + } + + // HACK: Don't deselect when we're navigating to rate an object's + // owner or creator. JC + if (gMenuObject->getVisible()) + { + return; + } + + LLVector3d selectionCenter = getSelectionCenterGlobal(); + if (gSavedSettings.getBOOL("LimitSelectDistance") + && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar()) + && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject()) + && !mSelectedObjects->isAttachment() + && !selectionCenter.isExactlyZero()) + { + F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance"); + F32 deselect_dist_sq = deselect_dist * deselect_dist; + + LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter; + F32 select_dist_sq = (F32) select_delta.magVecSquared(); + + if (select_dist_sq > deselect_dist_sq) + { + if (mDebugSelectMgr) + { + LL_INFOS() << "Selection manager: auto-deselecting, select_dist = " << (F32) sqrt(select_dist_sq) << LL_ENDL; + LL_INFOS() << "agent pos global = " << gAgent.getPositionGlobal() << LL_ENDL; + LL_INFOS() << "selection pos global = " << selectionCenter << LL_ENDL; + } + + deselectAll(); + } + } } void LLSelectMgr::selectionSetObjectName(const std::string& name) { - std::string name_copy(name); + std::string name_copy(name); - // we only work correctly if 1 object is selected. - if(mSelectedObjects->getRootObjectCount() == 1) - { - sendListToRegions("ObjectName", - packAgentAndSessionID, - packObjectName, + // we only work correctly if 1 object is selected. + if(mSelectedObjects->getRootObjectCount() == 1) + { + sendListToRegions("ObjectName", + packAgentAndSessionID, + packObjectName, logNoOp, - (void*)(&name_copy), - SEND_ONLY_ROOTS); - } - else if(mSelectedObjects->getObjectCount() == 1) - { - sendListToRegions("ObjectName", - packAgentAndSessionID, - packObjectName, + (void*)(&name_copy), + SEND_ONLY_ROOTS); + } + else if(mSelectedObjects->getObjectCount() == 1) + { + sendListToRegions("ObjectName", + packAgentAndSessionID, + packObjectName, logNoOp, - (void*)(&name_copy), - SEND_INDIVIDUALS); - } + (void*)(&name_copy), + SEND_INDIVIDUALS); + } } void LLSelectMgr::selectionSetObjectDescription(const std::string& desc) { - std::string desc_copy(desc); + std::string desc_copy(desc); - // we only work correctly if 1 object is selected. - if(mSelectedObjects->getRootObjectCount() == 1) - { - sendListToRegions("ObjectDescription", - packAgentAndSessionID, - packObjectDescription, + // we only work correctly if 1 object is selected. + if(mSelectedObjects->getRootObjectCount() == 1) + { + sendListToRegions("ObjectDescription", + packAgentAndSessionID, + packObjectDescription, logNoOp, - (void*)(&desc_copy), - SEND_ONLY_ROOTS); - } - else if(mSelectedObjects->getObjectCount() == 1) - { - sendListToRegions("ObjectDescription", - packAgentAndSessionID, - packObjectDescription, + (void*)(&desc_copy), + SEND_ONLY_ROOTS); + } + else if(mSelectedObjects->getObjectCount() == 1) + { + sendListToRegions("ObjectDescription", + packAgentAndSessionID, + packObjectDescription, logNoOp, - (void*)(&desc_copy), - SEND_INDIVIDUALS); - } + (void*)(&desc_copy), + SEND_INDIVIDUALS); + } } void LLSelectMgr::selectionSetObjectCategory(const LLCategory& category) { - // for now, we only want to be able to set one root category at - // a time. - if(mSelectedObjects->getRootObjectCount() != 1) return; - sendListToRegions("ObjectCategory", - packAgentAndSessionID, - packObjectCategory, + // for now, we only want to be able to set one root category at + // a time. + if(mSelectedObjects->getRootObjectCount() != 1) return; + sendListToRegions("ObjectCategory", + packAgentAndSessionID, + packObjectCategory, logNoOp, - (void*)(&category), - SEND_ONLY_ROOTS); + (void*)(&category), + SEND_ONLY_ROOTS); } void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info) { - sendListToRegions("ObjectSaleInfo", - packAgentAndSessionID, - packObjectSaleInfo, + sendListToRegions("ObjectSaleInfo", + packAgentAndSessionID, + packObjectSaleInfo, logNoOp, - (void*)(&sale_info), - SEND_ONLY_ROOTS); + (void*)(&sale_info), + SEND_ONLY_ROOTS); } //---------------------------------------------------------------------- @@ -4939,80 +4939,80 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace) void LLSelectMgr::sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace) { - if (selection_handle.isNull()) - { - return; - } - - LLViewerObject* attach_object = selection_handle->getFirstRootObject(); - - if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD) - { - return; - } - - BOOL build_mode = LLToolMgr::getInstance()->inEdit(); - // Special case: Attach to default location for this object. - if (0 == attachment_point || - get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) - { - if (!replace || attachment_point != 0) - { - // If we know the attachment point then we got here by clicking an - // "Attach to..." context menu item, so we should add, not replace. - attachment_point |= ATTACHMENT_ADD; - } - - sendListToRegions( - selection_handle, - "ObjectAttach", - packAgentIDAndSessionAndAttachment, - packObjectIDAndRotation, + if (selection_handle.isNull()) + { + return; + } + + LLViewerObject* attach_object = selection_handle->getFirstRootObject(); + + if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD) + { + return; + } + + BOOL build_mode = LLToolMgr::getInstance()->inEdit(); + // Special case: Attach to default location for this object. + if (0 == attachment_point || + get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) + { + if (!replace || attachment_point != 0) + { + // If we know the attachment point then we got here by clicking an + // "Attach to..." context menu item, so we should add, not replace. + attachment_point |= ATTACHMENT_ADD; + } + + sendListToRegions( + selection_handle, + "ObjectAttach", + packAgentIDAndSessionAndAttachment, + packObjectIDAndRotation, logAttachmentRequest, - &attachment_point, - SEND_ONLY_ROOTS ); - if (!build_mode) - { - // After "ObjectAttach" server will unsubscribe us from properties updates - // so either deselect objects or resend selection after attach packet reaches server - // In case of build_mode LLPanelObjectInventory::refresh() will deal with selection - // Still unsubscribe even in case selection_handle is not current selection - deselectAll(); - } - } + &attachment_point, + SEND_ONLY_ROOTS ); + if (!build_mode) + { + // After "ObjectAttach" server will unsubscribe us from properties updates + // so either deselect objects or resend selection after attach packet reaches server + // In case of build_mode LLPanelObjectInventory::refresh() will deal with selection + // Still unsubscribe even in case selection_handle is not current selection + deselectAll(); + } + } } void LLSelectMgr::sendDetach() { - if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD) - { - return; - } + if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD) + { + return; + } - sendListToRegions( - "ObjectDetach", - packAgentAndSessionID, - packObjectLocalID, + sendListToRegions( + "ObjectDetach", + packAgentAndSessionID, + packObjectLocalID, logDetachRequest, - NULL, - SEND_ONLY_ROOTS ); + NULL, + SEND_ONLY_ROOTS ); } void LLSelectMgr::sendDropAttachment() { - if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD) - { - return; - } + if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD) + { + return; + } - sendListToRegions( - "ObjectDrop", - packAgentAndSessionID, - packObjectLocalID, + sendListToRegions( + "ObjectDrop", + packAgentAndSessionID, + packObjectLocalID, logDetachRequest, - NULL, - SEND_ONLY_ROOTS); + NULL, + SEND_ONLY_ROOTS); } //---------------------------------------------------------------------- @@ -5021,56 +5021,56 @@ void LLSelectMgr::sendDropAttachment() void LLSelectMgr::sendLink() { - if (!mSelectedObjects->getNumNodes()) - { - return; - } + if (!mSelectedObjects->getNumNodes()) + { + return; + } - sendListToRegions( - "ObjectLink", - packAgentAndSessionID, - packObjectLocalID, + sendListToRegions( + "ObjectLink", + packAgentAndSessionID, + packObjectLocalID, logNoOp, - NULL, - SEND_ONLY_ROOTS); + NULL, + SEND_ONLY_ROOTS); } void LLSelectMgr::sendDelink() { - if (!mSelectedObjects->getNumNodes()) - { - return; - } - - struct f : public LLSelectedObjectFunctor - { //on delink, any modifyable object should - f() {} - - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - if (object->getPhysicsShapeType() == LLViewerObject::PHYSICS_SHAPE_NONE) - { - object->setPhysicsShapeType(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); - object->updateFlags(); - } - } - return true; - } - } sendfunc; - getSelection()->applyToObjects(&sendfunc); - - - // Delink needs to send individuals so you can unlink a single object from - // a linked set. - sendListToRegions( - "ObjectDelink", - packAgentAndSessionID, - packObjectLocalID, + if (!mSelectedObjects->getNumNodes()) + { + return; + } + + struct f : public LLSelectedObjectFunctor + { //on delink, any modifyable object should + f() {} + + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + if (object->getPhysicsShapeType() == LLViewerObject::PHYSICS_SHAPE_NONE) + { + object->setPhysicsShapeType(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + object->updateFlags(); + } + } + return true; + } + } sendfunc; + getSelection()->applyToObjects(&sendfunc); + + + // Delink needs to send individuals so you can unlink a single object from + // a linked set. + sendListToRegions( + "ObjectDelink", + packAgentAndSessionID, + packObjectLocalID, logNoOp, - NULL, - SEND_INDIVIDUALS); + NULL, + SEND_INDIVIDUALS); } @@ -5081,118 +5081,118 @@ void LLSelectMgr::sendDelink() /* void LLSelectMgr::sendHinge(U8 type) { - if (!mSelectedObjects->getNumNodes()) - { - return; - } + if (!mSelectedObjects->getNumNodes()) + { + return; + } - sendListToRegions( - "ObjectHinge", - packHingeHead, - packObjectLocalID, - &type, - SEND_ONLY_ROOTS); + sendListToRegions( + "ObjectHinge", + packHingeHead, + packObjectLocalID, + &type, + SEND_ONLY_ROOTS); } void LLSelectMgr::sendDehinge() { - if (!mSelectedObjects->getNumNodes()) - { - return; - } - - sendListToRegions( - "ObjectDehinge", - packAgentAndSessionID, - packObjectLocalID, - NULL, - SEND_ONLY_ROOTS); + if (!mSelectedObjects->getNumNodes()) + { + return; + } + + sendListToRegions( + "ObjectDehinge", + packAgentAndSessionID, + packObjectLocalID, + NULL, + SEND_ONLY_ROOTS); }*/ void LLSelectMgr::sendSelect() { - if (!mSelectedObjects->getNumNodes()) - { - return; - } + if (!mSelectedObjects->getNumNodes()) + { + return; + } - sendListToRegions( - "ObjectSelect", - packAgentAndSessionID, - packObjectLocalID, + sendListToRegions( + "ObjectSelect", + packAgentAndSessionID, + packObjectLocalID, logNoOp, - NULL, - SEND_INDIVIDUALS); + NULL, + SEND_INDIVIDUALS); } // static void LLSelectMgr::packHingeHead(void *user_data) { - U8 *type = (U8 *)user_data; + U8 *type = (U8 *)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - gMessageSystem->nextBlockFast(_PREHASH_JointType); - gMessageSystem->addU8Fast(_PREHASH_Type, *type ); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + gMessageSystem->nextBlockFast(_PREHASH_JointType); + gMessageSystem->addU8Fast(_PREHASH_Type, *type ); } void LLSelectMgr::selectionDump() { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - object->dump(); - return true; - } - } func; - getSelection()->applyToObjects(&func); + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + object->dump(); + return true; + } + } func; + getSelection()->applyToObjects(&func); } void LLSelectMgr::saveSelectedObjectColors() { - struct f : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* node) - { - node->saveColors(); - return true; - } - } func; - getSelection()->applyToNodes(&func); + struct f : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + node->saveColors(); + return true; + } + } func; + getSelection()->applyToNodes(&func); } void LLSelectMgr::saveSelectedShinyColors() { - struct f : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* node) - { - node->saveShinyColors(); - return true; - } - } func; - getSelection()->applyToNodes(&func); + struct f : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + node->saveShinyColors(); + return true; + } + } func; + getSelection()->applyToNodes(&func); } void LLSelectMgr::saveSelectedObjectTextures() { - // invalidate current selection so we update saved textures - struct f : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* node) - { - node->mValid = FALSE; - return true; - } - } func; - getSelection()->applyToNodes(&func); + // invalidate current selection so we update saved textures + struct f : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + node->mValid = FALSE; + return true; + } + } func; + getSelection()->applyToNodes(&func); - // request object properties message to get updated permissions data - sendSelect(); + // request object properties message to get updated permissions data + sendSelect(); } @@ -5200,24 +5200,24 @@ void LLSelectMgr::saveSelectedObjectTextures() // also need to know to which simulator to send update message void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) { - if (mSelectedObjects->isEmpty()) - { - // nothing selected, so nothing to save - return; - } - - struct f : public LLSelectedNodeFunctor - { - EActionType mActionType; - LLSelectMgr* mManager; - f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {} - virtual bool apply(LLSelectNode* selectNode) - { - LLViewerObject* object = selectNode->getObject(); - if (!object) - { - return true; // skip - } + if (mSelectedObjects->isEmpty()) + { + // nothing selected, so nothing to save + return; + } + + struct f : public LLSelectedNodeFunctor + { + EActionType mActionType; + LLSelectMgr* mManager; + f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {} + virtual bool apply(LLSelectNode* selectNode) + { + LLViewerObject* object = selectNode->getObject(); + if (!object) + { + return true; // skip + } if (selectNode->mSelectedGLTFNode != -1) { @@ -5269,235 +5269,235 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) selectNode->mSavedScale = object->getScale(); selectNode->saveTextureScaleRatios(mManager->mTextureChannel); } - return true; - } - } func(action_type, this); - getSelection()->applyToNodes(&func); - - mSavedSelectionBBox = getBBoxOfSelection(); + return true; + } + } func(action_type, this); + getSelection()->applyToNodes(&func); + + mSavedSelectionBBox = getBBoxOfSelection(); } struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor { - LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {} - U32 mFlags; - BOOL mState; - virtual bool apply(LLViewerObject* object) - { - if ( object->permModify()) - { - if (object->isRoot()) // don't send for child objects - { - object->setFlags( mFlags, mState); - } - else if (FLAGS_WORLD & mFlags && ((LLViewerObject*)object->getRoot())->isSelected()) - { - // FLAGS_WORLD are shared by all items in linkset - object->setFlagsWithoutUpdate(FLAGS_WORLD & mFlags, mState); - } - }; - return true; - } + LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {} + U32 mFlags; + BOOL mState; + virtual bool apply(LLViewerObject* object) + { + if ( object->permModify()) + { + if (object->isRoot()) // don't send for child objects + { + object->setFlags( mFlags, mState); + } + else if (FLAGS_WORLD & mFlags && ((LLViewerObject*)object->getRoot())->isSelected()) + { + // FLAGS_WORLD are shared by all items in linkset + object->setFlagsWithoutUpdate(FLAGS_WORLD & mFlags, mState); + } + }; + return true; + } }; void LLSelectMgr::selectionUpdatePhysics(BOOL physics) { - LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics); - getSelection()->applyToObjects(&func); + LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics); + getSelection()->applyToObjects(&func); } void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary) { - LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary); - getSelection()->applyToObjects(&func); + LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary); + getSelection()->applyToObjects(&func); } void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom) { - LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom); - getSelection()->applyToObjects(&func); + LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom); + getSelection()->applyToObjects(&func); } //---------------------------------------------------------------------- // Helpful packing functions for sendObjectMessage() //---------------------------------------------------------------------- -// static +// static void LLSelectMgr::packAgentIDAndSessionAndAttachment( void *user_data) { - U8 *attachment_point = (U8*)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point); + U8 *attachment_point = (U8*)user_data; + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point); } // static -void LLSelectMgr::packAgentID( void *user_data) +void LLSelectMgr::packAgentID( void *user_data) { - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); } // static void LLSelectMgr::packAgentAndSessionID(void* user_data) { - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); } // static void LLSelectMgr::packAgentAndGroupID(void* user_data) { - LLOwnerData *data = (LLOwnerData *)user_data; + LLOwnerData *data = (LLOwnerData *)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id ); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id ); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id ); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id ); } // static void LLSelectMgr::packAgentAndSessionAndGroupID(void* user_data) { - LLUUID* group_idp = (LLUUID*) user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp); + LLUUID* group_idp = (LLUUID*) user_data; + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp); } // static void LLSelectMgr::packDuplicateHeader(void* data) { - LLUUID group_id(gAgent.getGroupID()); - packAgentAndSessionAndGroupID(&group_id); + LLUUID group_id(gAgent.getGroupID()); + packAgentAndSessionAndGroupID(&group_id); - LLDuplicateData* dup_data = (LLDuplicateData*) data; + LLDuplicateData* dup_data = (LLDuplicateData*) data; - gMessageSystem->nextBlockFast(_PREHASH_SharedData); - gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset); - gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags); + gMessageSystem->nextBlockFast(_PREHASH_SharedData); + gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset); + gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags); } // static void LLSelectMgr::packDeleteHeader(void* userdata) { - BOOL force = (BOOL)(intptr_t)userdata; + BOOL force = (BOOL)(intptr_t)userdata; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addBOOLFast(_PREHASH_Force, force); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addBOOLFast(_PREHASH_Force, force); } // static void LLSelectMgr::packAgentGroupAndCatID(void* user_data) { - LLBuyData* buy = (LLBuyData*)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID); + LLBuyData* buy = (LLBuyData*)user_data; + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID); } //static void LLSelectMgr::packDeRezHeader(void* user_data) { - LLDeRezInfo* info = (LLDeRezInfo*)user_data; - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_AgentBlock); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination); - gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID); - LLUUID tid; - tid.generate(); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid); - const U8 PACKET = 1; - gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET); - gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET); -} - -// static + LLDeRezInfo* info = (LLDeRezInfo*)user_data; + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_AgentBlock); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination); + gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID); + LLUUID tid; + tid.generate(); + gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid); + const U8 PACKET = 1; + gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET); + gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET); +} + +// static void LLSelectMgr::packObjectID(LLSelectNode* node, void *user_data) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID ); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID ); } void LLSelectMgr::packObjectIDAndRotation(LLSelectNode* node, void *user_data) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); - gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); + gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation()); } void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); - gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); + gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction()); } void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); - gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); + gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch()); } // static void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *) { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); } // static void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data) { - const std::string* name = (const std::string*)user_data; - if(!name->empty()) - { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); - gMessageSystem->addStringFast(_PREHASH_Name, *name); - } + const std::string* name = (const std::string*)user_data; + if(!name->empty()) + { + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); + gMessageSystem->addStringFast(_PREHASH_Name, *name); + } } // static void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data) { - const std::string* desc = (const std::string*)user_data; - if(desc) - { // Empty (non-null, but zero length) descriptions are OK - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); - gMessageSystem->addStringFast(_PREHASH_Description, *desc); - } + const std::string* desc = (const std::string*)user_data; + if(desc) + { // Empty (non-null, but zero length) descriptions are OK + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); + gMessageSystem->addStringFast(_PREHASH_Description, *desc); + } } // static void LLSelectMgr::packObjectCategory(LLSelectNode* node, void* user_data) { - LLCategory* category = (LLCategory*)user_data; - if(!category) return; - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); - category->packMessage(gMessageSystem); + LLCategory* category = (LLCategory*)user_data; + if(!category) return; + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); + category->packMessage(gMessageSystem); } // static void LLSelectMgr::packObjectSaleInfo(LLSelectNode* node, void* user_data) { - LLSaleInfo* sale_info = (LLSaleInfo*)user_data; - if(!sale_info) return; - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); - sale_info->packMessage(gMessageSystem); + LLSaleInfo* sale_info = (LLSaleInfo*)user_data; + if(!sale_info) return; + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); + sale_info->packMessage(gMessageSystem); } // static @@ -5510,46 +5510,46 @@ void LLSelectMgr::packShape(LLSelectNode* node, void *user_data) { } -// static +// static void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data) { - LLPermData *data = (LLPermData *)user_data; + LLPermData *data = (LLPermData *)user_data; - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); - gMessageSystem->addU8Fast(_PREHASH_Field, data->mField); - gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet); - gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask); + gMessageSystem->addU8Fast(_PREHASH_Field, data->mField); + gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet); + gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask); } // Utility function to send some information to every region containing // an object on the selection list. We want to do this to reduce the total // number of packets sent by the viewer. void LLSelectMgr::sendListToRegions(const std::string& message_name, - void (*pack_header)(void *user_data), - void (*pack_body)(LLSelectNode* node, void *user_data), - void (*log_func)(LLSelectNode* node, void *user_data), - void *user_data, - ESendType send_type) + void (*pack_header)(void *user_data), + void (*pack_body)(LLSelectNode* node, void *user_data), + void (*log_func)(LLSelectNode* node, void *user_data), + void *user_data, + ESendType send_type) { sendListToRegions(mSelectedObjects, message_name, pack_header, pack_body, log_func, user_data, send_type); } void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle, - const std::string& message_name, - void (*pack_header)(void *user_data), - void (*pack_body)(LLSelectNode* node, void *user_data), - void (*log_func)(LLSelectNode* node, void *user_data), - void *user_data, - ESendType send_type) + const std::string& message_name, + void (*pack_header)(void *user_data), + void (*pack_body)(LLSelectNode* node, void *user_data), + void (*log_func)(LLSelectNode* node, void *user_data), + void *user_data, + ESendType send_type) { - LLSelectNode* node; - LLSelectNode* linkset_root = NULL; - LLViewerRegion* last_region; - LLViewerRegion* current_region; - S32 objects_in_this_packet = 0; + LLSelectNode* node; + LLSelectNode* linkset_root = NULL; + LLViewerRegion* last_region; + LLViewerRegion* current_region; + S32 objects_in_this_packet = 0; - bool link_operation = message_name == "ObjectLink"; + bool link_operation = message_name == "ObjectLink"; if (mAllowSelectAvatar) { @@ -5573,164 +5573,164 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle, resetObjectOverrides(selected_handle); } - std::queue nodes_to_send; - - struct push_all : public LLSelectedNodeFunctor - { - std::queue& nodes_to_send; - push_all(std::queue& n) : nodes_to_send(n) {} - virtual bool apply(LLSelectNode* node) - { - if (node->getObject()) - { - nodes_to_send.push(node); - } - return true; - } - }; - struct push_some : public LLSelectedNodeFunctor - { - std::queue& nodes_to_send; - bool mRoots; - push_some(std::queue& n, bool roots) : nodes_to_send(n), mRoots(roots) {} - virtual bool apply(LLSelectNode* node) - { - if (node->getObject()) - { - BOOL is_root = node->getObject()->isRootEdit(); - if ((mRoots && is_root) || (!mRoots && !is_root)) - { - nodes_to_send.push(node); - } - } - return true; - } - }; - struct push_all pushall(nodes_to_send); - struct push_some pushroots(nodes_to_send, TRUE); - struct push_some pushnonroots(nodes_to_send, FALSE); - - switch(send_type) - { - case SEND_ONLY_ROOTS: - if(message_name == "ObjectBuy") - selected_handle->applyToRootNodes(&pushroots); - else - selected_handle->applyToRootNodes(&pushall); - - break; - case SEND_INDIVIDUALS: - selected_handle->applyToNodes(&pushall); - break; - case SEND_ROOTS_FIRST: - // first roots... - selected_handle->applyToNodes(&pushroots); - // then children... - selected_handle->applyToNodes(&pushnonroots); - break; - case SEND_CHILDREN_FIRST: - // first children... - selected_handle->applyToNodes(&pushnonroots); - // then roots... - selected_handle->applyToNodes(&pushroots); - break; - - default: - LL_ERRS() << "Bad send type " << send_type << " passed to SendListToRegions()" << LL_ENDL; - } - - // bail if nothing selected - if (nodes_to_send.empty()) - { - return; - } - - node = nodes_to_send.front(); - nodes_to_send.pop(); - - // cache last region information - current_region = node->getObject()->getRegion(); - - // Start duplicate message - // CRO: this isn't - gMessageSystem->newMessage(message_name.c_str()); - (*pack_header)(user_data); - - // For each object - while (node != NULL) - { - // remember the last region, look up the current one - last_region = current_region; - current_region = node->getObject()->getRegion(); - - // if to same simulator and message not too big - if ((current_region == last_region) - && (! gMessageSystem->isSendFull(NULL)) - && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET)) - { - if (link_operation && linkset_root == NULL) - { - // linksets over 254 will be split into multiple messages, - // but we need to provide same root for all messages or we will get separate linksets - linkset_root = node; - } - // add another instance of the body of the data - (*pack_body)(node, user_data); + std::queue nodes_to_send; + + struct push_all : public LLSelectedNodeFunctor + { + std::queue& nodes_to_send; + push_all(std::queue& n) : nodes_to_send(n) {} + virtual bool apply(LLSelectNode* node) + { + if (node->getObject()) + { + nodes_to_send.push(node); + } + return true; + } + }; + struct push_some : public LLSelectedNodeFunctor + { + std::queue& nodes_to_send; + bool mRoots; + push_some(std::queue& n, bool roots) : nodes_to_send(n), mRoots(roots) {} + virtual bool apply(LLSelectNode* node) + { + if (node->getObject()) + { + BOOL is_root = node->getObject()->isRootEdit(); + if ((mRoots && is_root) || (!mRoots && !is_root)) + { + nodes_to_send.push(node); + } + } + return true; + } + }; + struct push_all pushall(nodes_to_send); + struct push_some pushroots(nodes_to_send, TRUE); + struct push_some pushnonroots(nodes_to_send, FALSE); + + switch(send_type) + { + case SEND_ONLY_ROOTS: + if(message_name == "ObjectBuy") + selected_handle->applyToRootNodes(&pushroots); + else + selected_handle->applyToRootNodes(&pushall); + + break; + case SEND_INDIVIDUALS: + selected_handle->applyToNodes(&pushall); + break; + case SEND_ROOTS_FIRST: + // first roots... + selected_handle->applyToNodes(&pushroots); + // then children... + selected_handle->applyToNodes(&pushnonroots); + break; + case SEND_CHILDREN_FIRST: + // first children... + selected_handle->applyToNodes(&pushnonroots); + // then roots... + selected_handle->applyToNodes(&pushroots); + break; + + default: + LL_ERRS() << "Bad send type " << send_type << " passed to SendListToRegions()" << LL_ENDL; + } + + // bail if nothing selected + if (nodes_to_send.empty()) + { + return; + } + + node = nodes_to_send.front(); + nodes_to_send.pop(); + + // cache last region information + current_region = node->getObject()->getRegion(); + + // Start duplicate message + // CRO: this isn't + gMessageSystem->newMessage(message_name.c_str()); + (*pack_header)(user_data); + + // For each object + while (node != NULL) + { + // remember the last region, look up the current one + last_region = current_region; + current_region = node->getObject()->getRegion(); + + // if to same simulator and message not too big + if ((current_region == last_region) + && (! gMessageSystem->isSendFull(NULL)) + && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET)) + { + if (link_operation && linkset_root == NULL) + { + // linksets over 254 will be split into multiple messages, + // but we need to provide same root for all messages or we will get separate linksets + linkset_root = node; + } + // add another instance of the body of the data + (*pack_body)(node, user_data); // do any related logging (*log_func)(node, user_data); - ++objects_in_this_packet; - - // and on to the next object - if(nodes_to_send.empty()) - { - node = NULL; - } - else - { - node = nodes_to_send.front(); - nodes_to_send.pop(); - } - } - else - { - // otherwise send current message and start new one - gMessageSystem->sendReliable( last_region->getHost()); - objects_in_this_packet = 0; - - gMessageSystem->newMessage(message_name.c_str()); - (*pack_header)(user_data); - - if (linkset_root != NULL) - { - if (current_region != last_region) - { - // root should be in one region with the child, reset it - linkset_root = NULL; - } - else - { - // add root instance into new message - (*pack_body)(linkset_root, user_data); - ++objects_in_this_packet; - } - } - - // don't move to the next object, we still need to add the - // body data. - } - } - - // flush messages - if (gMessageSystem->getCurrentSendTotal() > 0) - { - gMessageSystem->sendReliable( current_region->getHost()); - } - else - { - gMessageSystem->clearMessage(); - } - - // LL_INFOS() << "sendListToRegions " << message_name << " obj " << objects_sent << " pkt " << packets_sent << LL_ENDL; + ++objects_in_this_packet; + + // and on to the next object + if(nodes_to_send.empty()) + { + node = NULL; + } + else + { + node = nodes_to_send.front(); + nodes_to_send.pop(); + } + } + else + { + // otherwise send current message and start new one + gMessageSystem->sendReliable( last_region->getHost()); + objects_in_this_packet = 0; + + gMessageSystem->newMessage(message_name.c_str()); + (*pack_header)(user_data); + + if (linkset_root != NULL) + { + if (current_region != last_region) + { + // root should be in one region with the child, reset it + linkset_root = NULL; + } + else + { + // add root instance into new message + (*pack_body)(linkset_root, user_data); + ++objects_in_this_packet; + } + } + + // don't move to the next object, we still need to add the + // body data. + } + } + + // flush messages + if (gMessageSystem->getCurrentSendTotal() > 0) + { + gMessageSystem->sendReliable( current_region->getHost()); + } + else + { + gMessageSystem->clearMessage(); + } + + // LL_INFOS() << "sendListToRegions " << message_name << " obj " << objects_sent << " pkt " << packets_sent << LL_ENDL; } @@ -5740,166 +5740,166 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle, void LLSelectMgr::requestObjectPropertiesFamily(LLViewerObject* object) { - LLMessageSystem* msg = gMessageSystem; + LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_RequestFlags, 0x0 ); - msg->addUUIDFast(_PREHASH_ObjectID, object->mID ); + msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_RequestFlags, 0x0 ); + msg->addUUIDFast(_PREHASH_ObjectID, object->mID ); - LLViewerRegion* regionp = object->getRegion(); - msg->sendReliable( regionp->getHost() ); + LLViewerRegion* regionp = object->getRegion(); + msg->sendReliable( regionp->getHost() ); } // static void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data) { - S32 i; - S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData); - for (i = 0; i < count; i++) - { - LLUUID id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i); - - LLUUID creator_id; - LLUUID owner_id; - LLUUID group_id; - LLUUID last_owner_id; - U64 creation_date; - LLUUID extra_id; - U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask; - LLSaleInfo sale_info; - LLCategory category; - LLAggregatePermissions ag_perms; - LLAggregatePermissions ag_texture_perms; - LLAggregatePermissions ag_texture_perms_owner; - - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i); - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i); - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i); - msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i); - sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i); - - ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i); - ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i); - ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i); - category.unpackMultiMessage(msg, _PREHASH_ObjectData, i); - - S16 inv_serial = 0; - msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i); - - LLUUID item_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i); - LLUUID folder_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i); - LLUUID from_task_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i); - - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i); - - std::string name; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name, i); - std::string desc; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc, i); - - std::string touch_name; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, touch_name, i); - std::string sit_name; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i); - - //unpack TE IDs - uuid_vec_t texture_ids; - S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID); - if (size > 0) - { - S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES]; - msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES); - - for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES) - { - LLUUID tid; - memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */ - texture_ids.push_back(tid); - } - } - - - // Iterate through nodes at end, since it can be on both the regular AND hover list - struct f : public LLSelectedNodeFunctor - { - LLUUID mID; - f(const LLUUID& id) : mID(id) {} - virtual bool apply(LLSelectNode* node) - { - return (node->getObject() && node->getObject()->mID == mID); - } - } func(id); - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); - - if (!node) - { - LL_WARNS() << "Couldn't find object " << id << " selected." << LL_ENDL; - } - else - { + S32 i; + S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData); + for (i = 0; i < count; i++) + { + LLUUID id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i); + + LLUUID creator_id; + LLUUID owner_id; + LLUUID group_id; + LLUUID last_owner_id; + U64 creation_date; + LLUUID extra_id; + U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask; + LLSaleInfo sale_info; + LLCategory category; + LLAggregatePermissions ag_perms; + LLAggregatePermissions ag_texture_perms; + LLAggregatePermissions ag_texture_perms_owner; + + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i); + msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i); + sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i); + + ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i); + ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i); + ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i); + category.unpackMultiMessage(msg, _PREHASH_ObjectData, i); + + S16 inv_serial = 0; + msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i); + + LLUUID item_id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i); + LLUUID folder_id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i); + LLUUID from_task_id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i); + + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i); + + std::string name; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name, i); + std::string desc; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc, i); + + std::string touch_name; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, touch_name, i); + std::string sit_name; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i); + + //unpack TE IDs + uuid_vec_t texture_ids; + S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID); + if (size > 0) + { + S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES]; + msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES); + + for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES) + { + LLUUID tid; + memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */ + texture_ids.push_back(tid); + } + } + + + // Iterate through nodes at end, since it can be on both the regular AND hover list + struct f : public LLSelectedNodeFunctor + { + LLUUID mID; + f(const LLUUID& id) : mID(id) {} + virtual bool apply(LLSelectNode* node) + { + return (node->getObject() && node->getObject()->mID == mID); + } + } func(id); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); + + if (!node) + { + LL_WARNS() << "Couldn't find object " << id << " selected." << LL_ENDL; + } + else + { // save texture data as soon as we get texture perms first time bool save_textures = !node->mValid; - if (node->mInventorySerial != inv_serial && node->getObject()) - { - node->getObject()->dirtyInventory(); + if (node->mInventorySerial != inv_serial && node->getObject()) + { + node->getObject()->dirtyInventory(); // Even if this isn't object's first udpate, inventory changed // and some of the applied textures might have been in inventory // so update texture list. save_textures = true; - } - - if (save_textures) - { - BOOL can_copy = FALSE; - BOOL can_transfer = FALSE; - - LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE; - if(node->getObject()->permYouOwner()) - { - value = ag_texture_perms_owner.getValue(PERM_COPY); - if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) - { - can_copy = TRUE; - } - value = ag_texture_perms_owner.getValue(PERM_TRANSFER); - if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) - { - can_transfer = TRUE; - } - } - else - { - value = ag_texture_perms.getValue(PERM_COPY); - if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) - { - can_copy = TRUE; - } - value = ag_texture_perms.getValue(PERM_TRANSFER); - if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) - { - can_transfer = TRUE; - } - } - - if (can_copy && can_transfer) - { - node->saveTextures(texture_ids); - } + } + + if (save_textures) + { + BOOL can_copy = FALSE; + BOOL can_transfer = FALSE; + + LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE; + if(node->getObject()->permYouOwner()) + { + value = ag_texture_perms_owner.getValue(PERM_COPY); + if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) + { + can_copy = TRUE; + } + value = ag_texture_perms_owner.getValue(PERM_TRANSFER); + if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) + { + can_transfer = TRUE; + } + } + else + { + value = ag_texture_perms.getValue(PERM_COPY); + if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) + { + can_copy = TRUE; + } + value = ag_texture_perms.getValue(PERM_TRANSFER); + if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL) + { + can_transfer = TRUE; + } + } + + if (can_copy && can_transfer) + { + node->saveTextures(texture_ids); + } if (can_copy && can_transfer && node->getObject()->getVolume()) { @@ -5930,572 +5930,572 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data // might need to be moved to LLGLTFMaterialOverrideDispatchHandler node->saveGLTFMaterials(material_ids, override_materials); } - } - - node->mValid = TRUE; - node->mPermissions->init(creator_id, owner_id, - last_owner_id, group_id); - node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask); - node->mCreationDate = creation_date; - node->mItemID = item_id; - node->mFolderID = folder_id; - node->mFromTaskID = from_task_id; - node->mName.assign(name); - node->mDescription.assign(desc); - node->mSaleInfo = sale_info; - node->mAggregatePerm = ag_perms; - node->mAggregateTexturePerm = ag_texture_perms; - node->mAggregateTexturePermOwner = ag_texture_perms_owner; - node->mCategory = category; - node->mInventorySerial = inv_serial; - node->mSitName.assign(sit_name); - node->mTouchName.assign(touch_name); - } - } - - dialog_refresh_all(); - - // hack for left-click buy object - LLToolPie::selectionPropertiesReceived(); -} + } + + node->mValid = TRUE; + node->mPermissions->init(creator_id, owner_id, + last_owner_id, group_id); + node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask); + node->mCreationDate = creation_date; + node->mItemID = item_id; + node->mFolderID = folder_id; + node->mFromTaskID = from_task_id; + node->mName.assign(name); + node->mDescription.assign(desc); + node->mSaleInfo = sale_info; + node->mAggregatePerm = ag_perms; + node->mAggregateTexturePerm = ag_texture_perms; + node->mAggregateTexturePermOwner = ag_texture_perms_owner; + node->mCategory = category; + node->mInventorySerial = inv_serial; + node->mSitName.assign(sit_name); + node->mTouchName.assign(touch_name); + } + } + + dialog_refresh_all(); + + // hack for left-click buy object + LLToolPie::selectionPropertiesReceived(); +} // static void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data) { - LLUUID id; - - U32 request_flags; - LLUUID creator_id; - LLUUID owner_id; - LLUUID group_id; - LLUUID extra_id; - U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask; - LLSaleInfo sale_info; - LLCategory category; - - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags ); - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id ); - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id ); - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id ); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask ); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask ); - msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask ); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask ); - msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask); - sale_info.unpackMessage(msg, _PREHASH_ObjectData); - category.unpackMessage(msg, _PREHASH_ObjectData); - - LLUUID last_owner_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id ); - - // unpack name & desc - std::string name; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name); - - std::string desc; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc); - - // the reporter widget askes the server for info about picked objects - if (request_flags & COMPLAINT_REPORT_REQUEST ) - { - LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance("reporter"); - if (reporterp) - { - LLAvatarName av_name; - LLAvatarNameCache::get(owner_id, &av_name); - reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id); - } - } - else if (request_flags & OBJECT_PAY_REQUEST) - { - // check if the owner of the paid object is muted - LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY); - } - - // Now look through all of the hovered nodes - struct f : public LLSelectedNodeFunctor - { - LLUUID mID; - f(const LLUUID& id) : mID(id) {} - virtual bool apply(LLSelectNode* node) - { - return (node->getObject() && node->getObject()->mID == mID); - } - } func(id); - LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func); - - if (node) - { - node->mValid = TRUE; - node->mPermissions->init(LLUUID::null, owner_id, - last_owner_id, group_id); - node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask); - node->mSaleInfo = sale_info; - node->mCategory = category; - node->mName.assign(name); - node->mDescription.assign(desc); - } - - dialog_refresh_all(); + LLUUID id; + + U32 request_flags; + LLUUID creator_id; + LLUUID owner_id; + LLUUID group_id; + LLUUID extra_id; + U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask; + LLSaleInfo sale_info; + LLCategory category; + + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags ); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id ); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id ); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id ); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask ); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask ); + msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask ); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask ); + msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask); + sale_info.unpackMessage(msg, _PREHASH_ObjectData); + category.unpackMessage(msg, _PREHASH_ObjectData); + + LLUUID last_owner_id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id ); + + // unpack name & desc + std::string name; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name); + + std::string desc; + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc); + + // the reporter widget askes the server for info about picked objects + if (request_flags & COMPLAINT_REPORT_REQUEST ) + { + LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance("reporter"); + if (reporterp) + { + LLAvatarName av_name; + LLAvatarNameCache::get(owner_id, &av_name); + reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id); + } + } + else if (request_flags & OBJECT_PAY_REQUEST) + { + // check if the owner of the paid object is muted + LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY); + } + + // Now look through all of the hovered nodes + struct f : public LLSelectedNodeFunctor + { + LLUUID mID; + f(const LLUUID& id) : mID(id) {} + virtual bool apply(LLSelectNode* node) + { + return (node->getObject() && node->getObject()->mID == mID); + } + } func(id); + LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func); + + if (node) + { + node->mValid = TRUE; + node->mPermissions->init(LLUUID::null, owner_id, + last_owner_id, group_id); + node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask); + node->mSaleInfo = sale_info; + node->mCategory = category; + node->mName.assign(name); + node->mDescription.assign(desc); + } + + dialog_refresh_all(); } // static void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) { - BOOL reset_list; - msg->getBOOL("Header", "ResetList", reset_list); + BOOL reset_list; + msg->getBOOL("Header", "ResetList", reset_list); - if (reset_list) - { - LLSelectMgr::getInstance()->deselectAll(); - } - - LLUUID full_id; - S32 local_id; - LLViewerObject* object; - std::vector objects; - S32 i; - S32 block_count = msg->getNumberOfBlocks("Data"); + if (reset_list) + { + LLSelectMgr::getInstance()->deselectAll(); + } - for (i = 0; i < block_count; i++) - { - msg->getS32("Data", "LocalID", local_id, i); + LLUUID full_id; + S32 local_id; + LLViewerObject* object; + std::vector objects; + S32 i; + S32 block_count = msg->getNumberOfBlocks("Data"); - gObjectList.getUUIDFromLocal(full_id, - local_id, - msg->getSenderIP(), - msg->getSenderPort()); - object = gObjectList.findObject(full_id); - if (object) - { - objects.push_back(object); - } - } + for (i = 0; i < block_count; i++) + { + msg->getS32("Data", "LocalID", local_id, i); + + gObjectList.getUUIDFromLocal(full_id, + local_id, + msg->getSenderIP(), + msg->getSenderPort()); + object = gObjectList.findObject(full_id); + if (object) + { + objects.push_back(object); + } + } - // Don't select, just highlight - LLSelectMgr::getInstance()->highlightObjectAndFamily(objects); + // Don't select, just highlight + LLSelectMgr::getInstance()->highlightObjectAndFamily(objects); } -extern F32 gGLModelView[16]; +extern F32 gGLModelView[16]; void LLSelectMgr::updateSilhouettes() { - S32 num_sils_genned = 0; - - LLVector3d cameraPos = gAgentCamera.getCameraPositionGlobal(); - F32 currentCameraZoom = gAgentCamera.getCurrentCameraBuildOffset(); - - if (!mSilhouetteImagep) - { - mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI); - } - - mHighlightedObjects->cleanupNodes(); - - if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom) - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - object->setChanged(LLXform::SILHOUETTE); - return true; - } - } func; - getSelection()->applyToObjects(&func); - - mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); - } - - std::vector changed_objects; - - updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects); - if (mRectSelectedObjects.size() > 0) - { - //gGLSPipelineSelection.set(); - - //mSilhouetteImagep->bindTexture(); - //glAlphaFunc(GL_GREATER, sHighlightAlphaTest); - - std::set roots; - - // sync mHighlightedObjects with mRectSelectedObjects since the latter is rebuilt every frame and former - // persists from frame to frame to avoid regenerating object silhouettes - // mHighlightedObjects includes all siblings of rect selected objects - - BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - - // generate list of roots from current object selection - for (std::set >::iterator iter = mRectSelectedObjects.begin(); - iter != mRectSelectedObjects.end(); iter++) - { - LLViewerObject *objectp = *iter; - if (select_linked_set) - { - LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot(); - roots.insert(rootp); - } - else - { - roots.insert(objectp); - } - } - - // remove highlight nodes not in roots list - std::vector remove_these_nodes; - std::vector remove_these_roots; - - for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); - iter != mHighlightedObjects->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; - if (objectp->isRoot() || !select_linked_set) - { - if (roots.count(objectp) == 0) - { - remove_these_nodes.push_back(node); - } - else - { - remove_these_roots.push_back(objectp); - } - } - else - { - LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot(); - - if (roots.count(rootp) == 0) - { - remove_these_nodes.push_back(node); - } - } - } - - // remove all highlight nodes no longer in rectangle selection - for (std::vector::iterator iter = remove_these_nodes.begin(); - iter != remove_these_nodes.end(); ++iter) - { - LLSelectNode* nodep = *iter; - mHighlightedObjects->removeNode(nodep); - } - - // remove all root objects already being highlighted - for (std::vector::iterator iter = remove_these_roots.begin(); - iter != remove_these_roots.end(); ++iter) - { - LLViewerObject* objectp = *iter; - roots.erase(objectp); - } - - // add all new objects in rectangle selection - for (std::set::iterator iter = roots.begin(); - iter != roots.end(); iter++) - { - LLViewerObject* objectp = *iter; - if (!canSelectObject(objectp)) - { - continue; - } - - LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE); - rect_select_root_node->selectAllTEs(TRUE); - - if (!select_linked_set) - { - rect_select_root_node->mIndividualSelection = TRUE; - } - else - { - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child_objectp = *iter; - - if (!canSelectObject(child_objectp)) - { - continue; - } - - LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE); - rect_select_node->selectAllTEs(TRUE); - mHighlightedObjects->addNodeAtEnd(rect_select_node); - } - } - - // Add the root last, to preserve order for link operations. - mHighlightedObjects->addNodeAtEnd(rect_select_root_node); - } - - num_sils_genned = 0; - - // render silhouettes for highlighted objects - //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); - for (S32 pass = 0; pass < 2; pass++) - { - for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); - iter != mHighlightedObjects->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; - - // do roots first, then children so that root flags are cleared ASAP - BOOL roots_only = (pass == 0); - BOOL is_root = objectp->isRootEdit(); - if (roots_only != is_root) - { - continue; - } - - if (!node->mSilhouetteExists - || objectp->isChanged(LLXform::SILHOUETTE) - || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE))) - { - if (num_sils_genned++ < MAX_SILS_PER_FRAME) - { - generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin()); - changed_objects.push_back(objectp); - } - else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull()) - { - //RN: hack for orthogonal projection of HUD attachments - LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent(); - if (attachment_pt && attachment_pt->getIsHUDAttachment()) - { - LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f); - generateSilhouette(node, camera_pos); - } - } - } - //LLColor4 highlight_color; - // - //if (subtracting_from_selection) - //{ - // node->renderOneSilhouette(LLColor4::red); - //} - //else if (!objectp->isSelected()) - //{ - // highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; - // node->renderOneSilhouette(highlight_color); - //} - } - } - //mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D); - } - else - { - mHighlightedObjects->deleteAllNodes(); - } - - for (std::vector::iterator iter = changed_objects.begin(); - iter != changed_objects.end(); ++iter) - { - // clear flags after traversing node list (as child objects need to refer to parent flags, etc) - LLViewerObject* objectp = *iter; - objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); - } + S32 num_sils_genned = 0; + + LLVector3d cameraPos = gAgentCamera.getCameraPositionGlobal(); + F32 currentCameraZoom = gAgentCamera.getCurrentCameraBuildOffset(); + + if (!mSilhouetteImagep) + { + mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI); + } + + mHighlightedObjects->cleanupNodes(); + + if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + object->setChanged(LLXform::SILHOUETTE); + return true; + } + } func; + getSelection()->applyToObjects(&func); + + mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); + } + + std::vector changed_objects; + + updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects); + if (mRectSelectedObjects.size() > 0) + { + //gGLSPipelineSelection.set(); + + //mSilhouetteImagep->bindTexture(); + //glAlphaFunc(GL_GREATER, sHighlightAlphaTest); + + std::set roots; + + // sync mHighlightedObjects with mRectSelectedObjects since the latter is rebuilt every frame and former + // persists from frame to frame to avoid regenerating object silhouettes + // mHighlightedObjects includes all siblings of rect selected objects + + BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + + // generate list of roots from current object selection + for (std::set >::iterator iter = mRectSelectedObjects.begin(); + iter != mRectSelectedObjects.end(); iter++) + { + LLViewerObject *objectp = *iter; + if (select_linked_set) + { + LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot(); + roots.insert(rootp); + } + else + { + roots.insert(objectp); + } + } + + // remove highlight nodes not in roots list + std::vector remove_these_nodes; + std::vector remove_these_roots; + + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; + if (objectp->isRoot() || !select_linked_set) + { + if (roots.count(objectp) == 0) + { + remove_these_nodes.push_back(node); + } + else + { + remove_these_roots.push_back(objectp); + } + } + else + { + LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot(); + + if (roots.count(rootp) == 0) + { + remove_these_nodes.push_back(node); + } + } + } + + // remove all highlight nodes no longer in rectangle selection + for (std::vector::iterator iter = remove_these_nodes.begin(); + iter != remove_these_nodes.end(); ++iter) + { + LLSelectNode* nodep = *iter; + mHighlightedObjects->removeNode(nodep); + } + + // remove all root objects already being highlighted + for (std::vector::iterator iter = remove_these_roots.begin(); + iter != remove_these_roots.end(); ++iter) + { + LLViewerObject* objectp = *iter; + roots.erase(objectp); + } + + // add all new objects in rectangle selection + for (std::set::iterator iter = roots.begin(); + iter != roots.end(); iter++) + { + LLViewerObject* objectp = *iter; + if (!canSelectObject(objectp)) + { + continue; + } + + LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE); + rect_select_root_node->selectAllTEs(TRUE); + + if (!select_linked_set) + { + rect_select_root_node->mIndividualSelection = TRUE; + } + else + { + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child_objectp = *iter; + + if (!canSelectObject(child_objectp)) + { + continue; + } + + LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE); + rect_select_node->selectAllTEs(TRUE); + mHighlightedObjects->addNodeAtEnd(rect_select_node); + } + } + + // Add the root last, to preserve order for link operations. + mHighlightedObjects->addNodeAtEnd(rect_select_root_node); + } + + num_sils_genned = 0; + + // render silhouettes for highlighted objects + //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); + for (S32 pass = 0; pass < 2; pass++) + { + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; + + // do roots first, then children so that root flags are cleared ASAP + BOOL roots_only = (pass == 0); + BOOL is_root = objectp->isRootEdit(); + if (roots_only != is_root) + { + continue; + } + + if (!node->mSilhouetteExists + || objectp->isChanged(LLXform::SILHOUETTE) + || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE))) + { + if (num_sils_genned++ < MAX_SILS_PER_FRAME) + { + generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin()); + changed_objects.push_back(objectp); + } + else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull()) + { + //RN: hack for orthogonal projection of HUD attachments + LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent(); + if (attachment_pt && attachment_pt->getIsHUDAttachment()) + { + LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f); + generateSilhouette(node, camera_pos); + } + } + } + //LLColor4 highlight_color; + // + //if (subtracting_from_selection) + //{ + // node->renderOneSilhouette(LLColor4::red); + //} + //else if (!objectp->isSelected()) + //{ + // highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; + // node->renderOneSilhouette(highlight_color); + //} + } + } + //mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D); + } + else + { + mHighlightedObjects->deleteAllNodes(); + } + + for (std::vector::iterator iter = changed_objects.begin(); + iter != changed_objects.end(); ++iter) + { + // clear flags after traversing node list (as child objects need to refer to parent flags, etc) + LLViewerObject* objectp = *iter; + objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); + } } void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector& changed_objects) { - if (object_handle->getNumNodes()) - { - //gGLSPipelineSelection.set(); - - //mSilhouetteImagep->bindTexture(); - //glAlphaFunc(GL_GREATER, sHighlightAlphaTest); - - for (S32 pass = 0; pass < 2; pass++) - { - for (LLObjectSelection::iterator iter = object_handle->begin(); - iter != object_handle->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; - // do roots first, then children so that root flags are cleared ASAP - BOOL roots_only = (pass == 0); - BOOL is_root = (objectp->isRootEdit()); - if (roots_only != is_root || objectp->mDrawable.isNull()) - { - continue; - } - - if (!node->mSilhouetteExists - || objectp->isChanged(LLXform::SILHOUETTE) - || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE))) - { - if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible()) - { - generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin()); - changed_objects.push_back(objectp); - } - else if (objectp->isAttachment()) - { - //RN: hack for orthogonal projection of HUD attachments - LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent(); - if (attachment_pt && attachment_pt->getIsHUDAttachment()) - { - LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f); - generateSilhouette(node, camera_pos); - } - } - } - } - } - } + if (object_handle->getNumNodes()) + { + //gGLSPipelineSelection.set(); + + //mSilhouetteImagep->bindTexture(); + //glAlphaFunc(GL_GREATER, sHighlightAlphaTest); + + for (S32 pass = 0; pass < 2; pass++) + { + for (LLObjectSelection::iterator iter = object_handle->begin(); + iter != object_handle->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; + // do roots first, then children so that root flags are cleared ASAP + BOOL roots_only = (pass == 0); + BOOL is_root = (objectp->isRootEdit()); + if (roots_only != is_root || objectp->mDrawable.isNull()) + { + continue; + } + + if (!node->mSilhouetteExists + || objectp->isChanged(LLXform::SILHOUETTE) + || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE))) + { + if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible()) + { + generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin()); + changed_objects.push_back(objectp); + } + else if (objectp->isAttachment()) + { + //RN: hack for orthogonal projection of HUD attachments + LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent(); + if (attachment_pt && attachment_pt->getIsHUDAttachment()) + { + LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f); + generateSilhouette(node, camera_pos); + } + } + } + } + } + } } void LLSelectMgr::renderSilhouettes(BOOL for_hud) { - if (!mRenderSilhouettes || !mRenderHighlightSelections) - { - return; - } - - gGL.getTexUnit(0)->bind(mSilhouetteImagep); - LLGLSPipelineSelection gls_select; - LLGLEnable blend(GL_BLEND); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - if (isAgentAvatarValid() && for_hud) - { - LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); - - F32 cur_zoom = gAgentCamera.mHUDCurZoom; - - // set up transform to encompass bounding box of HUD - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.pushUIMatrix(); - gGL.loadUIIdentity(); - gGL.loadIdentity(); - gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame - gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f); - gGL.scalef(cur_zoom, cur_zoom, cur_zoom); - } - - bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections; - F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0); - - static LLColor4 sParentColor = LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha); - static LLColor4 sChildColor = LLColor4(sSilhouetteChildColor[VRED], sSilhouetteChildColor[VGREEN], sSilhouetteChildColor[VBLUE], LLSelectMgr::sHighlightAlpha); - - auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor) - { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) - { - gDebugProgram.bind(); - } - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - - BOOL is_hud_object = objectp->isHUDAttachment(); - - if (!is_hud_object) - { - gGL.loadIdentity(); - gGL.multMatrix(gGLModelView); - } - - if (objectp->mDrawable->isActive()) - { - gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix); - } - else if (!is_hud_object) - { - LLVector3 trans = objectp->getRegion()->getOriginAgent(); - gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - } - - bool bRenderHidenSelection = node->isTransient() ? false : LLSelectMgr::sRenderHiddenSelections; - - - LLVOVolume* vobj = objectp->mDrawable->getVOVolume(); - if (vobj) - { - LLVertexBuffer::unbind(); - gGL.pushMatrix(); - gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix); - - if (objectp->mDrawable->isState(LLDrawable::RIGGED)) - { - vobj->updateRiggedVolume(true); - } - } - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces - for (S32 te = 0; te < num_tes; ++te) - { - if (node->isTESelected(te)) - { - objectp->mDrawable->getFace(te)->renderOneWireframe(hlColor, fogCfx, wireframe_selection, bRenderHidenSelection, nullptr != shader); - } - } - - gGL.popMatrix(); - gGL.popMatrix(); - - glLineWidth(1.f); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - if (shader) - { - shader->bind(); - } - }; - - if (mSelectedObjects->getNumNodes()) - { - LLUUID inspect_item_id= LLUUID::null; - LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); - if(inspect_instance && inspect_instance->getVisible()) - { - inspect_item_id = inspect_instance->getSelectedUUID(); - } - else - { - LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel(); - if (panel_task_info) - { - inspect_item_id = panel_task_info->getSelectedUUID(); - } - } - - LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID(); - for (S32 pass = 0; pass < 2; pass++) - { - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); - iter != mSelectedObjects->end(); iter++) - { - LLSelectNode* node = *iter; - + if (!mRenderSilhouettes || !mRenderHighlightSelections) + { + return; + } + + gGL.getTexUnit(0)->bind(mSilhouetteImagep); + LLGLSPipelineSelection gls_select; + LLGLEnable blend(GL_BLEND); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + + if (isAgentAvatarValid() && for_hud) + { + LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); + + F32 cur_zoom = gAgentCamera.mHUDCurZoom; + + // set up transform to encompass bounding box of HUD + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); + gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.pushUIMatrix(); + gGL.loadUIIdentity(); + gGL.loadIdentity(); + gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame + gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f); + gGL.scalef(cur_zoom, cur_zoom, cur_zoom); + } + + bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections; + F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0); + + static LLColor4 sParentColor = LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha); + static LLColor4 sChildColor = LLColor4(sSilhouetteChildColor[VRED], sSilhouetteChildColor[VGREEN], sSilhouetteChildColor[VBLUE], LLSelectMgr::sHighlightAlpha); + + auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor) + { + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader) + { + gDebugProgram.bind(); + } + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + + BOOL is_hud_object = objectp->isHUDAttachment(); + + if (!is_hud_object) + { + gGL.loadIdentity(); + gGL.multMatrix(gGLModelView); + } + + if (objectp->mDrawable->isActive()) + { + gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix); + } + else if (!is_hud_object) + { + LLVector3 trans = objectp->getRegion()->getOriginAgent(); + gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); + } + + bool bRenderHidenSelection = node->isTransient() ? false : LLSelectMgr::sRenderHiddenSelections; + + + LLVOVolume* vobj = objectp->mDrawable->getVOVolume(); + if (vobj) + { + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix); + + if (objectp->mDrawable->isState(LLDrawable::RIGGED)) + { + vobj->updateRiggedVolume(true); + } + } + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + objectp->mDrawable->getFace(te)->renderOneWireframe(hlColor, fogCfx, wireframe_selection, bRenderHidenSelection, nullptr != shader); + } + } + + gGL.popMatrix(); + gGL.popMatrix(); + + glLineWidth(1.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + if (shader) + { + shader->bind(); + } + }; + + if (mSelectedObjects->getNumNodes()) + { + LLUUID inspect_item_id= LLUUID::null; + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); + if(inspect_instance && inspect_instance->getVisible()) + { + inspect_item_id = inspect_instance->getSelectedUUID(); + } + else + { + LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel(); + if (panel_task_info) + { + inspect_item_id = panel_task_info->getSelectedUUID(); + } + } + + LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID(); + for (S32 pass = 0; pass < 2; pass++) + { + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + if (getTEMode() && !node->hasSelectedTE()) continue; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; - if (objectp->mDrawable - && objectp->mDrawable->getVOVolume() + if (objectp->mDrawable + && objectp->mDrawable->getVOVolume() && objectp->mDrawable->getVOVolume()->isMesh()) { LLColor4 hlColor = objectp->isRootEdit() ? sParentColor : sChildColor; @@ -6539,145 +6539,145 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) node->renderOneSilhouette(sSilhouetteChildColor); } } - } //for all selected node's - } //for pass - } - - if (mHighlightedObjects->getNumNodes()) - { - // render silhouettes for highlighted objects - BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); - for (S32 pass = 0; pass < 2; pass++) - { - for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); - iter != mHighlightedObjects->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* objectp = node->getObject(); - if (!objectp) - continue; - if (objectp->isHUDAttachment() != for_hud) - { - continue; - } - - LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; - if (objectp->mDrawable - && objectp->mDrawable->getVOVolume() - && objectp->mDrawable->getVOVolume()->isMesh()) - { - renderMeshSelection_f(node, objectp, subtracting_from_selection ? LLColor4::red : highlight_color); - } - else if (subtracting_from_selection) - { - node->renderOneSilhouette(LLColor4::red); - } - else if (!objectp->isSelected()) - { - node->renderOneSilhouette(highlight_color); - } - } - } - } - - if (isAgentAvatarValid() && for_hud) - { - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - gGL.popUIMatrix(); - stop_glerror(); - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } //for all selected node's + } //for pass + } + + if (mHighlightedObjects->getNumNodes()) + { + // render silhouettes for highlighted objects + BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); + for (S32 pass = 0; pass < 2; pass++) + { + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + if (!objectp) + continue; + if (objectp->isHUDAttachment() != for_hud) + { + continue; + } + + LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; + if (objectp->mDrawable + && objectp->mDrawable->getVOVolume() + && objectp->mDrawable->getVOVolume()->isMesh()) + { + renderMeshSelection_f(node, objectp, subtracting_from_selection ? LLColor4::red : highlight_color); + } + else if (subtracting_from_selection) + { + node->renderOneSilhouette(LLColor4::red); + } + else if (!objectp->isSelected()) + { + node->renderOneSilhouette(highlight_color); + } + } + } + } + + if (isAgentAvatarValid() && for_hud) + { + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + gGL.popUIMatrix(); + stop_glerror(); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) { - LLViewerObject* objectp = nodep->getObject(); + LLViewerObject* objectp = nodep->getObject(); - if (objectp && objectp->getPCode() == LL_PCODE_VOLUME) - { - ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point); - } + if (objectp && objectp->getPCode() == LL_PCODE_VOLUME) + { + ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point); + } } // // Utility classes // LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow) -: mObject(object), - mIndividualSelection(FALSE), - mTransient(FALSE), - mValid(FALSE), - mPermissions(new LLPermissions()), - mInventorySerial(0), - mSilhouetteExists(FALSE), - mDuplicated(FALSE), - mTESelectMask(0), - mLastTESelected(0), - mName(LLStringUtil::null), - mDescription(LLStringUtil::null), - mTouchName(LLStringUtil::null), - mSitName(LLStringUtil::null), - mCreationDate(0) -{ - saveColors(); - saveShinyColors(); +: mObject(object), + mIndividualSelection(FALSE), + mTransient(FALSE), + mValid(FALSE), + mPermissions(new LLPermissions()), + mInventorySerial(0), + mSilhouetteExists(FALSE), + mDuplicated(FALSE), + mTESelectMask(0), + mLastTESelected(0), + mName(LLStringUtil::null), + mDescription(LLStringUtil::null), + mTouchName(LLStringUtil::null), + mSitName(LLStringUtil::null), + mCreationDate(0) +{ + saveColors(); + saveShinyColors(); } LLSelectNode::LLSelectNode(const LLSelectNode& nodep) { - mTESelectMask = nodep.mTESelectMask; - mLastTESelected = nodep.mLastTESelected; - - mIndividualSelection = nodep.mIndividualSelection; - - mValid = nodep.mValid; - mTransient = nodep.mTransient; - mPermissions = new LLPermissions(*nodep.mPermissions); - mSaleInfo = nodep.mSaleInfo;; - mAggregatePerm = nodep.mAggregatePerm; - mAggregateTexturePerm = nodep.mAggregateTexturePerm; - mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner; - mName = nodep.mName; - mDescription = nodep.mDescription; - mCategory = nodep.mCategory; - mInventorySerial = 0; - mSavedPositionLocal = nodep.mSavedPositionLocal; - mSavedPositionGlobal = nodep.mSavedPositionGlobal; - mSavedScale = nodep.mSavedScale; - mSavedRotation = nodep.mSavedRotation; - mDuplicated = nodep.mDuplicated; - mDuplicatePos = nodep.mDuplicatePos; - mDuplicateRot = nodep.mDuplicateRot; - mItemID = nodep.mItemID; - mFolderID = nodep.mFolderID; - mFromTaskID = nodep.mFromTaskID; - mTouchName = nodep.mTouchName; - mSitName = nodep.mSitName; - mCreationDate = nodep.mCreationDate; - - mSilhouetteVertices = nodep.mSilhouetteVertices; - mSilhouetteNormals = nodep.mSilhouetteNormals; - mSilhouetteExists = nodep.mSilhouetteExists; - mObject = nodep.mObject; - - std::vector::const_iterator color_iter; - mSavedColors.clear(); - for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter) - { - mSavedColors.push_back(*color_iter); - } - mSavedShinyColors.clear(); - for (color_iter = nodep.mSavedShinyColors.begin(); color_iter != nodep.mSavedShinyColors.end(); ++color_iter) - { - mSavedShinyColors.push_back(*color_iter); - } - - saveTextures(nodep.mSavedTextures); + mTESelectMask = nodep.mTESelectMask; + mLastTESelected = nodep.mLastTESelected; + + mIndividualSelection = nodep.mIndividualSelection; + + mValid = nodep.mValid; + mTransient = nodep.mTransient; + mPermissions = new LLPermissions(*nodep.mPermissions); + mSaleInfo = nodep.mSaleInfo;; + mAggregatePerm = nodep.mAggregatePerm; + mAggregateTexturePerm = nodep.mAggregateTexturePerm; + mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner; + mName = nodep.mName; + mDescription = nodep.mDescription; + mCategory = nodep.mCategory; + mInventorySerial = 0; + mSavedPositionLocal = nodep.mSavedPositionLocal; + mSavedPositionGlobal = nodep.mSavedPositionGlobal; + mSavedScale = nodep.mSavedScale; + mSavedRotation = nodep.mSavedRotation; + mDuplicated = nodep.mDuplicated; + mDuplicatePos = nodep.mDuplicatePos; + mDuplicateRot = nodep.mDuplicateRot; + mItemID = nodep.mItemID; + mFolderID = nodep.mFolderID; + mFromTaskID = nodep.mFromTaskID; + mTouchName = nodep.mTouchName; + mSitName = nodep.mSitName; + mCreationDate = nodep.mCreationDate; + + mSilhouetteVertices = nodep.mSilhouetteVertices; + mSilhouetteNormals = nodep.mSilhouetteNormals; + mSilhouetteExists = nodep.mSilhouetteExists; + mObject = nodep.mObject; + + std::vector::const_iterator color_iter; + mSavedColors.clear(); + for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter) + { + mSavedColors.push_back(*color_iter); + } + mSavedShinyColors.clear(); + for (color_iter = nodep.mSavedShinyColors.begin(); color_iter != nodep.mSavedShinyColors.end(); ++color_iter) + { + mSavedShinyColors.push_back(*color_iter); + } + + saveTextures(nodep.mSavedTextures); saveGLTFMaterials(nodep.mSavedGLTFMaterialIds, nodep.mSavedGLTFOverrideMaterials); } @@ -6701,31 +6701,31 @@ LLSelectNode::~LLSelectNode() } delete mPermissions; - mPermissions = NULL; + mPermissions = NULL; } void LLSelectNode::selectAllTEs(BOOL b) { - mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0; - mLastTESelected = 0; + mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0; + mLastTESelected = 0; } void LLSelectNode::selectTE(S32 te_index, BOOL selected) { - if (te_index < 0 || te_index >= SELECT_MAX_TES) - { - return; - } - S32 mask = 0x1 << te_index; - if(selected) - { - mTESelectMask |= mask; - } - else - { - mTESelectMask &= ~mask; - } - mLastTESelected = te_index; + if (te_index < 0 || te_index >= SELECT_MAX_TES) + { + return; + } + S32 mask = 0x1 << te_index; + if(selected) + { + mTESelectMask |= mask; + } + else + { + mTESelectMask &= ~mask; + } + mLastTESelected = te_index; } void LLSelectNode::selectGLTFNode(S32 node_index, S32 primitive_index, bool selected) @@ -6735,414 +6735,414 @@ void LLSelectNode::selectGLTFNode(S32 node_index, S32 primitive_index, bool sele return; } - mSelectedGLTFNode = node_index; - mSelectedGLTFPrimitive = primitive_index; -} + mSelectedGLTFNode = node_index; + mSelectedGLTFPrimitive = primitive_index; +} + +BOOL LLSelectNode::isTESelected(S32 te_index) const +{ + if (te_index < 0 || te_index >= mObject->getNumTEs()) + { + return FALSE; + } + return (mTESelectMask & (0x1 << te_index)) != 0; +} + +S32 LLSelectNode::getLastSelectedTE() const +{ + if (!isTESelected(mLastTESelected)) + { + return -1; + } + return mLastTESelected; +} + +LLViewerObject* LLSelectNode::getObject() +{ + if (!mObject) + { + return NULL; + } + else if (mObject->isDead()) + { + mObject = NULL; + } + return mObject; +} + +void LLSelectNode::setObject(LLViewerObject* object) +{ + mObject = object; +} + +void LLSelectNode::saveColors() +{ + if (mObject.notNull()) + { + mSavedColors.clear(); + for (S32 i = 0; i < mObject->getNumTEs(); i++) + { + const LLTextureEntry* tep = mObject->getTE(i); + mSavedColors.push_back(tep->getColor()); + } + } +} + +void LLSelectNode::saveShinyColors() +{ + if (mObject.notNull()) + { + mSavedShinyColors.clear(); + for (S32 i = 0; i < mObject->getNumTEs(); i++) + { + const LLMaterialPtr mat = mObject->getTE(i)->getMaterialParams(); + if (!mat.isNull()) + { + mSavedShinyColors.push_back(mat->getSpecularLightColor()); + } + else + { + mSavedShinyColors.push_back(LLColor4::white); + } + } + } +} + +void LLSelectNode::saveTextures(const uuid_vec_t& textures) +{ + if (mObject.notNull()) + { + mSavedTextures.clear(); + + for (uuid_vec_t::const_iterator texture_it = textures.begin(); + texture_it != textures.end(); ++texture_it) + { + mSavedTextures.push_back(*texture_it); + } + } +} + +void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials) +{ + if (mObject.notNull()) + { + mSavedGLTFMaterialIds.clear(); + mSavedGLTFOverrideMaterials.clear(); + + for (uuid_vec_t::const_iterator materials_it = materials.begin(); + materials_it != materials.end(); ++materials_it) + { + mSavedGLTFMaterialIds.push_back(*materials_it); + } + + for (gltf_materials_vec_t::const_iterator mat_it = override_materials.begin(); + mat_it != override_materials.end(); ++mat_it) + { + mSavedGLTFOverrideMaterials.push_back(*mat_it); + } + } +} + +void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) +{ + mTextureScaleRatios.clear(); + + if (mObject.notNull()) + { + + LLVector3 scale = mObject->getScale(); + + for (U8 i = 0; i < mObject->getNumTEs(); i++) + { + F32 diffuse_s = 1.0f; + F32 diffuse_t = 1.0f; + + LLVector3 v; + const LLTextureEntry* tep = mObject->getTE(i); + if (!tep) + continue; + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); + + tep->getScale(&diffuse_s,&diffuse_t); + + if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) + { + v.mV[s_axis] = diffuse_s*scale.mV[s_axis]; + v.mV[t_axis] = diffuse_t*scale.mV[t_axis]; + mTextureScaleRatios.push_back(v); + } + else + { + v.mV[s_axis] = diffuse_s/scale.mV[s_axis]; + v.mV[t_axis] = diffuse_t/scale.mV[t_axis]; + mTextureScaleRatios.push_back(v); + } + } + } +} + + +// This implementation should be similar to LLTask::allowOperationOnTask +BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const +{ + // Extract ownership. + BOOL object_is_group_owned = FALSE; + LLUUID object_owner_id; + mPermissions->getOwnership(object_owner_id, object_is_group_owned); + + // Operations on invalid or public objects is not allowed. + if (!mObject || (mObject->isDead()) || !mPermissions->isOwned()) + { + return FALSE; + } + + // The transfer permissions can never be given through proxy. + if (PERM_TRANSFER == op) + { + // The owner of an agent-owned object can transfer to themselves. + if ( !object_is_group_owned + && (gAgent.getID() == object_owner_id) ) + { + return TRUE; + } + else + { + // Otherwise check aggregate permissions. + return mObject->permTransfer(); + } + } + + if (PERM_MOVE == op + || PERM_MODIFY == op) + { + // only owners can move or modify their attachments + // no proxy allowed. + if (mObject->isAttachment() && object_owner_id != gAgent.getID()) + { + return FALSE; + } + } + + // Calculate proxy_agent_id and group_id to use for permissions checks. + // proxy_agent_id may be set to the object owner through group powers. + // group_id can only be set to the object's group, if the agent is in that group. + LLUUID group_id = LLUUID::null; + LLUUID proxy_agent_id = gAgent.getID(); + + // Gods can always operate. + if (gAgent.isGodlike()) + { + return TRUE; + } + + // Check if the agent is in the same group as the object. + LLUUID object_group_id = mPermissions->getGroup(); + if (object_group_id.notNull() && + gAgent.isInGroup(object_group_id)) + { + // Assume the object's group during this operation. + group_id = object_group_id; + } + + // Only allow proxy powers for PERM_COPY if the actual agent can + // receive the item (ie has PERM_TRANSFER permissions). + // NOTE: op == PERM_TRANSFER has already been handled, but if + // that ever changes we need to BLOCK proxy powers for PERM_TRANSFER. DK 03/28/06 + if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID())) + { + // Check if the agent can assume ownership through group proxy or agent-granted proxy. + if ( ( object_is_group_owned + && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power)) + // Only allow proxy for move, modify, and copy. + || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op) + && (!object_is_group_owned + && gAgent.isGrantedProxy(*mPermissions)))) + { + // This agent is able to assume the ownership role for this operation. + proxy_agent_id = object_owner_id; + } + } + + // We now have max ownership information. + if (PERM_OWNER == op) + { + // This this was just a check for ownership, we can now return the answer. + return (proxy_agent_id == object_owner_id ? TRUE : FALSE); + } + + // check permissions to see if the agent can operate + return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id)); +} + +//----------------------------------------------------------------------------- +// renderOneSilhouette() +//----------------------------------------------------------------------------- +void LLSelectNode::renderOneSilhouette(const LLColor4 &color) +{ + LLViewerObject* objectp = getObject(); + if (!objectp) + { + return; + } + + LLDrawable* drawable = objectp->mDrawable; + if(!drawable) + { + return; + } + + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj && vobj->isMesh()) + { + //This check (if(...)) with assert here just for ensure that this situation will not happens, and can be removed later. For example on the next release. + llassert(!"renderOneWireframe() was removed SL-10194"); + return; + } + + if (!mSilhouetteExists) + { + return; + } -BOOL LLSelectNode::isTESelected(S32 te_index) const -{ - if (te_index < 0 || te_index >= mObject->getNumTEs()) - { - return FALSE; - } - return (mTESelectMask & (0x1 << te_index)) != 0; -} + BOOL is_hud_object = objectp->isHUDAttachment(); -S32 LLSelectNode::getLastSelectedTE() const -{ - if (!isTESelected(mLastTESelected)) - { - return -1; - } - return mLastTESelected; -} + if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size()) + { + return; + } -LLViewerObject* LLSelectNode::getObject() -{ - if (!mObject) - { - return NULL; - } - else if (mObject->isDead()) - { - mObject = NULL; - } - return mObject; -} -void LLSelectNode::setObject(LLViewerObject* object) -{ - mObject = object; -} + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; -void LLSelectNode::saveColors() -{ - if (mObject.notNull()) - { - mSavedColors.clear(); - for (S32 i = 0; i < mObject->getNumTEs(); i++) - { - const LLTextureEntry* tep = mObject->getTE(i); - mSavedColors.push_back(tep->getColor()); - } - } -} + if (shader) + { //use UI program for selection highlights (texture color modulated by vertex color) + gUIProgram.bind(); + } -void LLSelectNode::saveShinyColors() -{ - if (mObject.notNull()) - { - mSavedShinyColors.clear(); - for (S32 i = 0; i < mObject->getNumTEs(); i++) - { - const LLMaterialPtr mat = mObject->getTE(i)->getMaterialParams(); - if (!mat.isNull()) - { - mSavedShinyColors.push_back(mat->getSpecularLightColor()); - } - else - { - mSavedShinyColors.push_back(LLColor4::white); - } - } - } -} + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.pushUIMatrix(); + gGL.loadUIIdentity(); -void LLSelectNode::saveTextures(const uuid_vec_t& textures) -{ - if (mObject.notNull()) - { - mSavedTextures.clear(); + if (!is_hud_object) + { + gGL.loadIdentity(); + gGL.multMatrix(gGLModelView); + } - for (uuid_vec_t::const_iterator texture_it = textures.begin(); - texture_it != textures.end(); ++texture_it) - { - mSavedTextures.push_back(*texture_it); - } - } -} -void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials) -{ - if (mObject.notNull()) + if (drawable->isActive()) { - mSavedGLTFMaterialIds.clear(); - mSavedGLTFOverrideMaterials.clear(); + gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix); + } - for (uuid_vec_t::const_iterator materials_it = materials.begin(); - materials_it != materials.end(); ++materials_it) + LLVolume *volume = objectp->getVolume(); + if (volume) + { + F32 silhouette_thickness; + if (isAgentAvatarValid() && is_hud_object) { - mSavedGLTFMaterialIds.push_back(*materials_it); + silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom; } - - for (gltf_materials_vec_t::const_iterator mat_it = override_materials.begin(); - mat_it != override_materials.end(); ++mat_it) + else { - mSavedGLTFOverrideMaterials.push_back(*mat_it); + LLVector3 view_vector = LLViewerCamera::getInstance()->getOrigin() - objectp->getRenderPosition(); + silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV()); } - } -} - -void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) -{ - mTextureScaleRatios.clear(); - - if (mObject.notNull()) - { - - LLVector3 scale = mObject->getScale(); - - for (U8 i = 0; i < mObject->getNumTEs(); i++) - { - F32 diffuse_s = 1.0f; - F32 diffuse_t = 1.0f; - - LLVector3 v; - const LLTextureEntry* tep = mObject->getTE(i); - if (!tep) - continue; - - U32 s_axis = VX; - U32 t_axis = VY; - LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); - - tep->getScale(&diffuse_s,&diffuse_t); - - if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) - { - v.mV[s_axis] = diffuse_s*scale.mV[s_axis]; - v.mV[t_axis] = diffuse_t*scale.mV[t_axis]; - mTextureScaleRatios.push_back(v); - } - else - { - v.mV[s_axis] = diffuse_s/scale.mV[s_axis]; - v.mV[t_axis] = diffuse_t/scale.mV[t_axis]; - mTextureScaleRatios.push_back(v); - } - } - } -} + F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds(); + F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f); + F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f); + F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1)); -// This implementation should be similar to LLTask::allowOperationOnTask -BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const -{ - // Extract ownership. - BOOL object_is_group_owned = FALSE; - LLUUID object_owner_id; - mPermissions->getOwnership(object_owner_id, object_is_group_owned); - - // Operations on invalid or public objects is not allowed. - if (!mObject || (mObject->isDead()) || !mPermissions->isOwned()) - { - return FALSE; - } - - // The transfer permissions can never be given through proxy. - if (PERM_TRANSFER == op) - { - // The owner of an agent-owned object can transfer to themselves. - if ( !object_is_group_owned - && (gAgent.getID() == object_owner_id) ) - { - return TRUE; - } - else - { - // Otherwise check aggregate permissions. - return mObject->permTransfer(); - } - } - - if (PERM_MOVE == op - || PERM_MODIFY == op) - { - // only owners can move or modify their attachments - // no proxy allowed. - if (mObject->isAttachment() && object_owner_id != gAgent.getID()) - { - return FALSE; - } - } - - // Calculate proxy_agent_id and group_id to use for permissions checks. - // proxy_agent_id may be set to the object owner through group powers. - // group_id can only be set to the object's group, if the agent is in that group. - LLUUID group_id = LLUUID::null; - LLUUID proxy_agent_id = gAgent.getID(); - - // Gods can always operate. - if (gAgent.isGodlike()) - { - return TRUE; - } - - // Check if the agent is in the same group as the object. - LLUUID object_group_id = mPermissions->getGroup(); - if (object_group_id.notNull() && - gAgent.isInGroup(object_group_id)) - { - // Assume the object's group during this operation. - group_id = object_group_id; - } - - // Only allow proxy powers for PERM_COPY if the actual agent can - // receive the item (ie has PERM_TRANSFER permissions). - // NOTE: op == PERM_TRANSFER has already been handled, but if - // that ever changes we need to BLOCK proxy powers for PERM_TRANSFER. DK 03/28/06 - if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID())) - { - // Check if the agent can assume ownership through group proxy or agent-granted proxy. - if ( ( object_is_group_owned - && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power)) - // Only allow proxy for move, modify, and copy. - || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op) - && (!object_is_group_owned - && gAgent.isGrantedProxy(*mPermissions)))) - { - // This agent is able to assume the ownership role for this operation. - proxy_agent_id = object_owner_id; - } - } - - // We now have max ownership information. - if (PERM_OWNER == op) - { - // This this was just a check for ownership, we can now return the answer. - return (proxy_agent_id == object_owner_id ? TRUE : FALSE); - } - - // check permissions to see if the agent can operate - return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id)); -} + if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) + { + gGL.flush(); + gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); -//----------------------------------------------------------------------------- -// renderOneSilhouette() -//----------------------------------------------------------------------------- -void LLSelectNode::renderOneSilhouette(const LLColor4 &color) -{ - LLViewerObject* objectp = getObject(); - if (!objectp) - { - return; - } - - LLDrawable* drawable = objectp->mDrawable; - if(!drawable) - { - return; - } - - LLVOVolume* vobj = drawable->getVOVolume(); - if (vobj && vobj->isMesh()) - { - //This check (if(...)) with assert here just for ensure that this situation will not happens, and can be removed later. For example on the next release. - llassert(!"renderOneWireframe() was removed SL-10194"); - return; - } - - if (!mSilhouetteExists) - { - return; - } - - BOOL is_hud_object = objectp->isHUDAttachment(); - - if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size()) - { - return; - } - - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) - { //use UI program for selection highlights (texture color modulated by vertex color) - gUIProgram.bind(); - } - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.pushUIMatrix(); - gGL.loadUIIdentity(); - - if (!is_hud_object) - { - gGL.loadIdentity(); - gGL.multMatrix(gGLModelView); - } - - - if (drawable->isActive()) - { - gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix); - } - - LLVolume *volume = objectp->getVolume(); - if (volume) - { - F32 silhouette_thickness; - if (isAgentAvatarValid() && is_hud_object) - { - silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom; - } - else - { - LLVector3 view_vector = LLViewerCamera::getInstance()->getOrigin() - objectp->getRenderPosition(); - silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV()); - } - F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds(); - - F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f); - F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f); - F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1)); - - if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) - { - gGL.flush(); - gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); gGL.flush(); - gGL.begin(LLRender::LINES); - { - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); - - for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2) - { - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - gGL.texCoord2f( u_coord, v_coord ); - gGL.vertex3fv( mSilhouetteVertices[i].mV); - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - gGL.texCoord2f( u_coord, v_coord ); - gGL.vertex3fv(mSilhouetteVertices[i+1].mV); - } - } + gGL.begin(LLRender::LINES); + { + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); + + for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2) + { + u_coord += u_divisor * LLSelectMgr::sHighlightUScale; + gGL.texCoord2f( u_coord, v_coord ); + gGL.vertex3fv( mSilhouetteVertices[i].mV); + u_coord += u_divisor * LLSelectMgr::sHighlightUScale; + gGL.texCoord2f( u_coord, v_coord ); + gGL.vertex3fv(mSilhouetteVertices[i+1].mV); + } + } gGL.end(); - u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f); - } - - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.begin(LLRender::TRIANGLES); - { - for(S32 i = 0; i < mSilhouetteVertices.size(); i+=2) - { - if (!mSilhouetteNormals[i].isFinite() || - !mSilhouetteNormals[i+1].isFinite()) - { //skip skewed segments - continue; - } - - LLVector3 v[4]; - LLVector2 tc[4]; - v[0] = mSilhouetteVertices[i] + (mSilhouetteNormals[i] * silhouette_thickness); - tc[0].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale); - - v[1] = mSilhouetteVertices[i]; - tc[1].set(u_coord, v_coord); - - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - - v[2] = mSilhouetteVertices[i+1] + (mSilhouetteNormals[i+1] * silhouette_thickness); - tc[2].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale); - - v[3] = mSilhouetteVertices[i+1]; - tc[3].set(u_coord,v_coord); - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - gGL.texCoord2fv(tc[0].mV); - gGL.vertex3fv( v[0].mV ); - - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); - gGL.texCoord2fv( tc[1].mV ); - gGL.vertex3fv( v[1].mV ); - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - gGL.texCoord2fv( tc[2].mV ); - gGL.vertex3fv( v[2].mV ); - - gGL.vertex3fv( v[2].mV ); - - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); - gGL.texCoord2fv( tc[1].mV ); - gGL.vertex3fv( v[1].mV ); - - gGL.texCoord2fv( tc[3].mV ); - gGL.vertex3fv( v[3].mV ); - } - } - gGL.end(); - gGL.flush(); - } - gGL.popMatrix(); - gGL.popUIMatrix(); - - if (shader) - { - shader->bind(); - } + u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f); + } + + gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.begin(LLRender::TRIANGLES); + { + for(S32 i = 0; i < mSilhouetteVertices.size(); i+=2) + { + if (!mSilhouetteNormals[i].isFinite() || + !mSilhouetteNormals[i+1].isFinite()) + { //skip skewed segments + continue; + } + + LLVector3 v[4]; + LLVector2 tc[4]; + v[0] = mSilhouetteVertices[i] + (mSilhouetteNormals[i] * silhouette_thickness); + tc[0].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale); + + v[1] = mSilhouetteVertices[i]; + tc[1].set(u_coord, v_coord); + + u_coord += u_divisor * LLSelectMgr::sHighlightUScale; + + v[2] = mSilhouetteVertices[i+1] + (mSilhouetteNormals[i+1] * silhouette_thickness); + tc[2].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale); + + v[3] = mSilhouetteVertices[i+1]; + tc[3].set(u_coord,v_coord); + + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); + gGL.texCoord2fv(tc[0].mV); + gGL.vertex3fv( v[0].mV ); + + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); + gGL.texCoord2fv( tc[1].mV ); + gGL.vertex3fv( v[1].mV ); + + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); + gGL.texCoord2fv( tc[2].mV ); + gGL.vertex3fv( v[2].mV ); + + gGL.vertex3fv( v[2].mV ); + + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); + gGL.texCoord2fv( tc[1].mV ); + gGL.vertex3fv( v[1].mV ); + + gGL.texCoord2fv( tc[3].mV ); + gGL.vertex3fv( v[3].mV ); + } + } + gGL.end(); + gGL.flush(); + } + gGL.popMatrix(); + gGL.popUIMatrix(); + + if (shader) + { + shader->bind(); + } } // @@ -7152,71 +7152,71 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) // *DEPRECATED: See header comment. void dialog_refresh_all() { - // This is the easiest place to fire the update signal, as it will - // make cleaning up the functions below easier. Also, sometimes entities - // outside the selection manager change properties of selected objects - // and call into this function. Yuck. - LLSelectMgr::getInstance()->mUpdateSignal(); + // This is the easiest place to fire the update signal, as it will + // make cleaning up the functions below easier. Also, sometimes entities + // outside the selection manager change properties of selected objects + // and call into this function. Yuck. + LLSelectMgr::getInstance()->mUpdateSignal(); - // *TODO: Eliminate all calls into outside classes below, make those - // objects register with the update signal. + // *TODO: Eliminate all calls into outside classes below, make those + // objects register with the update signal. - gFloaterTools->dirty(); + gFloaterTools->dirty(); - gMenuObject->needsArrange(); + gMenuObject->needsArrange(); - if( gMenuAttachmentSelf->getVisible() ) - { - gMenuAttachmentSelf->arrange(); - } - if( gMenuAttachmentOther->getVisible() ) - { - gMenuAttachmentOther->arrange(); - } + if( gMenuAttachmentSelf->getVisible() ) + { + gMenuAttachmentSelf->arrange(); + } + if( gMenuAttachmentOther->getVisible() ) + { + gMenuAttachmentOther->arrange(); + } - LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); - if(inspect_instance) - { - inspect_instance->dirty(); - } + LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance("inspect"); + if(inspect_instance) + { + inspect_instance->dirty(); + } - LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel(); - if (panel_task_info) - { - panel_task_info->dirty(); - } + LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel(); + if (panel_task_info) + { + panel_task_info->dirty(); + } } S32 get_family_count(LLViewerObject *parent) { - if (!parent) - { - LL_WARNS() << "Trying to get_family_count on null parent!" << LL_ENDL; - } - S32 count = 1; // for this object - LLViewerObject::const_child_list_t& child_list = parent->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - - if (!child) - { - LL_WARNS() << "Family object has NULL child! Show Doug." << LL_ENDL; - } - else if (child->isDead()) - { - LL_WARNS() << "Family object has dead child object. Show Doug." << LL_ENDL; - } - else - { - if (LLSelectMgr::getInstance()->canSelectObject(child)) - { - count += get_family_count( child ); - } - } - } - return count; + if (!parent) + { + LL_WARNS() << "Trying to get_family_count on null parent!" << LL_ENDL; + } + S32 count = 1; // for this object + LLViewerObject::const_child_list_t& child_list = parent->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + + if (!child) + { + LL_WARNS() << "Family object has NULL child! Show Doug." << LL_ENDL; + } + else if (child->isDead()) + { + LL_WARNS() << "Family object has dead child object. Show Doug." << LL_ENDL; + } + else + { + if (LLSelectMgr::getInstance()->canSelectObject(child)) + { + count += get_family_count( child ); + } + } + } + return count; } //----------------------------------------------------------------------------- @@ -7227,106 +7227,106 @@ S32 get_family_count(LLViewerObject *parent) // ----------------------------------------------------------------------------- void LLSelectMgr::updateSelectionCenter() { - const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection - // center (tractor beam) + const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection + // center (tractor beam) // override any avatar updates received // Works only if avatar was repositioned // and edit floater is visible overrideAvatarUpdates(); - //override any object updates received - //for selected objects - overrideObjectUpdates(); - - LLViewerObject* object = mSelectedObjects->getFirstObject(); - if (!object) - { - // nothing selected, probably grabbing - // Ignore by setting to avatar origin. - mSelectionCenterGlobal.clearVec(); - mShowSelection = FALSE; - mSelectionBBox = LLBBox(); - resetAgentHUDZoom(); - } - else - { - mSelectedObjects->mSelectType = getSelectTypeForObject(object); - - if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) - { - // reset hud ZOOM - resetAgentHUDZoom(); - } - - mShowSelection = FALSE; - LLBBox bbox; - - // have stuff selected - LLVector3d select_center; - // keep a list of jointed objects for showing the joint HUDEffects - - // Initialize the bounding box to the root prim, so the BBox orientation - // matches the root prim's (affecting the orientation of the manipulators). - bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() ); - - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); - iter != mSelectedObjects->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if (!object) - continue; - - LLViewerObject *root = object->getRootEdit(); - if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment - !root->isChild(gAgentAvatarp) && // not the object you're sitting on - !object->isAvatar()) // not another avatar - { - mShowSelection = TRUE; - } - - bbox.addBBoxAgent( object->getBoundingBoxAgent() ); - } - - LLVector3 bbox_center_agent = bbox.getCenterAgent(); - mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); - mSelectionBBox = bbox; - - } - - if ( !(gAgentID == LLUUID::null)) - { - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - if (mShowSelection) - { - LLVector3d select_center_global; - - if( tool->isEditing() ) - { - select_center_global = tool->getEditingPointGlobal(); - } - else - { - select_center_global = mSelectionCenterGlobal; - } - - // Send selection center if moved beyond threshold (used to animate tractor beam) - LLVector3d diff; - diff = select_center_global - mLastSentSelectionCenterGlobal; - - if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD ) - { - // Transmit updated selection center - mLastSentSelectionCenterGlobal = select_center_global; - } - } - } - - // give up edit menu if no objects selected - if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0) - { - gEditMenuHandler = NULL; - } + //override any object updates received + //for selected objects + overrideObjectUpdates(); + + LLViewerObject* object = mSelectedObjects->getFirstObject(); + if (!object) + { + // nothing selected, probably grabbing + // Ignore by setting to avatar origin. + mSelectionCenterGlobal.clearVec(); + mShowSelection = FALSE; + mSelectionBBox = LLBBox(); + resetAgentHUDZoom(); + } + else + { + mSelectedObjects->mSelectType = getSelectTypeForObject(object); + + if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) + { + // reset hud ZOOM + resetAgentHUDZoom(); + } + + mShowSelection = FALSE; + LLBBox bbox; + + // have stuff selected + LLVector3d select_center; + // keep a list of jointed objects for showing the joint HUDEffects + + // Initialize the bounding box to the root prim, so the BBox orientation + // matches the root prim's (affecting the orientation of the manipulators). + bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() ); + + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object) + continue; + + LLViewerObject *root = object->getRootEdit(); + if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment + !root->isChild(gAgentAvatarp) && // not the object you're sitting on + !object->isAvatar()) // not another avatar + { + mShowSelection = TRUE; + } + + bbox.addBBoxAgent( object->getBoundingBoxAgent() ); + } + + LLVector3 bbox_center_agent = bbox.getCenterAgent(); + mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); + mSelectionBBox = bbox; + + } + + if ( !(gAgentID == LLUUID::null)) + { + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + if (mShowSelection) + { + LLVector3d select_center_global; + + if( tool->isEditing() ) + { + select_center_global = tool->getEditingPointGlobal(); + } + else + { + select_center_global = mSelectionCenterGlobal; + } + + // Send selection center if moved beyond threshold (used to animate tractor beam) + LLVector3d diff; + diff = select_center_global - mLastSentSelectionCenterGlobal; + + if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD ) + { + // Transmit updated selection center + mLastSentSelectionCenterGlobal = select_center_global; + } + } + } + + // give up edit menu if no objects selected + if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0) + { + gEditMenuHandler = NULL; + } pauseAssociatedAvatars(); } @@ -7349,7 +7349,7 @@ void LLSelectMgr::pauseAssociatedAvatars() LLViewerObject* object = node->getObject(); if (!object) continue; - + mSelectedObjects->mSelectType = getSelectTypeForObject(object); LLVOAvatar* parent_av = NULL; @@ -7377,40 +7377,40 @@ void LLSelectMgr::pauseAssociatedAvatars() void LLSelectMgr::updatePointAt() { - if (mShowSelection) - { - if (mSelectedObjects->getObjectCount()) - { - LLVector3 select_offset; - const LLPickInfo& pick = gViewerWindow->getLastPick(); - LLViewerObject *click_object = pick.getObject(); - if (click_object && click_object->isSelected()) - { - // clicked on another object in our selection group, use that as target - select_offset.setVec(pick.mObjectOffset); - select_offset.rotVec(~click_object->getRenderRotation()); - - gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset); - gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset); - } - else - { - // didn't click on an object this time, revert to pointing at center of first object - gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject()); - gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject()); - } - } - else - { - gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR); - gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); - } - } - else - { - gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR); - gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); - } + if (mShowSelection) + { + if (mSelectedObjects->getObjectCount()) + { + LLVector3 select_offset; + const LLPickInfo& pick = gViewerWindow->getLastPick(); + LLViewerObject *click_object = pick.getObject(); + if (click_object && click_object->isSelected()) + { + // clicked on another object in our selection group, use that as target + select_offset.setVec(pick.mObjectOffset); + select_offset.rotVec(~click_object->getRenderRotation()); + + gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset); + gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset); + } + else + { + // didn't click on an object this time, revert to pointing at center of first object + gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject()); + gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject()); + } + } + else + { + gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR); + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + } + } + else + { + gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR); + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + } } //----------------------------------------------------------------------------- @@ -7418,7 +7418,7 @@ void LLSelectMgr::updatePointAt() //----------------------------------------------------------------------------- LLBBox LLSelectMgr::getBBoxOfSelection() const { - return mSelectionBBox; + return mSelectionBBox; } @@ -7427,8 +7427,8 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const //----------------------------------------------------------------------------- BOOL LLSelectMgr::canUndo() const { - // Can edit or can move - return const_cast(this)->mSelectedObjects->getFirstUndoEnabledObject() != NULL; // HACK: casting away constness - MG; + // Can edit or can move + return const_cast(this)->mSelectedObjects->getFirstUndoEnabledObject() != NULL; // HACK: casting away constness - MG; } //----------------------------------------------------------------------------- @@ -7436,9 +7436,9 @@ BOOL LLSelectMgr::canUndo() const //----------------------------------------------------------------------------- void LLSelectMgr::undo() { - BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - LLUUID group_id(gAgent.getGroupID()); - sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST); + BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + LLUUID group_id(gAgent.getGroupID()); + sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST); } //----------------------------------------------------------------------------- @@ -7446,7 +7446,7 @@ void LLSelectMgr::undo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canRedo() const { - return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -7454,9 +7454,9 @@ BOOL LLSelectMgr::canRedo() const //----------------------------------------------------------------------------- void LLSelectMgr::redo() { - BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - LLUUID group_id(gAgent.getGroupID()); - sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST); + BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + LLUUID group_id(gAgent.getGroupID()); + sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST); } //----------------------------------------------------------------------------- @@ -7464,22 +7464,22 @@ void LLSelectMgr::redo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canDoDelete() const { - bool can_delete = false; - // This function is "logically const" - it does not change state in - // a way visible outside the selection manager. - LLSelectMgr* self = const_cast(this); - LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject(); - // Note: Can only delete root objects (see getFirstDeleteableObject() for more info) - if (obj!= NULL) - { - // all the faces needs to be selected - if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES )) - { - can_delete = true; - } - } - - return can_delete; + bool can_delete = false; + // This function is "logically const" - it does not change state in + // a way visible outside the selection manager. + LLSelectMgr* self = const_cast(this); + LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject(); + // Note: Can only delete root objects (see getFirstDeleteableObject() for more info) + if (obj!= NULL) + { + // all the faces needs to be selected + if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES )) + { + can_delete = true; + } + } + + return can_delete; } //----------------------------------------------------------------------------- @@ -7487,7 +7487,7 @@ BOOL LLSelectMgr::canDoDelete() const //----------------------------------------------------------------------------- void LLSelectMgr::doDelete() { - selectDelete(); + selectDelete(); } //----------------------------------------------------------------------------- @@ -7495,7 +7495,7 @@ void LLSelectMgr::doDelete() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canDeselect() const { - return !mSelectedObjects->isEmpty(); + return !mSelectedObjects->isEmpty(); } //----------------------------------------------------------------------------- @@ -7503,123 +7503,123 @@ BOOL LLSelectMgr::canDeselect() const //----------------------------------------------------------------------------- void LLSelectMgr::deselect() { - deselectAll(); + deselectAll(); } //----------------------------------------------------------------------------- // canDuplicate() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canDuplicate() const { - return const_cast(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- // duplicate() //----------------------------------------------------------------------------- void LLSelectMgr::duplicate() { - LLVector3 offset(0.5f, 0.5f, 0.f); - selectDuplicate(offset, TRUE); + LLVector3 offset(0.5f, 0.5f, 0.f); + selectDuplicate(offset, TRUE); } ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object) { - if (!object) - { - return SELECT_TYPE_WORLD; - } - if (object->isHUDAttachment()) - { - return SELECT_TYPE_HUD; - } - else if (object->isAttachment()) - { - return SELECT_TYPE_ATTACHMENT; - } - else - { - return SELECT_TYPE_WORLD; - } + if (!object) + { + return SELECT_TYPE_WORLD; + } + if (object->isHUDAttachment()) + { + return SELECT_TYPE_HUD; + } + else if (object->isAttachment()) + { + return SELECT_TYPE_ATTACHMENT; + } + else + { + return SELECT_TYPE_WORLD; + } } void LLSelectMgr::validateSelection() { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (!LLSelectMgr::getInstance()->canSelectObject(object)) - { - LLSelectMgr::getInstance()->deselectObjectOnly(object); - } - return true; - } - } func; - getSelection()->applyToObjects(&func); + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (!LLSelectMgr::getInstance()->canSelectObject(object)) + { + LLSelectMgr::getInstance()->deselectObjectOnly(object); + } + return true; + } + } func; + getSelection()->applyToObjects(&func); } BOOL LLSelectMgr::canSelectObject(LLViewerObject* object, BOOL ignore_select_owned) { - // Never select dead objects - if (!object || object->isDead()) - { - return FALSE; - } + // Never select dead objects + if (!object || object->isDead()) + { + return FALSE; + } - if (mForceSelection) - { - return TRUE; - } + if (mForceSelection) + { + return TRUE; + } - if(!ignore_select_owned) - { - if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced()))) - { - // only select my own objects - return FALSE; - } - } + if(!ignore_select_owned) + { + if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || + (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced()))) + { + // only select my own objects + return FALSE; + } + } - // Can't select orphans - if (object->isOrphaned()) return FALSE; + // Can't select orphans + if (object->isOrphaned()) return FALSE; - // Can't select avatars - if (object->isAvatar()) return FALSE; + // Can't select avatars + if (object->isAvatar()) return FALSE; - // Can't select land - if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE; + // Can't select land + if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE; - ESelectType selection_type = getSelectTypeForObject(object); - if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE; + ESelectType selection_type = getSelectTypeForObject(object); + if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE; - return TRUE; + return TRUE; } -BOOL LLSelectMgr::setForceSelection(BOOL force) -{ - std::swap(mForceSelection,force); - return force; +BOOL LLSelectMgr::setForceSelection(BOOL force) +{ + std::swap(mForceSelection,force); + return force; } void LLSelectMgr::resetAgentHUDZoom() { - if (gAgentCamera.mHUDTargetZoom != 1) - { - gAgentCamera.mHUDTargetZoom = 1.f; - gAgentCamera.mHUDCurZoom = 1.f; - } + if (gAgentCamera.mHUDTargetZoom != 1) + { + gAgentCamera.mHUDTargetZoom = 1.f; + gAgentCamera.mHUDCurZoom = 1.f; + } } void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const { - target_zoom = gAgentCamera.mHUDTargetZoom; - current_zoom = gAgentCamera.mHUDCurZoom; + target_zoom = gAgentCamera.mHUDTargetZoom; + current_zoom = gAgentCamera.mHUDCurZoom; } void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) { - gAgentCamera.mHUDTargetZoom = target_zoom; - gAgentCamera.mHUDCurZoom = current_zoom; + gAgentCamera.mHUDTargetZoom = target_zoom; + gAgentCamera.mHUDCurZoom = current_zoom; } ///////////////////////////////////////////////////////////////////////////// @@ -7627,45 +7627,45 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) ///////////////////////////////////////////////////////////////////////////// bool LLObjectSelection::is_root::operator()(LLSelectNode *node) { - LLViewerObject* object = node->getObject(); - return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit()); + LLViewerObject* object = node->getObject(); + return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node) { - LLViewerObject* object = node->getObject(); - return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit()); + LLViewerObject* object = node->getObject(); + return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node) { - LLViewerObject* object = node->getObject(); - return (object != NULL) && (object->isRootEdit()); + LLViewerObject* object = node->getObject(); + return (object != NULL) && (object->isRootEdit()); } -LLObjectSelection::LLObjectSelection() : - LLRefCount(), - mSelectType(SELECT_TYPE_WORLD) +LLObjectSelection::LLObjectSelection() : + LLRefCount(), + mSelectType(SELECT_TYPE_WORLD) { } LLObjectSelection::~LLObjectSelection() { - deleteAllNodes(); + deleteAllNodes(); } void LLObjectSelection::cleanupNodes() { - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ) - { - list_t::iterator curiter = iter++; - LLSelectNode* node = *curiter; - if (node->getObject() == NULL || node->getObject()->isDead()) - { - mList.erase(curiter); - delete node; - } - } + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ) + { + list_t::iterator curiter = iter++; + LLSelectNode* node = *curiter; + if (node->getObject() == NULL || node->getObject()->isDead()) + { + mList.erase(curiter); + delete node; + } + } } void LLObjectSelection::updateEffects() @@ -7674,56 +7674,56 @@ void LLObjectSelection::updateEffects() S32 LLObjectSelection::getNumNodes() { - return mList.size(); + return mList.size(); } void LLObjectSelection::addNode(LLSelectNode *nodep) { - llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); - mList.push_front(nodep); - mSelectNodeMap[nodep->getObject()] = nodep; + llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + mList.push_front(nodep); + mSelectNodeMap[nodep->getObject()] = nodep; } void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep) { - llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); - mList.push_back(nodep); - mSelectNodeMap[nodep->getObject()] = nodep; + llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + mList.push_back(nodep); + mSelectNodeMap[nodep->getObject()] = nodep; } void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep) { - mList.remove(nodep); - mList.push_front(nodep); + mList.remove(nodep); + mList.push_front(nodep); } void LLObjectSelection::removeNode(LLSelectNode *nodep) { - mSelectNodeMap.erase(nodep->getObject()); - if (nodep->getObject() == mPrimaryObject) - { - mPrimaryObject = NULL; - } - nodep->setObject(NULL); // Will get erased in cleanupNodes() - mList.remove(nodep); + mSelectNodeMap.erase(nodep->getObject()); + if (nodep->getObject() == mPrimaryObject) + { + mPrimaryObject = NULL; + } + nodep->setObject(NULL); // Will get erased in cleanupNodes() + mList.remove(nodep); } void LLObjectSelection::deleteAllNodes() { - std::for_each(mList.begin(), mList.end(), DeletePointer()); - mList.clear(); - mSelectNodeMap.clear(); - mPrimaryObject = NULL; + std::for_each(mList.begin(), mList.end(), DeletePointer()); + mList.clear(); + mSelectNodeMap.clear(); + mPrimaryObject = NULL; } LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) { - std::map, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp); - if (found_it != mSelectNodeMap.end()) - { - return found_it->second; - } - return NULL; + std::map, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp); + if (found_it != mSelectNodeMap.end()) + { + return found_it->second; + } + return NULL; } //----------------------------------------------------------------------------- @@ -7731,7 +7731,7 @@ LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) //----------------------------------------------------------------------------- BOOL LLObjectSelection::isEmpty() const { - return (mList.size() == 0); + return (mList.size() == 0); } @@ -7740,119 +7740,119 @@ BOOL LLObjectSelection::isEmpty() const //----------------------------------------------------------------------------- S32 LLObjectSelection::getObjectCount() { - cleanupNodes(); - S32 count = mList.size(); + cleanupNodes(); + S32 count = mList.size(); - return count; + return count; } F32 LLObjectSelection::getSelectedObjectCost() { - cleanupNodes(); - F32 cost = 0.f; + cleanupNodes(); + F32 cost = 0.f; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object) - { - cost += object->getObjectCost(); - } - } + if (object) + { + cost += object->getObjectCost(); + } + } - return cost; + return cost; } F32 LLObjectSelection::getSelectedLinksetCost() { - cleanupNodes(); - F32 cost = 0.f; - - std::set me_roots; - - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object && !object->isAttachment()) - { - LLViewerObject* root = static_cast(object->getRoot()); - if (root) - { - if (me_roots.find(root) == me_roots.end()) - { - me_roots.insert(root); - cost += root->getLinksetCost(); - } - } - } - } - - return cost; + cleanupNodes(); + F32 cost = 0.f; + + std::set me_roots; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object && !object->isAttachment()) + { + LLViewerObject* root = static_cast(object->getRoot()); + if (root) + { + if (me_roots.find(root) == me_roots.end()) + { + me_roots.insert(root); + cost += root->getLinksetCost(); + } + } + } + } + + return cost; } F32 LLObjectSelection::getSelectedPhysicsCost() { - cleanupNodes(); - F32 cost = 0.f; + cleanupNodes(); + F32 cost = 0.f; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object) - { - cost += object->getPhysicsCost(); - } - } + if (object) + { + cost += object->getPhysicsCost(); + } + } - return cost; + return cost; } -F32 LLObjectSelection::getSelectedLinksetPhysicsCost() -{ - cleanupNodes(); - F32 cost = 0.f; - - std::set me_roots; - - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object) - { - LLViewerObject* root = static_cast(object->getRoot()); - if (root) - { - if (me_roots.find(root) == me_roots.end()) - { - me_roots.insert(root); - cost += root->getLinksetPhysicsCost(); - } - } - } - } - - return cost; +F32 LLObjectSelection::getSelectedLinksetPhysicsCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + std::set me_roots; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + LLViewerObject* root = static_cast(object->getRoot()); + if (root) + { + if (me_roots.find(root) == me_roots.end()) + { + me_roots.insert(root); + cost += root->getLinksetPhysicsCost(); + } + } + } + } + + return cost; } F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* visible_bytes) { - F32 cost = 0.f; - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object) - { - cost += object->getStreamingCost(); + F32 cost = 0.f; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + cost += object->getStreamingCost(); S32 bytes = 0; S32 visible = 0; @@ -7862,38 +7862,38 @@ F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* vis bytes = costs.getSizeTotal(); visible = costs.getSizeByLOD(object->getLOD()); } - if (total_bytes) - { - *total_bytes += bytes; - } + if (total_bytes) + { + *total_bytes += bytes; + } - if (visible_bytes) - { - *visible_bytes += visible; - } - } - } + if (visible_bytes) + { + *visible_bytes += visible; + } + } + } - return cost; + return cost; } U32 LLObjectSelection::getSelectedObjectTriangleCount(S32* vcount) { - U32 count = 0; - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - - if (object) - { - S32 vt = 0; - count += object->getTriangleCount(&vt); - *vcount += vt; - } - } + U32 count = 0; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + S32 vt = 0; + count += object->getTriangleCount(&vt); + *vcount += vt; + } + } - return count; + return count; } S32 LLObjectSelection::getSelectedObjectRenderCost() @@ -7903,65 +7903,65 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() typedef std::set uuid_list_t; uuid_list_t computed_objects; - typedef std::list > child_list_t; - typedef const child_list_t const_child_list_t; + typedef std::list > child_list_t; + typedef const child_list_t const_child_list_t; - // add render cost of complete linksets first, to get accurate texture counts + // add render cost of complete linksets first, to get accurate texture counts for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) { LLSelectNode* node = *iter; - + LLVOVolume* object = (LLVOVolume*)node->getObject(); if (object && object->isRootEdit()) { - cost += object->getRenderCost(textures); - computed_objects.insert(object->getID()); - - const_child_list_t children = object->getChildren(); - for (const_child_list_t::const_iterator child_iter = children.begin(); - child_iter != children.end(); - ++child_iter) - { - LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast( child_obj ); - if (child) - { - cost += child->getRenderCost(textures); - computed_objects.insert(child->getID()); - } - } - - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += LLVOVolume::getTextureCost(*iter); - } - - textures.clear(); + cost += object->getRenderCost(textures); + computed_objects.insert(object->getID()); + + const_child_list_t children = object->getChildren(); + for (const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) + { + LLViewerObject* child_obj = *child_iter; + LLVOVolume *child = dynamic_cast( child_obj ); + if (child) + { + cost += child->getRenderCost(textures); + computed_objects.insert(child->getID()); + } + } + + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += LLVOVolume::getTextureCost(*iter); + } + + textures.clear(); } } - - // add any partial linkset objects, texture cost may be slightly misleading - for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) - { - LLSelectNode* node = *iter; - LLVOVolume* object = (LLVOVolume*)node->getObject(); - - if (object && computed_objects.find(object->getID()) == computed_objects.end() ) - { - cost += object->getRenderCost(textures); - computed_objects.insert(object->getID()); - } - - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += LLVOVolume::getTextureCost(*iter); - } - - textures.clear(); - } + + // add any partial linkset objects, texture cost may be slightly misleading + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = (LLVOVolume*)node->getObject(); + + if (object && computed_objects.find(object->getID()) == computed_objects.end() ) + { + cost += object->getRenderCost(textures); + computed_objects.insert(object->getID()); + } + + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += LLVOVolume::getTextureCost(*iter); + } + + textures.clear(); + } return cost; } @@ -7971,23 +7971,23 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() //----------------------------------------------------------------------------- S32 LLObjectSelection::getTECount() { - S32 count = 0; - for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if (!object) - continue; - S32 num_tes = object->getNumTEs(); - for (S32 te = 0; te < num_tes; te++) - { - if (node->isTESelected(te)) - { - ++count; - } - } - } - return count; + S32 count = 0; + for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object) + continue; + S32 num_tes = object->getNumTEs(); + for (S32 te = 0; te < num_tes; te++) + { + if (node->isTESelected(te)) + { + ++count; + } + } + } + return count; } //----------------------------------------------------------------------------- @@ -7995,27 +7995,27 @@ S32 LLObjectSelection::getTECount() //----------------------------------------------------------------------------- S32 LLObjectSelection::getRootObjectCount() { - S32 count = 0; - for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++) - { - ++count; - } - return count; + S32 count = 0; + for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++) + { + ++count; + } + return count; } bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func) { - bool result = true; - for (iterator iter = begin(); iter != end(); ) - { - iterator nextiter = iter++; - LLViewerObject* object = (*nextiter)->getObject(); - if (!object) - continue; - bool r = func->apply(object); - result = result && r; - } - return result; + bool result = true; + for (iterator iter = begin(); iter != end(); ) + { + iterator nextiter = iter++; + LLViewerObject* object = (*nextiter)->getObject(); + if (!object) + continue; + bool r = func->apply(object); + result = result && r; + } + return result; } bool LLObjectSelection::checkAnimatedObjectEstTris() @@ -8023,19 +8023,19 @@ bool LLObjectSelection::checkAnimatedObjectEstTris() F32 est_tris = 0; F32 max_tris = 0; S32 anim_count = 0; - for (root_iterator iter = root_begin(); iter != root_end(); ++iter) - { - LLViewerObject* object = (*iter)->getObject(); - if (!object) - continue; + for (root_iterator iter = root_begin(); iter != root_end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + if (!object) + continue; if (object->isAnimatedObject()) { anim_count++; } est_tris += object->recursiveGetEstTrianglesMax(); max_tris = llmax((F32)max_tris,(F32)object->getAnimatedObjectMaxTris()); - } - return anim_count==0 || est_tris <= max_tris; + } + return anim_count==0 || est_tris <= max_tris; } bool LLObjectSelection::checkAnimatedObjectLinkable() @@ -8045,101 +8045,101 @@ bool LLObjectSelection::checkAnimatedObjectLinkable() bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly) { - bool result = firstonly ? false : true; - for (root_iterator iter = root_begin(); iter != root_end(); ) - { - root_iterator nextiter = iter++; - LLViewerObject* object = (*nextiter)->getObject(); - if (!object) - continue; - bool r = func->apply(object); - if (firstonly && r) - return true; - else - result = result && r; - } - return result; + bool result = firstonly ? false : true; + for (root_iterator iter = root_begin(); iter != root_end(); ) + { + root_iterator nextiter = iter++; + LLViewerObject* object = (*nextiter)->getObject(); + if (!object) + continue; + bool r = func->apply(object); + if (firstonly && r) + return true; + else + result = result && r; + } + return result; } bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly) { - bool result = firstonly ? false : true; - for (iterator iter = begin(); iter != end(); ) - { - iterator nextiter = iter++; - LLSelectNode* node = *nextiter; - LLViewerObject* object = (*nextiter)->getObject(); - if (!object) - continue; - S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces - for (S32 te = 0; te < num_tes; ++te) - { - if (node->isTESelected(te)) - { - bool r = func->apply(object, te); - if (firstonly && r) - return true; - else - result = result && r; - } - } - } - return result; + bool result = firstonly ? false : true; + for (iterator iter = begin(); iter != end(); ) + { + iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + LLViewerObject* object = (*nextiter)->getObject(); + if (!object) + continue; + S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + bool r = func->apply(object, te); + if (firstonly && r) + return true; + else + result = result && r; + } + } + } + return result; } bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly) { - bool result = firstonly ? false : true; - for (iterator iter = begin(); iter != end(); ) - { - iterator nextiter = iter++; - LLSelectNode* node = *nextiter; - bool r = func->apply(node); - if (firstonly && r) - return true; - else - result = result && r; - } - return result; + bool result = firstonly ? false : true; + for (iterator iter = begin(); iter != end(); ) + { + iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + bool r = func->apply(node); + if (firstonly && r) + return true; + else + result = result && r; + } + return result; } bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly) { - bool result = firstonly ? false : true; - for (root_iterator iter = root_begin(); iter != root_end(); ) - { - root_iterator nextiter = iter++; - LLSelectNode* node = *nextiter; - bool r = func->apply(node); - if (firstonly && r) - return true; - else - result = result && r; - } - return result; + bool result = firstonly ? false : true; + for (root_iterator iter = root_begin(); iter != root_end(); ) + { + root_iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + bool r = func->apply(node); + if (firstonly && r) + return true; + else + result = result && r; + } + return result; } BOOL LLObjectSelection::isMultipleTESelected() { - BOOL te_selected = FALSE; - // ...all faces - for (LLObjectSelection::iterator iter = begin(); - iter != end(); iter++) - { - LLSelectNode* nodep = *iter; - for (S32 i = 0; i < SELECT_MAX_TES; i++) - { - if(nodep->isTESelected(i)) - { - if(te_selected) - { - return TRUE; - } - te_selected = TRUE; - } - } - } - return FALSE; + BOOL te_selected = FALSE; + // ...all faces + for (LLObjectSelection::iterator iter = begin(); + iter != end(); iter++) + { + LLSelectNode* nodep = *iter; + for (S32 i = 0; i < SELECT_MAX_TES; i++) + { + if(nodep->isTESelected(i)) + { + if(te_selected) + { + return TRUE; + } + te_selected = TRUE; + } + } + } + return FALSE; } //----------------------------------------------------------------------------- @@ -8147,7 +8147,7 @@ BOOL LLObjectSelection::isMultipleTESelected() //----------------------------------------------------------------------------- BOOL LLObjectSelection::contains(LLViewerObject* object) { - return findNode(object) != NULL; + return findNode(object) != NULL; } @@ -8156,50 +8156,50 @@ BOOL LLObjectSelection::contains(LLViewerObject* object) //----------------------------------------------------------------------------- BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te) { - if (te == SELECT_ALL_TES) - { - // ...all faces - for (LLObjectSelection::iterator iter = begin(); - iter != end(); iter++) - { - LLSelectNode* nodep = *iter; - if (nodep->getObject() == object) - { - // Optimization - if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL) - { - return TRUE; - } - - BOOL all_selected = TRUE; - for (S32 i = 0; i < object->getNumTEs(); i++) - { - all_selected = all_selected && nodep->isTESelected(i); - } - return all_selected; - } - } - return FALSE; - } - else - { - // ...one face - for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) - { - LLSelectNode* nodep = *iter; - if (nodep->getObject() == object && nodep->isTESelected(te)) - { - return TRUE; - } - } - return FALSE; - } + if (te == SELECT_ALL_TES) + { + // ...all faces + for (LLObjectSelection::iterator iter = begin(); + iter != end(); iter++) + { + LLSelectNode* nodep = *iter; + if (nodep->getObject() == object) + { + // Optimization + if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL) + { + return TRUE; + } + + BOOL all_selected = TRUE; + for (S32 i = 0; i < object->getNumTEs(); i++) + { + all_selected = all_selected && nodep->isTESelected(i); + } + return all_selected; + } + } + return FALSE; + } + else + { + // ...one face + for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) + { + LLSelectNode* nodep = *iter; + if (nodep->getObject() == object && nodep->isTESelected(te)) + { + return TRUE; + } + } + return FALSE; + } } // returns TRUE is any node is currenly worn as an attachment BOOL LLObjectSelection::isAttachment() { - return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD); + return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD); } //----------------------------------------------------------------------------- @@ -8207,19 +8207,19 @@ BOOL LLObjectSelection::isAttachment() //----------------------------------------------------------------------------- LLViewerObject* getSelectedParentObject(LLViewerObject *object) { - LLViewerObject *parent; - while (object && (parent = (LLViewerObject*)object->getParent())) - { - if (parent->isSelected()) - { - object = parent; - } - else - { - break; - } - } - return object; + LLViewerObject *parent; + while (object && (parent = (LLViewerObject*)object->getParent())) + { + if (parent->isSelected()) + { + object = parent; + } + else + { + break; + } + } + return object; } //----------------------------------------------------------------------------- @@ -8227,33 +8227,33 @@ LLViewerObject* getSelectedParentObject(LLViewerObject *object) //----------------------------------------------------------------------------- LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func) { - for (iterator iter = begin(); iter != end(); ++iter) - { - LLSelectNode* node = *iter; - if (func == NULL || func->apply(node)) - { - return node; - } - } - return NULL; + for (iterator iter = begin(); iter != end(); ++iter) + { + LLSelectNode* node = *iter; + if (func == NULL || func->apply(node)) + { + return node; + } + } + return NULL; } LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok) { - for (root_iterator iter = root_begin(); iter != root_end(); ++iter) - { - LLSelectNode* node = *iter; - if (func == NULL || func->apply(node)) - { - return node; - } - } - if (non_root_ok) - { - // Get non root - return getFirstNode(func); - } - return NULL; + for (root_iterator iter = root_begin(); iter != root_end(); ++iter) + { + LLSelectNode* node = *iter; + if (func == NULL || func->apply(node)) + { + return node; + } + } + if (non_root_ok) + { + // Get non root + return getFirstNode(func); + } + return NULL; } @@ -8262,16 +8262,16 @@ LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, B //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent) { - LLSelectNode* res = getFirstNode(func); - if (res && get_parent) - { - return getSelectedParentObject(res->getObject()); - } - else if (res) - { - return res->getObject(); - } - return NULL; + LLSelectNode* res = getFirstNode(func); + if (res && get_parent) + { + return getSelectedParentObject(res->getObject()); + } + else if (res) + { + return res->getObject(); + } + return NULL; } //----------------------------------------------------------------------------- @@ -8279,8 +8279,8 @@ LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstObject() { - LLSelectNode* res = getFirstNode(NULL); - return res ? res->getObject() : NULL; + LLSelectNode* res = getFirstNode(NULL); + return res ? res->getObject() : NULL; } //----------------------------------------------------------------------------- @@ -8288,8 +8288,8 @@ LLViewerObject* LLObjectSelection::getFirstObject() //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok) { - LLSelectNode* res = getFirstRootNode(NULL, non_root_ok); - return res ? res->getObject() : NULL; + LLSelectNode* res = getFirstRootNode(NULL, non_root_ok); + return res ? res->getObject() : NULL; } //----------------------------------------------------------------------------- @@ -8297,16 +8297,16 @@ LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok) //----------------------------------------------------------------------------- LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first) { - struct f : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - return obj && obj->permMove() && !obj->isPermanentEnforced(); - } - } func; - LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func); - return res; + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + return obj && obj->permMove() && !obj->isPermanentEnforced(); + } + } func; + LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func); + return res; } //----------------------------------------------------------------------------- @@ -8314,15 +8314,15 @@ LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first) //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent) { - struct f : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - return obj && obj->permCopy() && !obj->isAttachment(); - } - } func; - return getFirstSelectedObject(&func, get_parent); + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + return obj && obj->permCopy() && !obj->isAttachment(); + } + } func; + return getFirstSelectedObject(&func, get_parent); } //----------------------------------------------------------------------------- @@ -8330,31 +8330,31 @@ LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent) //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstDeleteableObject() { - //RN: don't currently support deletion of child objects, as that requires separating them first - // then derezzing to trash - - struct f : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - // you can delete an object if you are the owner - // or you have permission to modify it. - if( obj && !obj->isPermanentEnforced() && - ( (obj->permModify()) || - (obj->permYouOwner()) || - (!obj->permAnyOwner()) )) // public - { - if( !obj->isAttachment() ) - { - return true; - } - } - return false; - } - } func; - LLSelectNode* node = getFirstNode(&func); - return node ? node->getObject() : NULL; + //RN: don't currently support deletion of child objects, as that requires separating them first + // then derezzing to trash + + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + // you can delete an object if you are the owner + // or you have permission to modify it. + if( obj && !obj->isPermanentEnforced() && + ( (obj->permModify()) || + (obj->permYouOwner()) || + (!obj->permAnyOwner()) )) // public + { + if( !obj->isAttachment() ) + { + return true; + } + } + return false; + } + } func; + LLSelectNode* node = getFirstNode(&func); + return node ? node->getObject() : NULL; } //----------------------------------------------------------------------------- @@ -8362,15 +8362,15 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject() //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent) { - struct f : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - return obj && obj->permModify(); - } - } func; - return getFirstSelectedObject(&func, get_parent); + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + return obj && obj->permModify(); + } + } func; + return getFirstSelectedObject(&func, get_parent); } //----------------------------------------------------------------------------- @@ -8378,15 +8378,15 @@ LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent) //----------------------------------------------------------------------------- LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent) { - struct f : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - return obj && obj->permMove() && !obj->isPermanentEnforced(); - } - } func; - return getFirstSelectedObject(&func, get_parent); + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + return obj && obj->permMove() && !obj->isPermanentEnforced(); + } + } func; + return getFirstSelectedObject(&func, get_parent); } //----------------------------------------------------------------------------- @@ -8411,196 +8411,196 @@ LLViewerObject* LLObjectSelection::getFirstUndoEnabledObject(BOOL get_parent) bool LLSelectMgr::selectionMove(const LLVector3& displ, F32 roll, F32 pitch, F32 yaw, U32 update_type) { - if (update_type == UPD_NONE) - { - return false; - } - - LLVector3 displ_global; - bool update_success = true; - bool update_position = update_type & UPD_POSITION; - bool update_rotation = update_type & UPD_ROTATION; - const bool noedit_linked_parts = !gSavedSettings.getBOOL("EditLinkedParts"); - - if (update_position) - { - // calculate the distance of the object closest to the camera origin - F32 min_dist_squared = F32_MAX; // value will be overridden in the loop - - LLVector3 obj_pos; - for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); - it != getSelection()->root_end(); ++it) - { - obj_pos = (*it)->getObject()->getPositionEdit(); - - F32 obj_dist_squared = dist_vec_squared(obj_pos, LLViewerCamera::getInstance()->getOrigin()); - if (obj_dist_squared < min_dist_squared) - { - min_dist_squared = obj_dist_squared; - } - } - - // factor the distance into the displacement vector. This will get us - // equally visible movements for both close and far away selections. - F32 min_dist = sqrt((F32) sqrtf(min_dist_squared)) / 2; - displ_global.setVec(displ.mV[0] * min_dist, - displ.mV[1] * min_dist, - displ.mV[2] * min_dist); - - // equates to: Displ_global = Displ * M_cam_axes_in_global_frame - displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global); - } - - LLQuaternion new_rot; - if (update_rotation) - { - // let's calculate the rotation around each camera axes - LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis()); - LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis()); - LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis()); - new_rot.setQuat(qx * qy * qz); - } - - LLViewerObject *obj; - S32 obj_count = getSelection()->getObjectCount(); - for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); - it != getSelection()->root_end(); ++it ) - { - obj = (*it)->getObject(); - bool enable_pos = false, enable_rot = false; - bool perm_move = obj->permMove() && !obj->isPermanentEnforced(); - bool perm_mod = obj->permModify(); - - LLVector3d sel_center(getSelectionCenterGlobal()); - - if (update_rotation) - { - enable_rot = perm_move - && ((perm_mod && !obj->isAttachment()) || noedit_linked_parts); - - if (enable_rot) - { - int children_count = obj->getChildren().size(); - if (obj_count > 1 && children_count > 0) - { - // for linked sets, rotate around the group center - const LLVector3 t(obj->getPositionGlobal() - sel_center); - - // Ra = T x R x T^-1 - LLMatrix4 mt; mt.setTranslation(t); - const LLMatrix4 mnew_rot(new_rot); - LLMatrix4 mt_1; mt_1.setTranslation(-t); - mt *= mnew_rot; - mt *= mt_1; - - // Rfin = Rcur * Ra - obj->setRotation(obj->getRotationEdit() * mt.quaternion()); - displ_global += mt.getTranslation(); - } - else - { - obj->setRotation(obj->getRotationEdit() * new_rot); - } - } - else - { - update_success = false; - } - } - - if (update_position) - { - // establish if object can be moved or not - enable_pos = perm_move && !obj->isAttachment() - && (perm_mod || noedit_linked_parts); - - if (enable_pos) - { - obj->setPosition(obj->getPositionEdit() + displ_global); - } - else - { - update_success = false; - } - } - - if (enable_pos && enable_rot && obj->mDrawable.notNull()) - { - gPipeline.markMoved(obj->mDrawable, TRUE); - } - } - - if (update_position && update_success && obj_count > 1) - { - updateSelectionCenter(); - } - - return update_success; + if (update_type == UPD_NONE) + { + return false; + } + + LLVector3 displ_global; + bool update_success = true; + bool update_position = update_type & UPD_POSITION; + bool update_rotation = update_type & UPD_ROTATION; + const bool noedit_linked_parts = !gSavedSettings.getBOOL("EditLinkedParts"); + + if (update_position) + { + // calculate the distance of the object closest to the camera origin + F32 min_dist_squared = F32_MAX; // value will be overridden in the loop + + LLVector3 obj_pos; + for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); + it != getSelection()->root_end(); ++it) + { + obj_pos = (*it)->getObject()->getPositionEdit(); + + F32 obj_dist_squared = dist_vec_squared(obj_pos, LLViewerCamera::getInstance()->getOrigin()); + if (obj_dist_squared < min_dist_squared) + { + min_dist_squared = obj_dist_squared; + } + } + + // factor the distance into the displacement vector. This will get us + // equally visible movements for both close and far away selections. + F32 min_dist = sqrt((F32) sqrtf(min_dist_squared)) / 2; + displ_global.setVec(displ.mV[0] * min_dist, + displ.mV[1] * min_dist, + displ.mV[2] * min_dist); + + // equates to: Displ_global = Displ * M_cam_axes_in_global_frame + displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global); + } + + LLQuaternion new_rot; + if (update_rotation) + { + // let's calculate the rotation around each camera axes + LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis()); + LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis()); + LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis()); + new_rot.setQuat(qx * qy * qz); + } + + LLViewerObject *obj; + S32 obj_count = getSelection()->getObjectCount(); + for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); + it != getSelection()->root_end(); ++it ) + { + obj = (*it)->getObject(); + bool enable_pos = false, enable_rot = false; + bool perm_move = obj->permMove() && !obj->isPermanentEnforced(); + bool perm_mod = obj->permModify(); + + LLVector3d sel_center(getSelectionCenterGlobal()); + + if (update_rotation) + { + enable_rot = perm_move + && ((perm_mod && !obj->isAttachment()) || noedit_linked_parts); + + if (enable_rot) + { + int children_count = obj->getChildren().size(); + if (obj_count > 1 && children_count > 0) + { + // for linked sets, rotate around the group center + const LLVector3 t(obj->getPositionGlobal() - sel_center); + + // Ra = T x R x T^-1 + LLMatrix4 mt; mt.setTranslation(t); + const LLMatrix4 mnew_rot(new_rot); + LLMatrix4 mt_1; mt_1.setTranslation(-t); + mt *= mnew_rot; + mt *= mt_1; + + // Rfin = Rcur * Ra + obj->setRotation(obj->getRotationEdit() * mt.quaternion()); + displ_global += mt.getTranslation(); + } + else + { + obj->setRotation(obj->getRotationEdit() * new_rot); + } + } + else + { + update_success = false; + } + } + + if (update_position) + { + // establish if object can be moved or not + enable_pos = perm_move && !obj->isAttachment() + && (perm_mod || noedit_linked_parts); + + if (enable_pos) + { + obj->setPosition(obj->getPositionEdit() + displ_global); + } + else + { + update_success = false; + } + } + + if (enable_pos && enable_rot && obj->mDrawable.notNull()) + { + gPipeline.markMoved(obj->mDrawable, TRUE); + } + } + + if (update_position && update_success && obj_count > 1) + { + updateSelectionCenter(); + } + + return update_success; } void LLSelectMgr::sendSelectionMove() { - LLSelectNode *node = mSelectedObjects->getFirstRootNode(); - if (node == NULL) - { - return; - } - - //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - - U32 update_type = UPD_POSITION | UPD_ROTATION; - LLViewerRegion *last_region, *curr_region = node->getObject()->getRegion(); - S32 objects_in_this_packet = 0; - - // apply to linked objects if unable to select their individual parts - if (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) - { - // tell simulator to apply to whole linked sets - update_type |= UPD_LINKED_SETS; - } - - // prepare first bulk message - gMessageSystem->newMessage("MultipleObjectUpdate"); - packAgentAndSessionID(&update_type); - - LLViewerObject *obj = NULL; - for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); - it != getSelection()->root_end(); ++it) - { - obj = (*it)->getObject(); - - // note: following code adapted from sendListToRegions() (@3924) - last_region = curr_region; - curr_region = obj->getRegion(); - - // if not simulator or message too big - if (curr_region != last_region - || gMessageSystem->isSendFull(NULL) - || objects_in_this_packet >= MAX_OBJECTS_PER_PACKET) - { - // send sim the current message and start new one - gMessageSystem->sendReliable(last_region->getHost()); - objects_in_this_packet = 0; - gMessageSystem->newMessage("MultipleObjectUpdate"); - packAgentAndSessionID(&update_type); - } - - // add another instance of the body of data - packMultipleUpdate(*it, &update_type); - ++objects_in_this_packet; - } - - // flush remaining messages - if (gMessageSystem->getCurrentSendTotal() > 0) - { - gMessageSystem->sendReliable(curr_region->getHost()); - } - else - { - gMessageSystem->clearMessage(); - } - - //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectNode *node = mSelectedObjects->getFirstRootNode(); + if (node == NULL) + { + return; + } + + //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + + U32 update_type = UPD_POSITION | UPD_ROTATION; + LLViewerRegion *last_region, *curr_region = node->getObject()->getRegion(); + S32 objects_in_this_packet = 0; + + // apply to linked objects if unable to select their individual parts + if (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) + { + // tell simulator to apply to whole linked sets + update_type |= UPD_LINKED_SETS; + } + + // prepare first bulk message + gMessageSystem->newMessage("MultipleObjectUpdate"); + packAgentAndSessionID(&update_type); + + LLViewerObject *obj = NULL; + for (LLObjectSelection::root_iterator it = getSelection()->root_begin(); + it != getSelection()->root_end(); ++it) + { + obj = (*it)->getObject(); + + // note: following code adapted from sendListToRegions() (@3924) + last_region = curr_region; + curr_region = obj->getRegion(); + + // if not simulator or message too big + if (curr_region != last_region + || gMessageSystem->isSendFull(NULL) + || objects_in_this_packet >= MAX_OBJECTS_PER_PACKET) + { + // send sim the current message and start new one + gMessageSystem->sendReliable(last_region->getHost()); + objects_in_this_packet = 0; + gMessageSystem->newMessage("MultipleObjectUpdate"); + packAgentAndSessionID(&update_type); + } + + // add another instance of the body of data + packMultipleUpdate(*it, &update_type); + ++objects_in_this_packet; + } + + // flush remaining messages + if (gMessageSystem->getCurrentSendTotal() > 0) + { + gMessageSystem->sendReliable(curr_region->getHost()); + } + else + { + gMessageSystem->clearMessage(); + } + + //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); } template<> diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 66c794af4c..02c74d0ab0 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -1,25 +1,25 @@ -/** +/** * @file llselectmgr.h * @brief A manager for selected objects and TEs. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,13 +42,13 @@ #include "llbbox.h" #include "llpermissions.h" #include "llcontrol.h" -#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template +#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template #include "llmaterial.h" #include #include #include -#include // boost::make_shared +#include // boost::make_shared class LLMessageSystem; class LLViewerTexture; @@ -56,30 +56,30 @@ class LLColor4; class LLVector3; class LLSelectNode; -const U8 UPD_NONE = 0x00; -const U8 UPD_POSITION = 0x01; -const U8 UPD_ROTATION = 0x02; -const U8 UPD_SCALE = 0x04; -const U8 UPD_LINKED_SETS = 0x08; -const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE +const U8 UPD_NONE = 0x00; +const U8 UPD_POSITION = 0x01; +const U8 UPD_ROTATION = 0x02; +const U8 UPD_SCALE = 0x04; +const U8 UPD_LINKED_SETS = 0x08; +const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE // This is used by the DeRezObject message to determine where to put // derezed tasks. enum EDeRezDestination { - DRD_SAVE_INTO_AGENT_INVENTORY = 0, - DRD_ACQUIRE_TO_AGENT_INVENTORY = 1, // try to leave copy in world - DRD_SAVE_INTO_TASK_INVENTORY = 2, - DRD_ATTACHMENT = 3, - DRD_TAKE_INTO_AGENT_INVENTORY = 4, // delete from world - DRD_FORCE_TO_GOD_INVENTORY = 5, // force take copy - DRD_TRASH = 6, - DRD_ATTACHMENT_TO_INV = 7, - DRD_ATTACHMENT_EXISTS = 8, - DRD_RETURN_TO_OWNER = 9, // back to owner's inventory - DRD_RETURN_TO_LAST_OWNER = 10, // deeded object back to last owner's inventory - - DRD_COUNT = 11 + DRD_SAVE_INTO_AGENT_INVENTORY = 0, + DRD_ACQUIRE_TO_AGENT_INVENTORY = 1, // try to leave copy in world + DRD_SAVE_INTO_TASK_INVENTORY = 2, + DRD_ATTACHMENT = 3, + DRD_TAKE_INTO_AGENT_INVENTORY = 4, // delete from world + DRD_FORCE_TO_GOD_INVENTORY = 5, // force take copy + DRD_TRASH = 6, + DRD_ATTACHMENT_TO_INV = 7, + DRD_ATTACHMENT_EXISTS = 8, + DRD_RETURN_TO_OWNER = 9, // back to owner's inventory + DRD_RETURN_TO_LAST_OWNER = 10, // deeded object back to last owner's inventory + + DRD_COUNT = 11 }; @@ -92,8 +92,8 @@ const S32 SELECT_MAX_TES = 32; // the operation was successful. struct LLSelectedObjectFunctor { - virtual ~LLSelectedObjectFunctor() {}; - virtual bool apply(LLViewerObject* object) = 0; + virtual ~LLSelectedObjectFunctor() {}; + virtual bool apply(LLViewerObject* object) = 0; }; // Do something to all select nodes in the selection manager. @@ -102,63 +102,63 @@ struct LLSelectedObjectFunctor // the operation was successful. struct LLSelectedNodeFunctor { - virtual ~LLSelectedNodeFunctor() {}; - virtual bool apply(LLSelectNode* node) = 0; + virtual ~LLSelectedNodeFunctor() {}; + virtual bool apply(LLSelectNode* node) = 0; }; struct LLSelectedTEFunctor { - virtual ~LLSelectedTEFunctor() {}; - virtual bool apply(LLViewerObject* object, S32 face) = 0; + virtual ~LLSelectedTEFunctor() {}; + virtual bool apply(LLViewerObject* object, S32 face) = 0; }; struct LLSelectedTEMaterialFunctor { - virtual ~LLSelectedTEMaterialFunctor() {}; - virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; + virtual ~LLSelectedTEMaterialFunctor() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; }; template struct LLSelectedTEGetFunctor { - virtual ~LLSelectedTEGetFunctor() {}; - virtual T get(LLViewerObject* object, S32 te) = 0; + virtual ~LLSelectedTEGetFunctor() {}; + virtual T get(LLViewerObject* object, S32 te) = 0; }; template struct LLCheckIdenticalFunctor { - static bool same(const T& a, const T& b, const T& tolerance); + static bool same(const T& a, const T& b, const T& tolerance); }; typedef enum e_send_type { - SEND_ONLY_ROOTS, - SEND_INDIVIDUALS, - SEND_ROOTS_FIRST, // useful for serial undos on linked sets - SEND_CHILDREN_FIRST // useful for serial transforms of linked sets + SEND_ONLY_ROOTS, + SEND_INDIVIDUALS, + SEND_ROOTS_FIRST, // useful for serial undos on linked sets + SEND_CHILDREN_FIRST // useful for serial transforms of linked sets } ESendType; typedef enum e_grid_mode { - GRID_MODE_WORLD, - GRID_MODE_LOCAL, - GRID_MODE_REF_OBJECT + GRID_MODE_WORLD, + GRID_MODE_LOCAL, + GRID_MODE_REF_OBJECT } EGridMode; typedef enum e_action_type { - SELECT_ACTION_TYPE_BEGIN, - SELECT_ACTION_TYPE_PICK, - SELECT_ACTION_TYPE_MOVE, - SELECT_ACTION_TYPE_ROTATE, - SELECT_ACTION_TYPE_SCALE, - NUM_ACTION_TYPES + SELECT_ACTION_TYPE_BEGIN, + SELECT_ACTION_TYPE_PICK, + SELECT_ACTION_TYPE_MOVE, + SELECT_ACTION_TYPE_ROTATE, + SELECT_ACTION_TYPE_SCALE, + NUM_ACTION_TYPES }EActionType; typedef enum e_selection_type { - SELECT_TYPE_WORLD, - SELECT_TYPE_ATTACHMENT, - SELECT_TYPE_HUD + SELECT_TYPE_WORLD, + SELECT_TYPE_ATTACHMENT, + SELECT_TYPE_HUD }ESelectType; typedef std::vector > gltf_materials_vec_t; @@ -169,29 +169,29 @@ const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; class LLSelectNode { public: - LLSelectNode(LLViewerObject* object, BOOL do_glow); - LLSelectNode(const LLSelectNode& nodep); - ~LLSelectNode(); + LLSelectNode(LLViewerObject* object, BOOL do_glow); + LLSelectNode(const LLSelectNode& nodep); + ~LLSelectNode(); - void selectAllTEs(BOOL b); - void selectTE(S32 te_index, BOOL selected); + void selectAllTEs(BOOL b); + void selectTE(S32 te_index, BOOL selected); void selectGLTFNode(S32 node_index, S32 primitive_index, bool selected); - BOOL isTESelected(S32 te_index) const; - bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; } - S32 getLastSelectedTE() const; - S32 getLastOperatedTE() const { return mLastTESelected; } - S32 getTESelectMask() { return mTESelectMask; } - void renderOneSilhouette(const LLColor4 &color); - void setTransient(BOOL transient) { mTransient = transient; } - BOOL isTransient() const { return mTransient; } - LLViewerObject* getObject(); - void setObject(LLViewerObject* object); - // *NOTE: invalidate stored textures and colors when # faces change + BOOL isTESelected(S32 te_index) const; + bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; } + S32 getLastSelectedTE() const; + S32 getLastOperatedTE() const { return mLastTESelected; } + S32 getTESelectMask() { return mTESelectMask; } + void renderOneSilhouette(const LLColor4 &color); + void setTransient(BOOL transient) { mTransient = transient; } + BOOL isTransient() const { return mTransient; } + LLViewerObject* getObject(); + void setObject(LLViewerObject* object); + // *NOTE: invalidate stored textures and colors when # faces change // Used by tools floater's color/texture pickers to restore changes - void saveColors(); - void saveShinyColors(); - void saveTextures(const uuid_vec_t& textures); - void saveTextureScaleRatios(LLRender::eTexIndex index_to_query); + void saveColors(); + void saveShinyColors(); + void saveTextures(const uuid_vec_t& textures); + void saveTextureScaleRatios(LLRender::eTexIndex index_to_query); // GLTF materials are applied to objects by ids, // overrides get applied on top of materials resulting in @@ -200,189 +200,189 @@ public: // overrides get applied in live material editor void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials); - BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; + BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; public: - BOOL mIndividualSelection; // For root objects and objects individually selected - - BOOL mTransient; - BOOL mValid; // is extra information valid? - LLPermissions* mPermissions; - LLSaleInfo mSaleInfo; - LLAggregatePermissions mAggregatePerm; - LLAggregatePermissions mAggregateTexturePerm; - LLAggregatePermissions mAggregateTexturePermOwner; - std::string mName; - std::string mDescription; - LLCategory mCategory; - S16 mInventorySerial; - LLVector3 mSavedPositionLocal; // for interactively modifying object position - LLVector3 mLastPositionLocal; - LLVector3 mLastMoveLocal; - LLVector3d mSavedPositionGlobal; // for interactively modifying object position - LLVector3 mSavedScale; // for interactively modifying object scale - LLVector3 mLastScale; - LLQuaternion mSavedRotation; // for interactively modifying object rotation - LLQuaternion mLastRotation; - BOOL mDuplicated; - LLVector3d mDuplicatePos; - LLQuaternion mDuplicateRot; - LLUUID mItemID; - LLUUID mFolderID; - LLUUID mFromTaskID; - std::string mTouchName; - std::string mSitName; - U64 mCreationDate; - std::vector mSavedColors; - std::vector mSavedShinyColors; - uuid_vec_t mSavedTextures; - uuid_vec_t mSavedGLTFMaterialIds; + BOOL mIndividualSelection; // For root objects and objects individually selected + + BOOL mTransient; + BOOL mValid; // is extra information valid? + LLPermissions* mPermissions; + LLSaleInfo mSaleInfo; + LLAggregatePermissions mAggregatePerm; + LLAggregatePermissions mAggregateTexturePerm; + LLAggregatePermissions mAggregateTexturePermOwner; + std::string mName; + std::string mDescription; + LLCategory mCategory; + S16 mInventorySerial; + LLVector3 mSavedPositionLocal; // for interactively modifying object position + LLVector3 mLastPositionLocal; + LLVector3 mLastMoveLocal; + LLVector3d mSavedPositionGlobal; // for interactively modifying object position + LLVector3 mSavedScale; // for interactively modifying object scale + LLVector3 mLastScale; + LLQuaternion mSavedRotation; // for interactively modifying object rotation + LLQuaternion mLastRotation; + BOOL mDuplicated; + LLVector3d mDuplicatePos; + LLQuaternion mDuplicateRot; + LLUUID mItemID; + LLUUID mFolderID; + LLUUID mFromTaskID; + std::string mTouchName; + std::string mSitName; + U64 mCreationDate; + std::vector mSavedColors; + std::vector mSavedShinyColors; + uuid_vec_t mSavedTextures; + uuid_vec_t mSavedGLTFMaterialIds; gltf_materials_vec_t mSavedGLTFOverrideMaterials; - std::vector mTextureScaleRatios; - std::vector mSilhouetteVertices; // array of vertices to render silhouette of object - std::vector mSilhouetteNormals; // array of normals to render silhouette of object - BOOL mSilhouetteExists; // need to generate silhouette? + std::vector mTextureScaleRatios; + std::vector mSilhouetteVertices; // array of vertices to render silhouette of object + std::vector mSilhouetteNormals; // array of normals to render silhouette of object + BOOL mSilhouetteExists; // need to generate silhouette? S32 mSelectedGLTFNode = -1; S32 mSelectedGLTFPrimitive = -1; protected: - LLPointer mObject; - S32 mTESelectMask; - S32 mLastTESelected; - + LLPointer mObject; + S32 mTESelectMask; + S32 mLastTESelected; + }; class LLObjectSelection : public LLRefCount { - friend class LLSelectMgr; - friend class LLSafeHandle; - friend class LLSelectionCallbackData; + friend class LLSelectMgr; + friend class LLSafeHandle; + friend class LLSelectionCallbackData; protected: - ~LLObjectSelection(); + ~LLObjectSelection(); public: - typedef std::list list_t; - - // Iterators - struct is_non_null - { - bool operator()(LLSelectNode* node) - { - return (node->getObject() != NULL); - } - }; - typedef boost::filter_iterator iterator; - iterator begin() { return iterator(mList.begin(), mList.end()); } - iterator end() { return iterator(mList.end(), mList.end()); } - - struct is_valid - { - bool operator()(LLSelectNode* node) - { - return (node->getObject() != NULL) && node->mValid; - } - }; - typedef boost::filter_iterator valid_iterator; - valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); } - valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); } - - struct is_root - { - bool operator()(LLSelectNode* node); - }; - typedef boost::filter_iterator root_iterator; - root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); } - root_iterator root_end() { return root_iterator(mList.end(), mList.end()); } - - struct is_valid_root - { - bool operator()(LLSelectNode* node); - }; - typedef boost::filter_iterator valid_root_iterator; - valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); } - valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); } - - struct is_root_object - { - bool operator()(LLSelectNode* node); - }; - typedef boost::filter_iterator root_object_iterator; - root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); } - root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); } - + typedef std::list list_t; + + // Iterators + struct is_non_null + { + bool operator()(LLSelectNode* node) + { + return (node->getObject() != NULL); + } + }; + typedef boost::filter_iterator iterator; + iterator begin() { return iterator(mList.begin(), mList.end()); } + iterator end() { return iterator(mList.end(), mList.end()); } + + struct is_valid + { + bool operator()(LLSelectNode* node) + { + return (node->getObject() != NULL) && node->mValid; + } + }; + typedef boost::filter_iterator valid_iterator; + valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); } + valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); } + + struct is_root + { + bool operator()(LLSelectNode* node); + }; + typedef boost::filter_iterator root_iterator; + root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); } + root_iterator root_end() { return root_iterator(mList.end(), mList.end()); } + + struct is_valid_root + { + bool operator()(LLSelectNode* node); + }; + typedef boost::filter_iterator valid_root_iterator; + valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); } + valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); } + + struct is_root_object + { + bool operator()(LLSelectNode* node); + }; + typedef boost::filter_iterator root_object_iterator; + root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); } + root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); } + public: - LLObjectSelection(); - - void updateEffects(); - - BOOL isEmpty() const; - - LLSelectNode* getFirstNode(LLSelectedNodeFunctor* func = NULL); - LLSelectNode* getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE); - LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE); - LLViewerObject* getFirstObject(); - LLViewerObject* getFirstRootObject(BOOL non_root_ok = FALSE); - - LLSelectNode* getFirstMoveableNode(BOOL get_root_first = FALSE); - - LLViewerObject* getFirstEditableObject(BOOL get_parent = FALSE); - LLViewerObject* getFirstCopyableObject(BOOL get_parent = FALSE); - LLViewerObject* getFirstDeleteableObject(); - LLViewerObject* getFirstMoveableObject(BOOL get_parent = FALSE); - LLViewerObject* getFirstUndoEnabledObject(BOOL get_parent = FALSE); - - /// Return the object that lead to this selection, possible a child - LLViewerObject* getPrimaryObject() { return mPrimaryObject; } - - // iterate through texture entries - template bool getSelectedTEValue(LLSelectedTEGetFunctor* func, T& res, bool has_tolerance = false, T tolerance = T()); - template bool isMultipleTEValue(LLSelectedTEGetFunctor* func, const T& ignore_value); - - S32 getNumNodes(); - LLSelectNode* findNode(LLViewerObject* objectp); - - // count members - S32 getObjectCount(); - F32 getSelectedObjectCost(); - F32 getSelectedLinksetCost(); - F32 getSelectedPhysicsCost(); - F32 getSelectedLinksetPhysicsCost(); - S32 getSelectedObjectRenderCost(); - - F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); - U32 getSelectedObjectTriangleCount(S32* vcount = NULL); - - S32 getTECount(); - S32 getRootObjectCount(); - - BOOL isMultipleTESelected(); - BOOL contains(LLViewerObject* object); - BOOL contains(LLViewerObject* object, S32 te); - - // returns TRUE is any node is currenly worn as an attachment - BOOL isAttachment(); + LLObjectSelection(); + + void updateEffects(); + + BOOL isEmpty() const; + + LLSelectNode* getFirstNode(LLSelectedNodeFunctor* func = NULL); + LLSelectNode* getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE); + LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE); + LLViewerObject* getFirstObject(); + LLViewerObject* getFirstRootObject(BOOL non_root_ok = FALSE); + + LLSelectNode* getFirstMoveableNode(BOOL get_root_first = FALSE); + + LLViewerObject* getFirstEditableObject(BOOL get_parent = FALSE); + LLViewerObject* getFirstCopyableObject(BOOL get_parent = FALSE); + LLViewerObject* getFirstDeleteableObject(); + LLViewerObject* getFirstMoveableObject(BOOL get_parent = FALSE); + LLViewerObject* getFirstUndoEnabledObject(BOOL get_parent = FALSE); + + /// Return the object that lead to this selection, possible a child + LLViewerObject* getPrimaryObject() { return mPrimaryObject; } + + // iterate through texture entries + template bool getSelectedTEValue(LLSelectedTEGetFunctor* func, T& res, bool has_tolerance = false, T tolerance = T()); + template bool isMultipleTEValue(LLSelectedTEGetFunctor* func, const T& ignore_value); + + S32 getNumNodes(); + LLSelectNode* findNode(LLViewerObject* objectp); + + // count members + S32 getObjectCount(); + F32 getSelectedObjectCost(); + F32 getSelectedLinksetCost(); + F32 getSelectedPhysicsCost(); + F32 getSelectedLinksetPhysicsCost(); + S32 getSelectedObjectRenderCost(); + + F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); + U32 getSelectedObjectTriangleCount(S32* vcount = NULL); + + S32 getTECount(); + S32 getRootObjectCount(); + + BOOL isMultipleTESelected(); + BOOL contains(LLViewerObject* object); + BOOL contains(LLViewerObject* object, S32 te); + + // returns TRUE is any node is currenly worn as an attachment + BOOL isAttachment(); bool checkAnimatedObjectEstTris(); bool checkAnimatedObjectLinkable(); - - // Apply functors to various subsets of the selected objects - // If firstonly is FALSE, returns the AND of all apply() calls. - // Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit) - bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false); - bool applyToObjects(LLSelectedObjectFunctor* func); - bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false); - bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false); - bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false); - - /* - * Used to apply (no-copy) textures to the selected object or - * selected face/faces of the object. - * This method moves (no-copy) texture to the object's inventory - * and doesn't make copy of the texture for each face. - * Then this only texture is used for all selected faces. - */ - void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); + + // Apply functors to various subsets of the selected objects + // If firstonly is FALSE, returns the AND of all apply() calls. + // Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit) + bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false); + bool applyToObjects(LLSelectedObjectFunctor* func); + bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false); + bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false); + bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false); + + /* + * Used to apply (no-copy) textures to the selected object or + * selected face/faces of the object. + * This method moves (no-copy) texture to the object's inventory + * and doesn't make copy of the texture for each face. + * Then this only texture is used for all selected faces. + */ + void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); /* * Multi-purpose function for applying PBR materials to the * selected object or faces, any combination of copy/mod/transfer @@ -395,24 +395,24 @@ public: */ bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item); - ESelectType getSelectType() const { return mSelectType; } + ESelectType getSelectType() const { return mSelectType; } private: - void addNode(LLSelectNode *nodep); - void addNodeAtEnd(LLSelectNode *nodep); - void moveNodeToFront(LLSelectNode *nodep); - void removeNode(LLSelectNode *nodep); - void deleteAllNodes(); - void cleanupNodes(); + void addNode(LLSelectNode *nodep); + void addNodeAtEnd(LLSelectNode *nodep); + void moveNodeToFront(LLSelectNode *nodep); + void removeNode(LLSelectNode *nodep); + void deleteAllNodes(); + void cleanupNodes(); private: - list_t mList; - const LLObjectSelection &operator=(const LLObjectSelection &); + list_t mList; + const LLObjectSelection &operator=(const LLObjectSelection &); - LLPointer mPrimaryObject; - std::map, LLSelectNode*> mSelectNodeMap; - ESelectType mSelectType; + LLPointer mPrimaryObject; + std::map, LLSelectNode*> mSelectNodeMap; + ESelectType mSelectType; }; typedef LLSafeHandle LLObjectSelectionHandle; @@ -430,70 +430,70 @@ class LLSelectionCallbackData { public: LLSelectionCallbackData(); - LLObjectSelectionHandle getSelection() { return mSelectedObjects; } + LLObjectSelectionHandle getSelection() { return mSelectedObjects; } private: - LLObjectSelectionHandle mSelectedObjects; + LLObjectSelectionHandle mSelectedObjects; }; class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton { public: - static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? - static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? - static BOOL sRenderLightRadius; // do we show the radius of selected lights? - - static F32 sHighlightThickness; - static F32 sHighlightUScale; - static F32 sHighlightVScale; - static F32 sHighlightAlpha; - static F32 sHighlightAlphaTest; - static F32 sHighlightUAnim; - static F32 sHighlightVAnim; - static LLColor4 sSilhouetteParentColor; - static LLColor4 sSilhouetteChildColor; - static LLColor4 sHighlightParentColor; - static LLColor4 sHighlightChildColor; - static LLColor4 sHighlightInspectColor; - static LLColor4 sContextSilhouetteColor; - - LLCachedControl mHideSelectedObjects; - LLCachedControl mRenderHighlightSelections; - LLCachedControl mAllowSelectAvatar; - LLCachedControl mDebugSelectMgr; + static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? + static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? + static BOOL sRenderLightRadius; // do we show the radius of selected lights? + + static F32 sHighlightThickness; + static F32 sHighlightUScale; + static F32 sHighlightVScale; + static F32 sHighlightAlpha; + static F32 sHighlightAlphaTest; + static F32 sHighlightUAnim; + static F32 sHighlightVAnim; + static LLColor4 sSilhouetteParentColor; + static LLColor4 sSilhouetteChildColor; + static LLColor4 sHighlightParentColor; + static LLColor4 sHighlightChildColor; + static LLColor4 sHighlightInspectColor; + static LLColor4 sContextSilhouetteColor; + + LLCachedControl mHideSelectedObjects; + LLCachedControl mRenderHighlightSelections; + LLCachedControl mAllowSelectAvatar; + LLCachedControl mDebugSelectMgr; public: LLSelectMgr(); ~LLSelectMgr(); - static void cleanupGlobals(); + static void cleanupGlobals(); - // LLEditMenuHandler interface - virtual BOOL canUndo() const; - virtual void undo(); + // LLEditMenuHandler interface + virtual BOOL canUndo() const; + virtual void undo(); - virtual BOOL canRedo() const; - virtual void redo(); + virtual BOOL canRedo() const; + virtual void redo(); - virtual BOOL canDoDelete() const; - virtual void doDelete(); + virtual BOOL canDoDelete() const; + virtual void doDelete(); - virtual void deselect(); - virtual BOOL canDeselect() const; + virtual void deselect(); + virtual BOOL canDeselect() const; - virtual void duplicate(); - virtual BOOL canDuplicate() const; + virtual void duplicate(); + virtual BOOL canDuplicate() const; - void clearSelections(); - void update(); - void updateEffects(); // Update HUD effects + void clearSelections(); + void update(); + void updateEffects(); // Update HUD effects - // When we edit object's position/rotation/scale we set local - // overrides and ignore any updates (override received valeus). - // When we send data to server, we send local values and reset - // overrides - void resetObjectOverrides(); - void resetObjectOverrides(LLObjectSelectionHandle selected_handle); - void overrideObjectUpdates(); + // When we edit object's position/rotation/scale we set local + // overrides and ignore any updates (override received valeus). + // When we send data to server, we send local values and reset + // overrides + void resetObjectOverrides(); + void resetObjectOverrides(LLObjectSelectionHandle selected_handle); + void overrideObjectUpdates(); void resetAvatarOverrides(); void overrideAvatarUpdates(); @@ -519,430 +519,430 @@ public: public: - // Returns the previous value of mForceSelection - BOOL setForceSelection(BOOL force); + // Returns the previous value of mForceSelection + BOOL setForceSelection(BOOL force); - //////////////////////////////////////////////////////////////// - // Selection methods - //////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////// + // Selection methods + //////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////// - // Add - //////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////// + // Add + //////////////////////////////////////////////////////////////// - // This method is meant to select an object, and then select all - // of the ancestors and descendants. This should be the normal behavior. - // - // *NOTE: You must hold on to the object selection handle, otherwise - // the objects will be automatically deselected in 1 frame. - LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE, BOOL ignore_select_owned = FALSE); + // This method is meant to select an object, and then select all + // of the ancestors and descendants. This should be the normal behavior. + // + // *NOTE: You must hold on to the object selection handle, otherwise + // the objects will be automatically deselected in 1 frame. + LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE, BOOL ignore_select_owned = FALSE); - // For when you want just a child object. + // For when you want just a child object. LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES, S32 gltf_node = -1, S32 gltf_primitive = -1); - // Same as above, but takes a list of objects. Used by rectangle select. - LLObjectSelectionHandle selectObjectAndFamily(const std::vector& object_list, BOOL send_to_sim = TRUE); + // Same as above, but takes a list of objects. Used by rectangle select. + LLObjectSelectionHandle selectObjectAndFamily(const std::vector& object_list, BOOL send_to_sim = TRUE); + + // converts all objects currently highlighted to a selection, and returns it + LLObjectSelectionHandle selectHighlightedObjects(); + + LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1); + LLSelectNode *getHoverNode(); + LLSelectNode *getPrimaryHoverNode(); - // converts all objects currently highlighted to a selection, and returns it - LLObjectSelectionHandle selectHighlightedObjects(); + void highlightObjectOnly(LLViewerObject *objectp); + void highlightObjectAndFamily(LLViewerObject *objectp); + void highlightObjectAndFamily(const std::vector& list); - LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1); - LLSelectNode *getHoverNode(); - LLSelectNode *getPrimaryHoverNode(); + //////////////////////////////////////////////////////////////// + // Remove + //////////////////////////////////////////////////////////////// - void highlightObjectOnly(LLViewerObject *objectp); - void highlightObjectAndFamily(LLViewerObject *objectp); - void highlightObjectAndFamily(const std::vector& list); + void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE); + void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE); - //////////////////////////////////////////////////////////////// - // Remove - //////////////////////////////////////////////////////////////// + // Send deselect messages to simulator, then clear the list + void deselectAll(); + void deselectAllForStandingUp(); - void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE); - void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE); + // deselect only if nothing else currently referencing the selection + void deselectUnused(); - // Send deselect messages to simulator, then clear the list - void deselectAll(); - void deselectAllForStandingUp(); + // Deselect if the selection center is too far away from the agent. + void deselectAllIfTooFar(); - // deselect only if nothing else currently referencing the selection - void deselectUnused(); + // Removes all highlighted objects from current selection + void deselectHighlightedObjects(); - // Deselect if the selection center is too far away from the agent. - void deselectAllIfTooFar(); + void unhighlightObjectOnly(LLViewerObject *objectp); + void unhighlightObjectAndFamily(LLViewerObject *objectp); + void unhighlightAll(); - // Removes all highlighted objects from current selection - void deselectHighlightedObjects(); + BOOL removeObjectFromSelections(const LLUUID &id); - void unhighlightObjectOnly(LLViewerObject *objectp); - void unhighlightObjectAndFamily(LLViewerObject *objectp); - void unhighlightAll(); + //////////////////////////////////////////////////////////////// + // Selection editing + //////////////////////////////////////////////////////////////// + bool linkObjects(); - BOOL removeObjectFromSelections(const LLUUID &id); + bool unlinkObjects(); - //////////////////////////////////////////////////////////////// - // Selection editing - //////////////////////////////////////////////////////////////// - bool linkObjects(); + void confirmUnlinkObjects(const LLSD& notification, const LLSD& response); - bool unlinkObjects(); + bool enableLinkObjects(); - void confirmUnlinkObjects(const LLSD& notification, const LLSD& response); + bool enableUnlinkObjects(); - bool enableLinkObjects(); + //////////////////////////////////////////////////////////////// + // Selection accessors + //////////////////////////////////////////////////////////////// + LLObjectSelectionHandle getSelection() { return mSelectedObjects; } + // right now this just renders the selection with root/child colors instead of a single color + LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; } + LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; } - bool enableUnlinkObjects(); + //////////////////////////////////////////////////////////////// + // Grid manipulation + //////////////////////////////////////////////////////////////// + void addGridObject(LLViewerObject* objectp); + void clearGridObjects(); + void setGridMode(EGridMode mode); + EGridMode getGridMode() { return mGridMode; } + void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false); - //////////////////////////////////////////////////////////////// - // Selection accessors - //////////////////////////////////////////////////////////////// - LLObjectSelectionHandle getSelection() { return mSelectedObjects; } - // right now this just renders the selection with root/child colors instead of a single color - LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; } - LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; } + BOOL getTEMode() const { return mTEMode; } + void setTEMode(BOOL b) { mTEMode = b; } - //////////////////////////////////////////////////////////////// - // Grid manipulation - //////////////////////////////////////////////////////////////// - void addGridObject(LLViewerObject* objectp); - void clearGridObjects(); - void setGridMode(EGridMode mode); - EGridMode getGridMode() { return mGridMode; } - void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false); + BOOL shouldShowSelection() const { return mShowSelection; } - BOOL getTEMode() const { return mTEMode; } - void setTEMode(BOOL b) { mTEMode = b; } + LLBBox getBBoxOfSelection() const; + LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; } - BOOL shouldShowSelection() const { return mShowSelection; } + void dump(); + void cleanup(); - LLBBox getBBoxOfSelection() const; - LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; } + void updateSilhouettes(); + void renderSilhouettes(BOOL for_hud); + void enableSilhouette(BOOL enable) { mRenderSilhouettes = enable; } - void dump(); - void cleanup(); + //////////////////////////////////////////////////////////////// + // Utility functions that operate on the current selection + //////////////////////////////////////////////////////////////// + void saveSelectedObjectTransform(EActionType action_type); + void saveSelectedObjectColors(); + void saveSelectedShinyColors(); + void saveSelectedObjectTextures(); - void updateSilhouettes(); - void renderSilhouettes(BOOL for_hud); - void enableSilhouette(BOOL enable) { mRenderSilhouettes = enable; } - - //////////////////////////////////////////////////////////////// - // Utility functions that operate on the current selection - //////////////////////////////////////////////////////////////// - void saveSelectedObjectTransform(EActionType action_type); - void saveSelectedObjectColors(); - void saveSelectedShinyColors(); - void saveSelectedObjectTextures(); + void selectionUpdatePhysics(BOOL use_physics); + void selectionUpdateTemporary(BOOL is_temporary); + void selectionUpdatePhantom(BOOL is_ghost); + void selectionDump(); - void selectionUpdatePhysics(BOOL use_physics); - void selectionUpdateTemporary(BOOL is_temporary); - void selectionUpdatePhantom(BOOL is_ghost); - void selectionDump(); + BOOL selectionAllPCode(LLPCode code); // all objects have this PCode + BOOL selectionGetClickAction(U8 *out_action); + bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same + BOOL selectionGetGlow(F32 *glow); - BOOL selectionAllPCode(LLPCode code); // all objects have this PCode - BOOL selectionGetClickAction(U8 *out_action); - bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same - BOOL selectionGetGlow(F32 *glow); - - void selectionSetPhysicsType(U8 type); - void selectionSetGravity(F32 gravity); - void selectionSetFriction(F32 friction); - void selectionSetDensity(F32 density); - void selectionSetRestitution(F32 restitution); - void selectionSetMaterial(U8 material); - bool selectionSetImage(const LLUUID& imageid); // could be item or asset id + void selectionSetPhysicsType(U8 type); + void selectionSetGravity(F32 gravity); + void selectionSetFriction(F32 friction); + void selectionSetDensity(F32 density); + void selectionSetRestitution(F32 restitution); + void selectionSetMaterial(U8 material); + bool selectionSetImage(const LLUUID& imageid); // could be item or asset id bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only - void selectionSetColor(const LLColor4 &color); - void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels - void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel - void selectionRevertColors(); - void selectionRevertShinyColors(); - BOOL selectionRevertTextures(); + void selectionSetColor(const LLColor4 &color); + void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels + void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel + void selectionRevertColors(); + void selectionRevertShinyColors(); + BOOL selectionRevertTextures(); void selectionRevertGLTFMaterials(); - void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id ); - void selectionSetTexGen( U8 texgen ); - void selectionSetShiny( U8 shiny, const LLUUID &image_id ); - void selectionSetFullbright( U8 fullbright ); - void selectionSetMedia( U8 media_type, const LLSD &media_data ); - void selectionSetClickAction(U8 action); - void selectionSetIncludeInSearch(bool include_in_search); - void selectionSetGlow(const F32 glow); - void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1); - void selectionRemoveMaterial(); - - void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); - void selectionSetObjectName(const std::string& name); - void selectionSetObjectDescription(const std::string& desc); - void selectionSetObjectCategory(const LLCategory& category); - void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info); - - void selectionTexScaleAutofit(F32 repeats_per_meter); - void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch); - - bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz, - U32 update_type); - void sendSelectionMove(); - - void sendGodlikeRequest(const std::string& request, const std::string& parameter); - - - // will make sure all selected object meet current criteria, or deselect them otherwise - void validateSelection(); - - // returns TRUE if it is possible to select this object - BOOL canSelectObject(LLViewerObject* object, BOOL ignore_select_owned = FALSE); - - // Returns TRUE if the viewer has information on all selected objects - BOOL selectGetAllRootsValid(); - BOOL selectGetAllValid(); - BOOL selectGetAllValidAndObjectsFound(); - - // returns TRUE if you can modify all selected objects. - BOOL selectGetRootsModify(); - BOOL selectGetModify(); - - // returns TRUE if all objects are in same region - BOOL selectGetSameRegion(); - - // returns TRUE if is all objects are non-permanent-enforced - BOOL selectGetRootsNonPermanentEnforced(); - BOOL selectGetNonPermanentEnforced(); - - // returns TRUE if is all objects are permanent - BOOL selectGetRootsPermanent(); - BOOL selectGetPermanent(); - - // returns TRUE if is all objects are character - BOOL selectGetRootsCharacter(); - BOOL selectGetCharacter(); - - // returns TRUE if is all objects are not permanent - BOOL selectGetRootsNonPathfinding(); - BOOL selectGetNonPathfinding(); - - // returns TRUE if is all objects are not permanent - BOOL selectGetRootsNonPermanent(); - BOOL selectGetNonPermanent(); - - // returns TRUE if is all objects are not character - BOOL selectGetRootsNonCharacter(); - BOOL selectGetNonCharacter(); - - BOOL selectGetEditableLinksets(); - BOOL selectGetViewableCharacters(); - - // returns TRUE if selected objects can be transferred. - BOOL selectGetRootsTransfer(); - - // returns TRUE if selected objects can be copied. - BOOL selectGetRootsCopy(); - - BOOL selectGetCreator(LLUUID& id, std::string& name); // TRUE if all have same creator, returns id - BOOL selectGetOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id - BOOL selectGetLastOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id - - // returns TRUE if all are the same. id is stuffed with - // the value found if available. - BOOL selectGetGroup(LLUUID& id); - BOOL selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off); // TRUE if all have data, returns two masks, each indicating which bits are all on and all off - - BOOL selectIsGroupOwned(); // TRUE if all root objects have valid data and are group owned. - - // returns TRUE if all the nodes are valid. Accumulates - // permissions in the parameter. - BOOL selectGetPermissions(LLPermissions& perm); - - // returns TRUE if all the nodes are valid. Depends onto "edit linked" state - // Children in linksets are a bit special - they require not only move permission - // but also modify if "edit linked" is set, since you move them relative to parent - BOOL selectGetEditMoveLinksetPermissions(bool &move, bool &modify); - - // Get a bunch of useful sale information for the object(s) selected. - // "_mixed" is true if not all objects have the same setting. - void selectGetAggregateSaleInfo(U32 &num_for_sale, - BOOL &is_for_sale_mixed, - BOOL &is_sale_price_mixed, - S32 &total_sale_price, - S32 &individual_sale_price); - - // returns TRUE if all nodes are valid. - BOOL selectGetCategory(LLCategory& category); - - // returns TRUE if all nodes are valid. method also stores an - // accumulated sale info. - BOOL selectGetSaleInfo(LLSaleInfo& sale_info); - - // returns TRUE if all nodes are valid. fills passed in object - // with the aggregate permissions of the selection. - BOOL selectGetAggregatePermissions(LLAggregatePermissions& ag_perm); - - // returns TRUE if all nodes are valid. fills passed in object - // with the aggregate permissions for texture inventory items of the selection. - BOOL selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm); - - LLPermissions* findObjectPermissions(const LLViewerObject* object); - - BOOL isMovableAvatarSelected(); - - void selectDelete(); // Delete on simulator - void selectForceDelete(); // just delete, no into trash - void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator - void repeatDuplicate(); - void selectDuplicateOnRay(const LLVector3 &ray_start_region, - const LLVector3 &ray_end_region, - BOOL bypass_raycast, - BOOL ray_end_is_intersection, - const LLUUID &ray_target_id, - BOOL copy_centers, - BOOL copy_rotates, - BOOL select_copy); - - void sendMultipleUpdate(U32 type); // Position, rotation, scale all in one - void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, BOOL override = FALSE); - void sendGroup(const LLUUID& group_id); - - // Category ID is the UUID of the folder you want to contain the purchase. - // *NOTE: sale_info check doesn't work for multiple object buy, - // which UI does not currently support sale info is used for - // verification only, if it doesn't match region info then sale is - // canceled - void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info); - void sendAttach(U8 attachment_point, bool replace); - void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace); - void sendDetach(); - void sendDropAttachment(); - void sendLink(); - void sendDelink(); - //void sendHinge(U8 type); - //void sendDehinge(); - void sendSelect(); - - void requestObjectPropertiesFamily(LLViewerObject* object); // asks sim for creator, permissions, resources, etc. - static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data); - static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data); - static void processForceObjectSelect(LLMessageSystem* msg, void**); - - void requestGodInfo(); - - LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; } - void updateSelectionCenter(); + void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id ); + void selectionSetTexGen( U8 texgen ); + void selectionSetShiny( U8 shiny, const LLUUID &image_id ); + void selectionSetFullbright( U8 fullbright ); + void selectionSetMedia( U8 media_type, const LLSD &media_data ); + void selectionSetClickAction(U8 action); + void selectionSetIncludeInSearch(bool include_in_search); + void selectionSetGlow(const F32 glow); + void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1); + void selectionRemoveMaterial(); + + void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); + void selectionSetObjectName(const std::string& name); + void selectionSetObjectDescription(const std::string& desc); + void selectionSetObjectCategory(const LLCategory& category); + void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info); + + void selectionTexScaleAutofit(F32 repeats_per_meter); + void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch); + + bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz, + U32 update_type); + void sendSelectionMove(); + + void sendGodlikeRequest(const std::string& request, const std::string& parameter); + + + // will make sure all selected object meet current criteria, or deselect them otherwise + void validateSelection(); + + // returns TRUE if it is possible to select this object + BOOL canSelectObject(LLViewerObject* object, BOOL ignore_select_owned = FALSE); + + // Returns TRUE if the viewer has information on all selected objects + BOOL selectGetAllRootsValid(); + BOOL selectGetAllValid(); + BOOL selectGetAllValidAndObjectsFound(); + + // returns TRUE if you can modify all selected objects. + BOOL selectGetRootsModify(); + BOOL selectGetModify(); + + // returns TRUE if all objects are in same region + BOOL selectGetSameRegion(); + + // returns TRUE if is all objects are non-permanent-enforced + BOOL selectGetRootsNonPermanentEnforced(); + BOOL selectGetNonPermanentEnforced(); + + // returns TRUE if is all objects are permanent + BOOL selectGetRootsPermanent(); + BOOL selectGetPermanent(); + + // returns TRUE if is all objects are character + BOOL selectGetRootsCharacter(); + BOOL selectGetCharacter(); + + // returns TRUE if is all objects are not permanent + BOOL selectGetRootsNonPathfinding(); + BOOL selectGetNonPathfinding(); + + // returns TRUE if is all objects are not permanent + BOOL selectGetRootsNonPermanent(); + BOOL selectGetNonPermanent(); + + // returns TRUE if is all objects are not character + BOOL selectGetRootsNonCharacter(); + BOOL selectGetNonCharacter(); + + BOOL selectGetEditableLinksets(); + BOOL selectGetViewableCharacters(); + + // returns TRUE if selected objects can be transferred. + BOOL selectGetRootsTransfer(); + + // returns TRUE if selected objects can be copied. + BOOL selectGetRootsCopy(); + + BOOL selectGetCreator(LLUUID& id, std::string& name); // TRUE if all have same creator, returns id + BOOL selectGetOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id + BOOL selectGetLastOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id + + // returns TRUE if all are the same. id is stuffed with + // the value found if available. + BOOL selectGetGroup(LLUUID& id); + BOOL selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off); // TRUE if all have data, returns two masks, each indicating which bits are all on and all off + + BOOL selectIsGroupOwned(); // TRUE if all root objects have valid data and are group owned. + + // returns TRUE if all the nodes are valid. Accumulates + // permissions in the parameter. + BOOL selectGetPermissions(LLPermissions& perm); + + // returns TRUE if all the nodes are valid. Depends onto "edit linked" state + // Children in linksets are a bit special - they require not only move permission + // but also modify if "edit linked" is set, since you move them relative to parent + BOOL selectGetEditMoveLinksetPermissions(bool &move, bool &modify); + + // Get a bunch of useful sale information for the object(s) selected. + // "_mixed" is true if not all objects have the same setting. + void selectGetAggregateSaleInfo(U32 &num_for_sale, + BOOL &is_for_sale_mixed, + BOOL &is_sale_price_mixed, + S32 &total_sale_price, + S32 &individual_sale_price); + + // returns TRUE if all nodes are valid. + BOOL selectGetCategory(LLCategory& category); + + // returns TRUE if all nodes are valid. method also stores an + // accumulated sale info. + BOOL selectGetSaleInfo(LLSaleInfo& sale_info); + + // returns TRUE if all nodes are valid. fills passed in object + // with the aggregate permissions of the selection. + BOOL selectGetAggregatePermissions(LLAggregatePermissions& ag_perm); + + // returns TRUE if all nodes are valid. fills passed in object + // with the aggregate permissions for texture inventory items of the selection. + BOOL selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm); + + LLPermissions* findObjectPermissions(const LLViewerObject* object); + + BOOL isMovableAvatarSelected(); + + void selectDelete(); // Delete on simulator + void selectForceDelete(); // just delete, no into trash + void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator + void repeatDuplicate(); + void selectDuplicateOnRay(const LLVector3 &ray_start_region, + const LLVector3 &ray_end_region, + BOOL bypass_raycast, + BOOL ray_end_is_intersection, + const LLUUID &ray_target_id, + BOOL copy_centers, + BOOL copy_rotates, + BOOL select_copy); + + void sendMultipleUpdate(U32 type); // Position, rotation, scale all in one + void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, BOOL override = FALSE); + void sendGroup(const LLUUID& group_id); + + // Category ID is the UUID of the folder you want to contain the purchase. + // *NOTE: sale_info check doesn't work for multiple object buy, + // which UI does not currently support sale info is used for + // verification only, if it doesn't match region info then sale is + // canceled + void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info); + void sendAttach(U8 attachment_point, bool replace); + void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace); + void sendDetach(); + void sendDropAttachment(); + void sendLink(); + void sendDelink(); + //void sendHinge(U8 type); + //void sendDehinge(); + void sendSelect(); + + void requestObjectPropertiesFamily(LLViewerObject* object); // asks sim for creator, permissions, resources, etc. + static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data); + static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data); + static void processForceObjectSelect(LLMessageSystem* msg, void**); + + void requestGodInfo(); + + LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; } + void updateSelectionCenter(); void pauseAssociatedAvatars(); - void resetAgentHUDZoom(); - void setAgentHUDZoom(F32 target_zoom, F32 current_zoom); - void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; + void resetAgentHUDZoom(); + void setAgentHUDZoom(F32 target_zoom, F32 current_zoom); + void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; - void updatePointAt(); + void updatePointAt(); - // Internal list maintenance functions. TODO: Make these private! - void remove(std::vector& objects); - void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE); - void removeAll(); - void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE, S32 gltf_node = -1, S32 gltf_primitive = -1); - void promoteSelectionToRoot(); - void demoteSelectionToIndividuals(); + // Internal list maintenance functions. TODO: Make these private! + void remove(std::vector& objects); + void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE); + void removeAll(); + void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE, S32 gltf_node = -1, S32 gltf_primitive = -1); + void promoteSelectionToRoot(); + void demoteSelectionToIndividuals(); private: - void convertTransient(); // converts temporarily selected objects to full-fledged selections - ESelectType getSelectTypeForObject(LLViewerObject* object); - void addAsFamily(std::vector& objects, BOOL add_to_end = FALSE); - void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point); - void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector& changed_objects); - // Send one message to each region containing an object on selection list. - void sendListToRegions( const std::string& message_name, - void (*pack_header)(void *user_data), - void (*pack_body)(LLSelectNode* node, void *user_data), - void (*log_func)(LLSelectNode* node, void *user_data), - void *user_data, - ESendType send_type); - void sendListToRegions( LLObjectSelectionHandle selected_handle, - const std::string& message_name, - void (*pack_header)(void *user_data), - void (*pack_body)(LLSelectNode* node, void *user_data), - void (*log_func)(LLSelectNode* node, void *user_data), - void *user_data, - ESendType send_type); - - - static void packAgentID( void *); - static void packAgentAndSessionID(void* user_data); - static void packAgentAndGroupID(void* user_data); - static void packAgentAndSessionAndGroupID(void* user_data); - static void packAgentIDAndSessionAndAttachment(void*); - static void packAgentGroupAndCatID(void*); - static void packDeleteHeader(void* userdata); - static void packDeRezHeader(void* user_data); - static void packObjectID( LLSelectNode* node, void *); - static void packObjectIDAsParam(LLSelectNode* node, void *); - static void packObjectIDAndRotation(LLSelectNode* node, void *); - static void packObjectLocalID(LLSelectNode* node, void *); - static void packObjectClickAction(LLSelectNode* node, void* data); - static void packObjectIncludeInSearch(LLSelectNode* node, void* data); - static void packObjectName(LLSelectNode* node, void* user_data); - static void packObjectDescription(LLSelectNode* node, void* user_data); - static void packObjectCategory(LLSelectNode* node, void* user_data); - static void packObjectSaleInfo(LLSelectNode* node, void* user_data); - static void packBuyObjectIDs(LLSelectNode* node, void* user_data); - static void packDuplicate( LLSelectNode* node, void *duplicate_data); - static void packDuplicateHeader(void*); - static void packDuplicateOnRayHead(void *user_data); - static void packPermissions(LLSelectNode* node, void *user_data); - static void packDeselect( LLSelectNode* node, void *user_data); - static void packMultipleUpdate(LLSelectNode* node, void *user_data); - static void packPhysics(LLSelectNode* node, void *user_data); - static void packShape(LLSelectNode* node, void *user_data); - static void packOwnerHead(void *user_data); - static void packHingeHead(void *user_data); - static void packPermissionsHead(void* user_data); - static void packGodlikeHead(void* user_data); + void convertTransient(); // converts temporarily selected objects to full-fledged selections + ESelectType getSelectTypeForObject(LLViewerObject* object); + void addAsFamily(std::vector& objects, BOOL add_to_end = FALSE); + void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point); + void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector& changed_objects); + // Send one message to each region containing an object on selection list. + void sendListToRegions( const std::string& message_name, + void (*pack_header)(void *user_data), + void (*pack_body)(LLSelectNode* node, void *user_data), + void (*log_func)(LLSelectNode* node, void *user_data), + void *user_data, + ESendType send_type); + void sendListToRegions( LLObjectSelectionHandle selected_handle, + const std::string& message_name, + void (*pack_header)(void *user_data), + void (*pack_body)(LLSelectNode* node, void *user_data), + void (*log_func)(LLSelectNode* node, void *user_data), + void *user_data, + ESendType send_type); + + + static void packAgentID( void *); + static void packAgentAndSessionID(void* user_data); + static void packAgentAndGroupID(void* user_data); + static void packAgentAndSessionAndGroupID(void* user_data); + static void packAgentIDAndSessionAndAttachment(void*); + static void packAgentGroupAndCatID(void*); + static void packDeleteHeader(void* userdata); + static void packDeRezHeader(void* user_data); + static void packObjectID( LLSelectNode* node, void *); + static void packObjectIDAsParam(LLSelectNode* node, void *); + static void packObjectIDAndRotation(LLSelectNode* node, void *); + static void packObjectLocalID(LLSelectNode* node, void *); + static void packObjectClickAction(LLSelectNode* node, void* data); + static void packObjectIncludeInSearch(LLSelectNode* node, void* data); + static void packObjectName(LLSelectNode* node, void* user_data); + static void packObjectDescription(LLSelectNode* node, void* user_data); + static void packObjectCategory(LLSelectNode* node, void* user_data); + static void packObjectSaleInfo(LLSelectNode* node, void* user_data); + static void packBuyObjectIDs(LLSelectNode* node, void* user_data); + static void packDuplicate( LLSelectNode* node, void *duplicate_data); + static void packDuplicateHeader(void*); + static void packDuplicateOnRayHead(void *user_data); + static void packPermissions(LLSelectNode* node, void *user_data); + static void packDeselect( LLSelectNode* node, void *user_data); + static void packMultipleUpdate(LLSelectNode* node, void *user_data); + static void packPhysics(LLSelectNode* node, void *user_data); + static void packShape(LLSelectNode* node, void *user_data); + static void packOwnerHead(void *user_data); + static void packHingeHead(void *user_data); + static void packPermissionsHead(void* user_data); + static void packGodlikeHead(void* user_data); static void logNoOp(LLSelectNode* node, void *user_data); static void logAttachmentRequest(LLSelectNode* node, void *user_data); static void logDetachRequest(LLSelectNode* node, void *user_data); - static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); + static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); - // Get the first ID that matches test and whether or not all ids are identical in selected objects. - void getFirst(LLSelectGetFirstTest* test); + // Get the first ID that matches test and whether or not all ids are identical in selected objects. + void getFirst(LLSelectGetFirstTest* test); public: - // Observer/callback support for when object selection changes or - // properties are received/updated - typedef boost::signals2::signal< void ()> update_signal_t; - update_signal_t mUpdateSignal; + // Observer/callback support for when object selection changes or + // properties are received/updated + typedef boost::signals2::signal< void ()> update_signal_t; + update_signal_t mUpdateSignal; private: - LLPointer mSilhouetteImagep; - LLObjectSelectionHandle mSelectedObjects; - LLObjectSelectionHandle mHoverObjects; - LLObjectSelectionHandle mHighlightedObjects; - std::set > mRectSelectedObjects; - - LLObjectSelection mGridObjects; - LLQuaternion mGridRotation; - LLVector3 mGridOrigin; - LLVector3 mGridScale; - EGridMode mGridMode; - - BOOL mTEMode; // render te - LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode - LLVector3d mSelectionCenterGlobal; - LLBBox mSelectionBBox; - - LLVector3d mLastSentSelectionCenterGlobal; - BOOL mShowSelection; // do we send the selection center name value and do we animate this selection? - LLVector3d mLastCameraPos; // camera position from last generation of selection silhouette - BOOL mRenderSilhouettes; // do we render the silhouette - LLBBox mSavedSelectionBBox; - - LLFrameTimer mEffectsTimer; - BOOL mForceSelection; - - std::vector mPauseRequests; + LLPointer mSilhouetteImagep; + LLObjectSelectionHandle mSelectedObjects; + LLObjectSelectionHandle mHoverObjects; + LLObjectSelectionHandle mHighlightedObjects; + std::set > mRectSelectedObjects; + + LLObjectSelection mGridObjects; + LLQuaternion mGridRotation; + LLVector3 mGridOrigin; + LLVector3 mGridScale; + EGridMode mGridMode; + + BOOL mTEMode; // render te + LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode + LLVector3d mSelectionCenterGlobal; + LLBBox mSelectionBBox; + + LLVector3d mLastSentSelectionCenterGlobal; + BOOL mShowSelection; // do we send the selection center name value and do we animate this selection? + LLVector3d mLastCameraPos; // camera position from last generation of selection silhouette + BOOL mRenderSilhouettes; // do we render the silhouette + LLBBox mSavedSelectionBBox; + + LLFrameTimer mEffectsTimer; + BOOL mForceSelection; + + std::vector mPauseRequests; }; // *DEPRECATED: For callbacks or observers, use // LLSelectMgr::getInstance()->mUpdateSignal.connect( callback ) // Update subscribers to the selection list -void dialog_refresh_all(); +void dialog_refresh_all(); // Templates //----------------------------------------------------------------------------- @@ -950,113 +950,113 @@ void dialog_refresh_all(); //----------------------------------------------------------------------------- template bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor* func, T& res, bool has_tolerance, T tolerance) { - bool have_first = false; - bool have_selected = false; - T selected_value = T(); - - // Now iterate through all TEs to test for sameness - bool identical = TRUE; - for (iterator iter = begin(); iter != end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - S32 selected_te = -1; - if (object == getPrimaryObject()) - { - selected_te = node->getLastSelectedTE(); - } - for (S32 te = 0; te < object->getNumTEs(); ++te) - { - if (!node->isTESelected(te)) - { - continue; - } - T value = func->get(object, te); - if (!have_first) - { - have_first = true; - if (!have_selected) - { - selected_value = value; - } - } - else - { - if ( value != selected_value ) - { + bool have_first = false; + bool have_selected = false; + T selected_value = T(); + + // Now iterate through all TEs to test for sameness + bool identical = TRUE; + for (iterator iter = begin(); iter != end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + S32 selected_te = -1; + if (object == getPrimaryObject()) + { + selected_te = node->getLastSelectedTE(); + } + for (S32 te = 0; te < object->getNumTEs(); ++te) + { + if (!node->isTESelected(te)) + { + continue; + } + T value = func->get(object, te); + if (!have_first) + { + have_first = true; + if (!have_selected) + { + selected_value = value; + } + } + else + { + if ( value != selected_value ) + { if (!has_tolerance) { - identical = false; + identical = false; } else if (!LLCheckIdenticalFunctor::same(value, selected_value, tolerance)) { identical = false; } - } - if (te == selected_te) - { - selected_value = value; - have_selected = true; - } - } - } - if (!identical && have_selected) - { - break; - } - } - if (have_first || have_selected) - { - res = selected_value; - } - return identical; + } + if (te == selected_te) + { + selected_value = value; + have_selected = true; + } + } + } + if (!identical && have_selected) + { + break; + } + } + if (have_first || have_selected) + { + res = selected_value; + } + return identical; } // Templates //----------------------------------------------------------------------------- -// isMultipleTEValue iterate through all TEs and test for uniqueness -// with certain return value ignored when performing the test. +// isMultipleTEValue iterate through all TEs and test for uniqueness +// with certain return value ignored when performing the test. // e.g. when testing if the selection has a unique non-empty homeurl : -// you can set ignore_value = "" and it will only compare among the non-empty +// you can set ignore_value = "" and it will only compare among the non-empty // homeUrls and ignore the empty ones. //----------------------------------------------------------------------------- template bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor* func, const T& ignore_value) { - bool have_first = false; - T selected_value = T(); - - // Now iterate through all TEs to test for sameness - bool unique = TRUE; - for (iterator iter = begin(); iter != end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - for (S32 te = 0; te < object->getNumTEs(); ++te) - { - if (!node->isTESelected(te)) - { - continue; - } - T value = func->get(object, te); - if(value == ignore_value) - { - continue; - } - if (!have_first) - { - have_first = true; - } - else - { - if (value !=selected_value ) - { - unique = false; - return !unique; - } - } - } - } - return !unique; + bool have_first = false; + T selected_value = T(); + + // Now iterate through all TEs to test for sameness + bool unique = TRUE; + for (iterator iter = begin(); iter != end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + for (S32 te = 0; te < object->getNumTEs(); ++te) + { + if (!node->isTESelected(te)) + { + continue; + } + T value = func->get(object, te); + if(value == ignore_value) + { + continue; + } + if (!have_first) + { + have_first = true; + } + else + { + if (value !=selected_value ) + { + unique = false; + return !unique; + } + } + } + } + return !unique; } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index ff9332aeee..76632a83ae 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -72,7 +72,7 @@ extern BOOL gCubeSnapshot; //========================================================================= -namespace +namespace { LLSD ensure_array_4(LLSD in, F32 fill); LLSD read_legacy_preset_data(const std::string &name, const std::string& path, LLSD &messages); @@ -185,7 +185,7 @@ void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSetti } } if (!settings) - { // The item was created as new with no settings passed in. Simulator should have given it the default for the type... check ID, + { // The item was created as new with no settings passed in. Simulator should have given it the default for the type... check ID, // no need to upload asset. LLUUID asset_id; if (pitem) @@ -246,11 +246,11 @@ void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings } } - std::stringstream buffer; + std::stringstream buffer; LLSD settingdata(settings->getSettings()); LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); - LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), + LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) { LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback); @@ -313,7 +313,7 @@ void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, L void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback) { gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS, - [callback](const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status) + [callback](const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status) { onAssetDownloadComplete(asset_id, status, ext_status, callback); }, nullptr, true); @@ -503,7 +503,7 @@ LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &n if (!llsd_equals(oldsettings, oldsettings)) { - LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n" + LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n" << "Old: " << oldsettings << "new: " << oldsettings << LL_ENDL; } @@ -601,7 +601,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA { LLSD legacy(LLSD::emptyMap()); LLSD settings = psky->getSettings(); - + convertAtmosphericsToLegacy(legacy, settings); legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0); @@ -610,15 +610,15 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA legacy[SETTING_CLOUD_SCALE] = llsd::array(settings[SETTING_CLOUD_SCALE], LLSD::Real(0.0), LLSD::Real(0.0), LLSD::Real(1.0)); legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE]; legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = llsd::array(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())), - LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal()))); - legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f); + LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal()))); + legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f); legacy[SETTING_GAMMA] = llsd::array(settings[SETTING_GAMMA], 0.0f, 0.0f, 1.0f); legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0); legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f); legacy[SETTING_MAX_Y] = llsd::array(settings[SETTING_MAX_Y], 0.0f, 0.0f, 1.0f); legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f); - + LLVector3 dir = psky->getLightDirection(); F32 phi = asin(dir.mV[2]); @@ -633,17 +633,17 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA { theta += F_PI * 2; } - + if (theta > 4 * F_PI) { theta = fmod(theta, 2 * F_PI); } - + while (phi < -F_PI) { phi += 2 * F_PI; } - + if (phi > 3 * F_PI) { phi = F_PI + fmod(phi - F_PI, 2 * F_PI); @@ -651,8 +651,8 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA legacy[SETTING_LEGACY_EAST_ANGLE] = theta; legacy[SETTING_LEGACY_SUN_ANGLE] = phi; - - return legacy; + + return legacy; } //------------------------------------------------------------------------- @@ -669,10 +669,10 @@ void LLSettingsVOSky::updateSettings() // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio // between sunlight and point lights in windlight to normalize point lights. // - // After some A/B comparison of relesae vs EEP, tweak to allow strength to fall below 2 + // After some A/B comparison of relesae vs EEP, tweak to allow strength to fall below 2 // at night, for better match. (mSceneLightStrength is a divisor, so lower value means brighter // local lights) - F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); + F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); mSceneLightStrength = 2.0f * (0.75f + sun_dynamic_range * dp); gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction); @@ -693,11 +693,11 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) bool irradiance_pass = gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass(); LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT]; - { + { shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction); shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin()); - } - + } + shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY]; shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction); @@ -759,13 +759,13 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails } else if (psky->canAutoAdjust() && should_auto_adjust) - { // auto-adjust legacy sky to take advantage of probe ambiance + { // auto-adjust legacy sky to take advantage of probe ambiance shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV); shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale); LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale; LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale; sun_light_color = sun_light_color * auto_adjust_sun_color_scale; - + shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color.mV); shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV); shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV); @@ -785,7 +785,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor()); shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier()); shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier()); - + shader->uniform1f(LLShaderMgr::GAMMA, g); } @@ -809,7 +809,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const // Following values are always present, so we can just zero these ones, but used values from defaults() LLSD sky_defaults = LLSettingsSky::defaults(); - + param_map[SETTING_CLOUD_POS_DENSITY2] = DefaultParam(LLShaderMgr::CLOUD_POS_DENSITY2, sky_defaults[SETTING_CLOUD_POS_DENSITY2]); param_map[SETTING_CLOUD_SCALE] = DefaultParam(LLShaderMgr::CLOUD_SCALE, sky_defaults[SETTING_CLOUD_SCALE]); param_map[SETTING_CLOUD_SHADOW] = DefaultParam(LLShaderMgr::CLOUD_SHADOW, sky_defaults[SETTING_CLOUD_SHADOW]); @@ -872,7 +872,7 @@ LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::strin return LLSettingsWater::ptr_t(); } - newsettings[SETTING_NAME] = name; + newsettings[SETTING_NAME] = name; LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); LLSD results = LLSettingsWater::settingValidation(newsettings, validations); if (!results["success"].asBoolean()) @@ -970,7 +970,7 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW]; legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR]; legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR]; - + return legacy; } //------------------------------------------------------------------------- @@ -983,8 +983,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) auto group = LLGLSLShader::SG_ANY; LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group]; - - { + + { F32 water_height = env.getWaterHeight(); if (LLViewerCamera::instance().cameraUnderWater()) @@ -1119,7 +1119,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n std::set notfound; // expected and correct folder sctructure is to have - // three folders in widnlight's root: days, water, skies + // three folders in widnlight's root: days, water, skies std::string base_path(gDirUtilp->getDirName(path)); std::string water_path(base_path); std::string sky_path(base_path); @@ -1210,7 +1210,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n if (!llsd_equals(oldsettings, testsettings)) { - LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n" + LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n" << "Old: " << oldsettings << "new: " << testsettings << LL_ENDL; } @@ -1245,7 +1245,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®io { std::string newname = "sky:" + (*itm).first; LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second); - + newsettings[SETTING_NAME] = newname; frames[newname] = newsettings; @@ -1284,7 +1284,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®io } LLSettingsDay::ptr_t dayp = std::make_shared(newsettings); - + if (dayp) { // true for validation - either validate here, or when cloning for floater. @@ -1434,34 +1434,34 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday) if (!pwater) pwater = LLSettingsVOWater::buildDefaultWater(); - + LLSD llsdwater = LLSettingsVOWater::convertToLegacy(pwater); - + CycleTrack_t &tracksky = pday->getCycleTrack(1); // first sky track std::map skys; - + LLSD llsdcycle(LLSD::emptyArray()); - + for(CycleTrack_t::iterator it = tracksky.begin(); it != tracksky.end(); ++it) { size_t hash = (*it).second->getHash(); std::stringstream name; - + name << hash; - + skys[name.str()] = std::static_pointer_cast((*it).second); - + F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first; llsdcycle.append( llsd::array(LLSD::Real(frame), name.str()) ); } LLSD llsdskylist(LLSD::emptyMap()); - + for (std::map::iterator its = skys.begin(); its != skys.end(); ++its) { LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false); llsdsky[SETTING_NAME] = (*its).first; - + llsdskylist[(*its).first] = llsdsky; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f3b5bb0565..9e05a02b7a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llspatialpartition.cpp * @brief LLSpatialGroup class implementation and supporting functions * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -73,131 +73,131 @@ static F32 sCurMaxTexPriority = 1.f; void sg_assert(BOOL expr) { #if LL_OCTREE_PARANOIA_CHECK - if (!expr) - { - LL_ERRS() << "Octree invalid!" << LL_ENDL; - } + if (!expr) + { + LL_ERRS() << "Octree invalid!" << LL_ENDL; + } #endif } //returns: -// 0 if sphere and AABB are not intersecting -// 1 if they are -// 2 if AABB is entirely inside sphere +// 0 if sphere and AABB are not intersecting +// 1 if they are +// 2 if AABB is entirely inside sphere S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3& pos, const F32 &rad) { - S32 ret = 2; - - LLVector3 min = center - size; - LLVector3 max = center + size; - for (U32 i = 0; i < 3; i++) - { - if (min.mV[i] > pos.mV[i] + rad || - max.mV[i] < pos.mV[i] - rad) - { //totally outside - return 0; - } - - if (min.mV[i] < pos.mV[i] - rad || - max.mV[i] > pos.mV[i] + rad) - { //intersecting - ret = 1; - } - } - - return ret; + S32 ret = 2; + + LLVector3 min = center - size; + LLVector3 max = center + size; + for (U32 i = 0; i < 3; i++) + { + if (min.mV[i] > pos.mV[i] + rad || + max.mV[i] < pos.mV[i] - rad) + { //totally outside + return 0; + } + + if (min.mV[i] < pos.mV[i] - rad || + max.mV[i] > pos.mV[i] + rad) + { //intersecting + ret = 1; + } + } + + return ret; } LLSpatialGroup::~LLSpatialGroup() { - /*if (sNoDelete) - { - LL_ERRS() << "Illegal deletion of LLSpatialGroup!" << LL_ENDL; - }*/ + /*if (sNoDelete) + { + LL_ERRS() << "Illegal deletion of LLSpatialGroup!" << LL_ENDL; + }*/ + + if (gDebugGL) + { + gPipeline.checkReferences(this); + } - if (gDebugGL) - { - gPipeline.checkReferences(this); - } + if (hasState(DEAD)) + { + sZombieGroups--; + } - if (hasState(DEAD)) - { - sZombieGroups--; - } - - sNodeCount--; + sNodeCount--; - clearDrawMap(); + clearDrawMap(); } void LLSpatialGroup::clearDrawMap() { - mDrawMap.clear(); + mDrawMap.clear(); } -BOOL LLSpatialGroup::isHUDGroup() +BOOL LLSpatialGroup::isHUDGroup() { - return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; + return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; } void LLSpatialGroup::validate() { - ll_assert_aligned(this,64); + ll_assert_aligned(this,64); #if LL_OCTREE_PARANOIA_CHECK - sg_assert(!isState(DIRTY)); - sg_assert(!isDead()); - - LLVector4a myMin; - myMin.setSub(mBounds[0], mBounds[1]); - LLVector4a myMax; - myMax.setAdd(mBounds[0], mBounds[1]); - - validateDrawMap(); - - for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) - { - LLDrawable* drawable = *i; - sg_assert(drawable->getSpatialGroup() == this); - if (drawable->getSpatialBridge()) - { - sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge()); - } - - /*if (drawable->isSpatialBridge()) - { - LLSpatialPartition* part = drawable->asPartition(); - if (!part) - { - LL_ERRS() << "Drawable reports it is a spatial bridge but not a partition." << LL_ENDL; - } - LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); - group->validate(); - }*/ - } - - for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i) - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); - - group->validate(); - - //ensure all children are enclosed in this node - LLVector4a center = group->mBounds[0]; - LLVector4a size = group->mBounds[1]; - - LLVector4a min; - min.setSub(center, size); - LLVector4a max; - max.setAdd(center, size); - - for (U32 j = 0; j < 3; j++) - { - sg_assert(min[j] >= myMin[j]-0.02f); - sg_assert(max[j] <= myMax[j]+0.02f); - } - } + sg_assert(!isState(DIRTY)); + sg_assert(!isDead()); + + LLVector4a myMin; + myMin.setSub(mBounds[0], mBounds[1]); + LLVector4a myMax; + myMax.setAdd(mBounds[0], mBounds[1]); + + validateDrawMap(); + + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) + { + LLDrawable* drawable = *i; + sg_assert(drawable->getSpatialGroup() == this); + if (drawable->getSpatialBridge()) + { + sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge()); + } + + /*if (drawable->isSpatialBridge()) + { + LLSpatialPartition* part = drawable->asPartition(); + if (!part) + { + LL_ERRS() << "Drawable reports it is a spatial bridge but not a partition." << LL_ENDL; + } + LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); + group->validate(); + }*/ + } + + for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i) + { + LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); + + group->validate(); + + //ensure all children are enclosed in this node + LLVector4a center = group->mBounds[0]; + LLVector4a size = group->mBounds[1]; + + LLVector4a min; + min.setSub(center, size); + LLVector4a max; + max.setAdd(center, size); + + for (U32 j = 0; j < 3; j++) + { + sg_assert(min[j] >= myMin[j]-0.02f); + sg_assert(max[j] <= myMax[j]+0.02f); + } + } #endif } @@ -205,195 +205,195 @@ void LLSpatialGroup::validate() void LLSpatialGroup::validateDrawMap() { #if LL_OCTREE_PARANOIA_CHECK - for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) - { - LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; - for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) - { - LLDrawInfo& params = **j; - - params.validate(); - } - } + for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo& params = **j; + + params.validate(); + } + } #endif } BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) { LL_PROFILE_ZONE_SCOPED; - drawablep->updateSpatialExtents(); - - OctreeNode* parent = mOctreeNode->getOctParent(); - - if (mOctreeNode->isInside(drawablep->getPositionGroup()) && - (mOctreeNode->contains(drawablep->getEntry()) || - (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && - parent && parent->getElementCount() >= gOctreeMaxCapacity))) - { - unbound(); - setState(OBJECT_DIRTY); - //setState(GEOM_DIRTY); - return TRUE; - } - - return FALSE; + drawablep->updateSpatialExtents(); + + OctreeNode* parent = mOctreeNode->getOctParent(); + + if (mOctreeNode->isInside(drawablep->getPositionGroup()) && + (mOctreeNode->contains(drawablep->getEntry()) || + (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && + parent && parent->getElementCount() >= gOctreeMaxCapacity))) + { + unbound(); + setState(OBJECT_DIRTY); + //setState(GEOM_DIRTY); + return TRUE; + } + + return FALSE; } void LLSpatialGroup::expandExtents(const LLVector4a* addingExtents, const LLXformMatrix& currentTransform) { - // Get coordinates of the adding extents - const LLVector4a& min = addingExtents[0]; - const LLVector4a& max = addingExtents[1]; - - // Get coordinates of all corners of the bounding box - LLVector3 corners[] = - { - LLVector3(min[0], min[1], min[2]), - LLVector3(min[0], min[1], max[2]), - LLVector3(min[0], max[1], min[2]), - LLVector3(min[0], max[1], max[2]), - LLVector3(max[0], min[1], min[2]), - LLVector3(max[0], min[1], max[2]), - LLVector3(max[0], max[1], min[2]), - LLVector3(max[0], max[1], max[2]) - }; - - // New extents (to be expanded) - LLVector3 extents[] = - { - LLVector3(mExtents[0].getF32ptr()), - LLVector3(mExtents[1].getF32ptr()) - }; - - LLQuaternion backwardRotation = ~currentTransform.getWorldRotation(); - for (LLVector3& corner : corners) - { - // Make coordinates relative to the current position - corner -= currentTransform.getWorldPosition(); - // Rotate coordinates backward to the current rotation - corner.rotVec(backwardRotation); - // Expand root extents on the current corner - for (int j = 0; j < 3; ++j) - { - if (corner[j] < extents[0][j]) - extents[0][j] = corner[j]; - if (corner[j] > extents[1][j]) - extents[1][j] = corner[j]; - } - } - - // Set new expanded extents - mExtents[0].load3(extents[0].mV); - mExtents[1].load3(extents[1].mV); - - // Calculate new center and size - mBounds[0].setAdd(mExtents[0], mExtents[1]); - mBounds[0].mul(0.5f); - mBounds[1].setSub(mExtents[0], mExtents[1]); - mBounds[1].mul(0.5f); + // Get coordinates of the adding extents + const LLVector4a& min = addingExtents[0]; + const LLVector4a& max = addingExtents[1]; + + // Get coordinates of all corners of the bounding box + LLVector3 corners[] = + { + LLVector3(min[0], min[1], min[2]), + LLVector3(min[0], min[1], max[2]), + LLVector3(min[0], max[1], min[2]), + LLVector3(min[0], max[1], max[2]), + LLVector3(max[0], min[1], min[2]), + LLVector3(max[0], min[1], max[2]), + LLVector3(max[0], max[1], min[2]), + LLVector3(max[0], max[1], max[2]) + }; + + // New extents (to be expanded) + LLVector3 extents[] = + { + LLVector3(mExtents[0].getF32ptr()), + LLVector3(mExtents[1].getF32ptr()) + }; + + LLQuaternion backwardRotation = ~currentTransform.getWorldRotation(); + for (LLVector3& corner : corners) + { + // Make coordinates relative to the current position + corner -= currentTransform.getWorldPosition(); + // Rotate coordinates backward to the current rotation + corner.rotVec(backwardRotation); + // Expand root extents on the current corner + for (int j = 0; j < 3; ++j) + { + if (corner[j] < extents[0][j]) + extents[0][j] = corner[j]; + if (corner[j] > extents[1][j]) + extents[1][j] = corner[j]; + } + } + + // Set new expanded extents + mExtents[0].load3(extents[0].mV); + mExtents[1].load3(extents[1].mV); + + // Calculate new center and size + mBounds[0].setAdd(mExtents[0], mExtents[1]); + mBounds[0].mul(0.5f); + mBounds[1].setSub(mExtents[0], mExtents[1]); + mBounds[1].mul(0.5f); } BOOL LLSpatialGroup::addObject(LLDrawable *drawablep) { - if(!drawablep) - { - return FALSE; - } - { - drawablep->setGroup(this); - setState(OBJECT_DIRTY | GEOM_DIRTY); - setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); - gPipeline.markRebuild(this); - if (drawablep->isSpatialBridge()) - { - mBridgeList.push_back((LLSpatialBridge*) drawablep); - } - if (drawablep->getRadius() > 1.f) - { - setState(IMAGE_DIRTY); - } - } - - return TRUE; + if(!drawablep) + { + return FALSE; + } + { + drawablep->setGroup(this); + setState(OBJECT_DIRTY | GEOM_DIRTY); + setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); + gPipeline.markRebuild(this); + if (drawablep->isSpatialBridge()) + { + mBridgeList.push_back((LLSpatialBridge*) drawablep); + } + if (drawablep->getRadius() > 1.f) + { + setState(IMAGE_DIRTY); + } + } + + return TRUE; } void LLSpatialGroup::rebuildGeom() { - if (!isDead()) - { - getSpatialPartition()->rebuildGeom(this); + if (!isDead()) + { + getSpatialPartition()->rebuildGeom(this); - if (hasState(LLSpatialGroup::MESH_DIRTY)) - { - gPipeline.markMeshDirty(this); - } - } + if (hasState(LLSpatialGroup::MESH_DIRTY)) + { + gPipeline.markMeshDirty(this); + } + } } void LLSpatialGroup::rebuildMesh() { - if (!isDead()) - { - getSpatialPartition()->rebuildMesh(this); - } + if (!isDead()) + { + getSpatialPartition()->rebuildMesh(this); + } } void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) - { - return; - } - - if (group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; - } - + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) + { + return; + } + + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; - group->clearDrawMap(); - - //get geometry count - U32 index_count = 0; - U32 vertex_count = 0; + group->clearDrawMap(); + + //get geometry count + U32 index_count = 0; + U32 vertex_count = 0; addGeometryCount(group, vertex_count, index_count); - - if (vertex_count > 0 && index_count > 0) - { //create vertex buffer containing volume geometry for this node - { - group->mBuilt = 1.f; - if (group->mVertexBuffer.isNull() || + + if (vertex_count > 0 && index_count > 0) + { //create vertex buffer containing volume geometry for this node + { + group->mBuilt = 1.f; + if (group->mVertexBuffer.isNull() || group->mVertexBuffer->getNumVerts() != vertex_count || group->mVertexBuffer->getNumVerts() != index_count) - { - group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask); - if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to " - << vertex_count << " vertices and " - << index_count << " indices" << LL_ENDL; - group->mVertexBuffer = NULL; - group->mBufferMap.clear(); - } - } - } - - if (group->mVertexBuffer) - { - getGeometry(group); - } - } - else - { - group->mVertexBuffer = NULL; - group->mBufferMap.clear(); - } - - group->mLastUpdateTime = gFrameTimeSeconds; - group->clearState(LLSpatialGroup::GEOM_DIRTY); + { + group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask); + if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to " + << vertex_count << " vertices and " + << index_count << " indices" << LL_ENDL; + group->mVertexBuffer = NULL; + group->mBufferMap.clear(); + } + } + } + + if (group->mVertexBuffer) + { + getGeometry(group); + } + } + else + { + group->mVertexBuffer = NULL; + group->mBufferMap.clear(); + } + + group->mLastUpdateTime = gFrameTimeSeconds; + group->clearState(LLSpatialGroup::GEOM_DIRTY); } @@ -404,198 +404,198 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) LLSpatialGroup* LLSpatialGroup::getParent() { - return (LLSpatialGroup*)LLViewerOctreeGroup::getParent(); - } + return (LLSpatialGroup*)LLViewerOctreeGroup::getParent(); + } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - - if(!drawablep) - { - return FALSE; - } - - unbound(); - if (mOctreeNode && !from_octree) - { - drawablep->setGroup(NULL); - } - else - { - drawablep->setGroup(NULL); - setState(GEOM_DIRTY); - gPipeline.markRebuild(this); - - if (drawablep->isSpatialBridge()) - { - for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) - { - if (*i == drawablep) - { - mBridgeList.erase(i); - break; - } - } - } - - if (getElementCount() == 0) - { //delete draw map on last element removal since a rebuild might never happen - clearDrawMap(); - } - } - return TRUE; + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + + if(!drawablep) + { + return FALSE; + } + + unbound(); + if (mOctreeNode && !from_octree) + { + drawablep->setGroup(NULL); + } + else + { + drawablep->setGroup(NULL); + setState(GEOM_DIRTY); + gPipeline.markRebuild(this); + + if (drawablep->isSpatialBridge()) + { + for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) + { + if (*i == drawablep) + { + mBridgeList.erase(i); + break; + } + } + } + + if (getElementCount() == 0) + { //delete draw map on last element removal since a rebuild might never happen + clearDrawMap(); + } + } + return TRUE; } void LLSpatialGroup::shift(const LLVector4a &offset) { - LLVector4a t = mOctreeNode->getCenter(); - t.add(offset); - mOctreeNode->setCenter(t); - mOctreeNode->updateMinMax(); - mBounds[0].add(offset); - mExtents[0].add(offset); - mExtents[1].add(offset); - mObjectBounds[0].add(offset); - mObjectExtents[0].add(offset); - mObjectExtents[1].add(offset); - - if (!getSpatialPartition()->mRenderByGroup && - getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && - getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && - getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE && - getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR && - getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV) - { - setState(GEOM_DIRTY); - gPipeline.markRebuild(this); - } + LLVector4a t = mOctreeNode->getCenter(); + t.add(offset); + mOctreeNode->setCenter(t); + mOctreeNode->updateMinMax(); + mBounds[0].add(offset); + mExtents[0].add(offset); + mExtents[1].add(offset); + mObjectBounds[0].add(offset); + mObjectExtents[0].add(offset); + mObjectExtents[1].add(offset); + + if (!getSpatialPartition()->mRenderByGroup && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV) + { + setState(GEOM_DIRTY); + gPipeline.markRebuild(this); + } } class LLSpatialSetState : public OctreeTraveler { public: - U32 mState; - LLSpatialSetState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } + U32 mState; + LLSpatialSetState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState { public: - LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (!group->hasState(mState)) - { - OctreeTraveler::traverse(n); - } - } + LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (!group->hasState(mState)) + { + OctreeTraveler::traverse(n); + } + } }; -void LLSpatialGroup::setState(U32 state, S32 mode) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - - llassert(state <= LLSpatialGroup::STATE_MASK); - - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialSetStateDiff setter(state); - setter.traverse(mOctreeNode); - } - else - { - LLSpatialSetState setter(state); - setter.traverse(mOctreeNode); - } - } - else - { - mState |= state; - } +void LLSpatialGroup::setState(U32 state, S32 mode) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + + llassert(state <= LLSpatialGroup::STATE_MASK); + + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialSetStateDiff setter(state); + setter.traverse(mOctreeNode); + } + else + { + LLSpatialSetState setter(state); + setter.traverse(mOctreeNode); + } + } + else + { + mState |= state; + } } class LLSpatialClearState : public OctreeTraveler { public: - U32 mState; - LLSpatialClearState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } + U32 mState; + LLSpatialClearState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState { public: - LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (group->hasState(mState)) - { - OctreeTraveler::traverse(n); - } - } + LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (group->hasState(mState)) + { + OctreeTraveler::traverse(n); + } + } }; void LLSpatialGroup::clearState(U32 state, S32 mode) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - - llassert(state <= LLSpatialGroup::STATE_MASK); - - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialClearStateDiff clearer(state); - clearer.traverse(mOctreeNode); - } - else - { - LLSpatialClearState clearer(state); - clearer.traverse(mOctreeNode); - } - } - else - { - mState &= ~state; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + + llassert(state <= LLSpatialGroup::STATE_MASK); + + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialClearStateDiff clearer(state); + clearer.traverse(mOctreeNode); + } + else + { + LLSpatialClearState clearer(state); + clearer.traverse(mOctreeNode); + } + } + else + { + mState &= ~state; + } } //====================================== -// Octree Listener Implementation +// Octree Listener Implementation //====================================== LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part), - mObjectBoxSize(1.f), - mGeometryBytes(0), - mSurfaceArea(0.f), - mBuilt(0.f), - mVertexBuffer(NULL), - mDistance(0.f), - mDepth(0.f), - mLastUpdateDistance(-1.f), - mLastUpdateTime(gFrameTimeSeconds) -{ - ll_assert_aligned(this,16); - - sNodeCount++; - - mViewAngle.splat(0.f); - mLastUpdateViewAngle.splat(-1.f); - - sg_assert(mOctreeNode->getListenerCount() == 0); - setState(SG_INITIAL_STATE_MASK); - gPipeline.markRebuild(this); - + mObjectBoxSize(1.f), + mGeometryBytes(0), + mSurfaceArea(0.f), + mBuilt(0.f), + mVertexBuffer(NULL), + mDistance(0.f), + mDepth(0.f), + mLastUpdateDistance(-1.f), + mLastUpdateTime(gFrameTimeSeconds) +{ + ll_assert_aligned(this,16); + + sNodeCount++; + + mViewAngle.splat(0.f); + mLastUpdateViewAngle.splat(-1.f); + + sg_assert(mOctreeNode->getListenerCount() == 0); + setState(SG_INITIAL_STATE_MASK); + gPipeline.markRebuild(this); + // let the reflection map manager know about this spatial group mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this); @@ -605,141 +605,141 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO void LLSpatialGroup::updateDistance(LLCamera &camera) { - if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) - { - LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL; + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL; llassert(false); - return; - } + return; + } - if (gShiftFrame) - { - return; - } + if (gShiftFrame) + { + return; + } #if !LL_RELEASE_FOR_DOWNLOAD - if (hasState(LLSpatialGroup::OBJECT_DIRTY)) - { - LL_ERRS() << "Spatial group dirty on distance update." << LL_ENDL; - } + if (hasState(LLSpatialGroup::OBJECT_DIRTY)) + { + LL_ERRS() << "Spatial group dirty on distance update." << LL_ENDL; + } #endif - if (!isEmpty()) - { - mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : - (F32) mOctreeNode->getSize().getLength3().getF32(); - mDistance = getSpatialPartition()->calcDistance(this, camera); - mPixelArea = getSpatialPartition()->calcPixelArea(this, camera); - } + if (!isEmpty()) + { + mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : + (F32) mOctreeNode->getSize().getLength3().getF32(); + mDistance = getSpatialPartition()->calcDistance(this, camera); + mPixelArea = getSpatialPartition()->calcPixelArea(this, camera); + } } F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - - LLVector4a eye; - LLVector4a origin; - origin.load3(camera.getOrigin().mV); - - eye.setSub(group->mObjectBounds[0], origin); - - F32 dist = 0.f; - - if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end()) - { - LLVector4a v = eye; - - dist = eye.getLength3().getF32(); - eye.normalize3fast(); - - if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) - { - if (!group->getSpatialPartition()->isBridge()) - { - LLVector4a view_angle = eye; - - LLVector4a diff; - diff.setSub(view_angle, group->mLastUpdateViewAngle); - - if (diff.getLength3().getF32() > 0.64f) - { - group->mViewAngle = view_angle; - group->mLastUpdateViewAngle = view_angle; - //for occasional alpha sorting within the group - //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, - //not setting this node to dirty would be a very good thing - group->setState(LLSpatialGroup::ALPHA_DIRTY); - gPipeline.markRebuild(group); - } - } - } - - //calculate depth of node for alpha sorting - - LLVector3 at = camera.getAtAxis(); - - LLVector4a ata; - ata.load3(at.mV); - - LLVector4a t = ata; - //front of bounding box - t.mul(0.25f); - t.mul(group->mObjectBounds[1]); - v.sub(t); - - group->mDepth = v.dot3(ata).getF32(); - } - else - { - dist = eye.getLength3().getF32(); - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + + LLVector4a eye; + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + eye.setSub(group->mObjectBounds[0], origin); + + F32 dist = 0.f; + + if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end()) + { + LLVector4a v = eye; + + dist = eye.getLength3().getF32(); + eye.normalize3fast(); + + if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) + { + if (!group->getSpatialPartition()->isBridge()) + { + LLVector4a view_angle = eye; + + LLVector4a diff; + diff.setSub(view_angle, group->mLastUpdateViewAngle); + + if (diff.getLength3().getF32() > 0.64f) + { + group->mViewAngle = view_angle; + group->mLastUpdateViewAngle = view_angle; + //for occasional alpha sorting within the group + //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, + //not setting this node to dirty would be a very good thing + group->setState(LLSpatialGroup::ALPHA_DIRTY); + gPipeline.markRebuild(group); + } + } + } + + //calculate depth of node for alpha sorting + + LLVector3 at = camera.getAtAxis(); + + LLVector4a ata; + ata.load3(at.mV); + + LLVector4a t = ata; + //front of bounding box + t.mul(0.25f); + t.mul(group->mObjectBounds[1]); + v.sub(t); + + group->mDepth = v.dot3(ata).getF32(); + } + else + { + dist = eye.getLength3().getF32(); + } #if !LL_RELEASE - LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds " - << group->mObjectBounds[0] << ", " << group->mObjectBounds[1] + LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds " + << group->mObjectBounds[0] << ", " << group->mObjectBounds[1] << " dist " << dist << " radius " << group->mRadius << LL_ENDL; #endif - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } - return dist; + return dist; } F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) { - return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); + return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } F32 LLSpatialGroup::getUpdateUrgency() const { - if (!isVisible()) - { - return 0.f; - } - else - { - F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f; - return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance; - } + if (!isVisible()) + { + return 0.f; + } + else + { + F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f; + return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance; + } } BOOL LLSpatialGroup::changeLOD() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) - { - //a rebuild is going to happen, update distance and LoD - return TRUE; - } + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) + { + //a rebuild is going to happen, update distance and LoD + return TRUE; + } - if (getSpatialPartition()->mSlopRatio > 0.f) - { - F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); + if (getSpatialPartition()->mSlopRatio > 0.f) + { + F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); // MAINT-8264 - this check is not robust if it needs to work // for bounding boxes much larger than the actual enclosed @@ -753,85 +753,85 @@ BOOL LLSpatialGroup::changeLOD() // was large only due to another error, so this logic did not // need to be changed. - if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) - { + if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) + { LL_DEBUGS("RiggedBox") << "changeLOD true because of ratio compare " << fabsf(ratio) << " " << getSpatialPartition()->mSlopRatio << LL_ENDL; LL_DEBUGS("RiggedBox") << "sg " << this << "\nmDistance " << mDistance << " mLastUpdateDistance " << mLastUpdateDistance << " mRadius " << mRadius - << " fab ratio " << fabsf(ratio) + << " fab ratio " << fabsf(ratio) << " slop " << getSpatialPartition()->mSlopRatio << LL_ENDL; - - return TRUE; - } - } - - if (needsUpdate()) - { - return TRUE; - } - - return FALSE; + + return TRUE; + } + } + + if (needsUpdate()) + { + return TRUE; + } + + return FALSE; } void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - addObject((LLDrawable*)entry->getDrawable()); - unbound(); - setState(OBJECT_DIRTY); + addObject((LLDrawable*)entry->getDrawable()); + unbound(); + setState(OBJECT_DIRTY); } void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - removeObject((LLDrawable*)entry->getDrawable(), TRUE); - LLViewerOctreeGroup::handleRemoval(node, entry); + removeObject((LLDrawable*)entry->getDrawable(), TRUE); + LLViewerOctreeGroup::handleRemoval(node, entry); } void LLSpatialGroup::handleDestruction(const TreeNode* node) { - if(isDead()) - { - return; - } - setState(DEAD); - - for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) - { - LLViewerOctreeEntry* entry = *i; - - if (entry->getGroup() == this) - { - if(entry->hasDrawable()) - { - ((LLDrawable*)entry->getDrawable())->setGroup(NULL); - } - } - } - - clearDrawMap(); - mVertexBuffer = NULL; - mBufferMap.clear(); - sZombieGroups++; - mOctreeNode = NULL; + if(isDead()) + { + return; + } + setState(DEAD); + + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) + { + LLViewerOctreeEntry* entry = *i; + + if (entry->getGroup() == this) + { + if(entry->hasDrawable()) + { + ((LLDrawable*)entry->getDrawable())->setGroup(NULL); + } + } + } + + clearDrawMap(); + mVertexBuffer = NULL; + mBufferMap.clear(); + sZombieGroups++; + mOctreeNode = NULL; } -void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL - if (child->getListenerCount() == 0) - { - new LLSpatialGroup(child, getSpatialPartition()); - } - else - { - OCT_ERRS << "LLSpatialGroup redundancy detected." << LL_ENDL; - } + if (child->getListenerCount() == 0) + { + new LLSpatialGroup(child, getSpatialPartition()); + } + else + { + OCT_ERRS << "LLSpatialGroup redundancy detected." << LL_ENDL; + } - unbound(); + unbound(); - assert_states_valid(this); + assert_states_valid(this); } //virtual @@ -872,41 +872,41 @@ void LLSpatialGroup::rebound() void LLSpatialGroup::destroyGLState(bool keep_occlusion) { - setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); - - if (!keep_occlusion) - { //going to need a rebuild - gPipeline.markRebuild(this); - } - - mLastUpdateTime = gFrameTimeSeconds; - mVertexBuffer = NULL; - mBufferMap.clear(); - - clearDrawMap(); - - if (!keep_occlusion) - { - releaseOcclusionQueryObjectNames(); - } - - - for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - for (S32 j = 0; j < drawable->getNumFaces(); j++) - { - LLFace* facep = drawable->getFace(j); - if (facep) - { - facep->clearVertexBuffer(); - } - } - } + setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); + + if (!keep_occlusion) + { //going to need a rebuild + gPipeline.markRebuild(this); + } + + mLastUpdateTime = gFrameTimeSeconds; + mVertexBuffer = NULL; + mBufferMap.clear(); + + clearDrawMap(); + + if (!keep_occlusion) + { + releaseOcclusionQueryObjectNames(); + } + + + for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + for (S32 j = 0; j < drawable->getNumFaces(); j++) + { + LLFace* facep = drawable->getFace(j); + if (facep) + { + facep->clearVertexBuffer(); + } + } + } } //============================================== @@ -914,14 +914,14 @@ void LLSpatialGroup::destroyGLState(bool keep_occlusion) LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp) : mRenderByGroup(render_by_group), mBridge(NULL) { - mRegionp = regionp; - mPartitionType = LLViewerRegion::PARTITION_NONE; - mVertexDataMask = data_mask; - mDepthMask = FALSE; - mSlopRatio = 0.25f; - mInfiniteFarClip = FALSE; + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_NONE; + mVertexDataMask = data_mask; + mDepthMask = FALSE; + mSlopRatio = 0.25f; + mInfiniteFarClip = FALSE; - new LLSpatialGroup(mOctree, this); + new LLSpatialGroup(mOctree, this); } @@ -933,391 +933,391 @@ LLSpatialPartition::~LLSpatialPartition() LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { LL_PROFILE_ZONE_SCOPED; - drawablep->updateSpatialExtents(); - - //keep drawable from being garbage collected - LLPointer ptr = drawablep; - - if(!drawablep->getGroup()) - { - assert_octree_valid(mOctree); - mOctree->insert(drawablep->getEntry()); - assert_octree_valid(mOctree); - } - - LLSpatialGroup* group = drawablep->getSpatialGroup(); - //llassert(group != NULL); - - if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) - { - group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); - } - - return group; + drawablep->updateSpatialExtents(); + + //keep drawable from being garbage collected + LLPointer ptr = drawablep; + + if(!drawablep->getGroup()) + { + assert_octree_valid(mOctree); + mOctree->insert(drawablep->getEntry()); + assert_octree_valid(mOctree); + } + + LLSpatialGroup* group = drawablep->getSpatialGroup(); + //llassert(group != NULL); + + if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) + { + group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); + } + + return group; } BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) { LL_PROFILE_ZONE_SCOPED; - if (!curp->removeObject(drawablep)) - { - OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL; - } - else - { - drawablep->setGroup(NULL); - } - - assert_octree_valid(mOctree); - - return TRUE; -} + if (!curp->removeObject(drawablep)) + { + OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL; + } + else + { + drawablep->setGroup(NULL); + } + + assert_octree_valid(mOctree); + + return TRUE; +} void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) { LL_PROFILE_ZONE_SCOPED; - // sanity check submitted by open source user bushing Spatula - // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) - if (!drawablep) - { - OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << LL_ENDL; - return; - } - - BOOL was_visible = curp ? curp->isVisible() : FALSE; - - if (curp && curp->getSpatialPartition() != this) - { - //keep drawable from being garbage collected - LLPointer ptr = drawablep; - if (curp->getSpatialPartition()->remove(drawablep, curp)) - { - put(drawablep, was_visible); - return; - } - else - { - OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << LL_ENDL; - } - } - - if (curp && curp->updateInGroup(drawablep, immediate)) - { - // Already updated, don't need to do anything - assert_octree_valid(mOctree); - return; - } - - //keep drawable from being garbage collected - LLPointer ptr = drawablep; - if (curp && !remove(drawablep, curp)) - { - OCT_ERRS << "Move couldn't find existing spatial group!" << LL_ENDL; - } - - put(drawablep, was_visible); + // sanity check submitted by open source user bushing Spatula + // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) + if (!drawablep) + { + OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << LL_ENDL; + return; + } + + BOOL was_visible = curp ? curp->isVisible() : FALSE; + + if (curp && curp->getSpatialPartition() != this) + { + //keep drawable from being garbage collected + LLPointer ptr = drawablep; + if (curp->getSpatialPartition()->remove(drawablep, curp)) + { + put(drawablep, was_visible); + return; + } + else + { + OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << LL_ENDL; + } + } + + if (curp && curp->updateInGroup(drawablep, immediate)) + { + // Already updated, don't need to do anything + assert_octree_valid(mOctree); + return; + } + + //keep drawable from being garbage collected + LLPointer ptr = drawablep; + if (curp && !remove(drawablep, curp)) + { + OCT_ERRS << "Move couldn't find existing spatial group!" << LL_ENDL; + } + + put(drawablep, was_visible); } class LLSpatialShift : public OctreeTraveler { public: - const LLVector4a& mOffset; + const LLVector4a& mOffset; - LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } - virtual void visit(const OctreeNode* branch) - { - ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); - } + LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } + virtual void visit(const OctreeNode* branch) + { + ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); + } }; void LLSpatialPartition::shift(const LLVector4a &offset) { //shift octree node bounding boxes by offset - LLSpatialShift shifter(offset); - shifter.traverse(mOctree); + LLSpatialShift shifter(offset); + shifter.traverse(mOctree); } class LLOctreeCull : public LLViewerOctreeCull { public: - LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} + LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} - virtual bool earlyFail(LLViewerOctreeGroup* base_group) - { + virtual bool earlyFail(LLViewerOctreeGroup* base_group) + { if (LLPipeline::sReflectionRender) { return false; } - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - group->checkOcclusion(); - - if (group->getOctreeNode()->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - gPipeline.markOccluder(group); - return true; - } - - return false; - } - - virtual S32 frustumCheck(const LLViewerOctreeGroup* group) - { - S32 res = AABBInFrustumNoFarClipGroupBounds(group); - if (res != 0) - { - res = llmin(res, AABBSphereIntersectGroupExtents(group)); - } - return res; - } - - virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) - { - S32 res = AABBInFrustumNoFarClipObjectBounds(group); - if (res != 0) - { - res = llmin(res, AABBSphereIntersectObjectExtents(group)); - } - return res; - } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - /*if (group->needsUpdate() || - group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1) - { - group->doOcclusion(mCamera); - }*/ - gPipeline.markNotCulled(group, *mCamera); - } + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + group->checkOcclusion(); + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + gPipeline.markOccluder(group); + return true; + } + + return false; + } + + virtual S32 frustumCheck(const LLViewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipGroupBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectGroupExtents(group)); + } + return res; + } + + virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipObjectBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectObjectExtents(group)); + } + return res; + } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + /*if (group->needsUpdate() || + group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1) + { + group->doOcclusion(mCamera); + }*/ + gPipeline.markNotCulled(group, *mCamera); + } }; class LLOctreeCullNoFarClip : public LLOctreeCull { -public: - LLOctreeCullNoFarClip(LLCamera* camera) - : LLOctreeCull(camera) { } +public: + LLOctreeCullNoFarClip(LLCamera* camera) + : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLViewerOctreeGroup* group) - { - return AABBInFrustumNoFarClipGroupBounds(group); - } + virtual S32 frustumCheck(const LLViewerOctreeGroup* group) + { + return AABBInFrustumNoFarClipGroupBounds(group); + } - virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) - { - S32 res = AABBInFrustumNoFarClipObjectBounds(group); - return res; - } + virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipObjectBounds(group); + return res; + } }; class LLOctreeCullShadow : public LLOctreeCull { public: - LLOctreeCullShadow(LLCamera* camera) - : LLOctreeCull(camera) { } - - virtual S32 frustumCheck(const LLViewerOctreeGroup* group) - { - return AABBInFrustumGroupBounds(group); - } - - virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) - { - return AABBInFrustumObjectBounds(group); - } + LLOctreeCullShadow(LLCamera* camera) + : LLOctreeCull(camera) { } + + virtual S32 frustumCheck(const LLViewerOctreeGroup* group) + { + return AABBInFrustumGroupBounds(group); + } + + virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) + { + return AABBInFrustumObjectBounds(group); + } }; class LLOctreeCullVisExtents: public LLOctreeCullShadow { public: - LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) - : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } - - virtual bool earlyFail(LLViewerOctreeGroup* base_group) - { - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - - if (group->getOctreeNode()->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - return true; - } - - return false; - } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (earlyFail(group)) - { - return; - } - - if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || - mRes == 2) - { //don't need to do frustum check - OctreeTraveler::traverse(n); - } - else - { - mRes = frustumCheck(group); - - if (mRes) - { //at least partially in, run on down - OctreeTraveler::traverse(n); - } - - mRes = 0; - } - } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - - llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty()); - - if (mRes < 2) - { - if (AABBInFrustumObjectBounds(group) > 0) - { - mEmpty = FALSE; - const LLVector4a* exts = group->getObjectExtents(); - update_min_max(mMin, mMax, exts[0]); - update_min_max(mMin, mMax, exts[1]); - } - } - else - { - mEmpty = FALSE; - const LLVector4a* exts = group->getExtents(); - update_min_max(mMin, mMax, exts[0]); - update_min_max(mMin, mMax, exts[1]); - } - } - - BOOL mEmpty; - LLVector4a& mMin; - LLVector4a& mMax; + LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) + : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } + + virtual bool earlyFail(LLViewerOctreeGroup* base_group) + { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + return true; + } + + return false; + } + + virtual void traverse(const OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || + mRes == 2) + { //don't need to do frustum check + OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + OctreeTraveler::traverse(n); + } + + mRes = 0; + } + } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty()); + + if (mRes < 2) + { + if (AABBInFrustumObjectBounds(group) > 0) + { + mEmpty = FALSE; + const LLVector4a* exts = group->getObjectExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); + } + } + else + { + mEmpty = FALSE; + const LLVector4a* exts = group->getExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); + } + } + + BOOL mEmpty; + LLVector4a& mMin; + LLVector4a& mMax; }; class LLOctreeCullDetectVisible: public LLOctreeCullShadow { public: - LLOctreeCullDetectVisible(LLCamera* camera) - : LLOctreeCullShadow(camera), mResult(FALSE) { } - - virtual bool earlyFail(LLViewerOctreeGroup* base_group) - { - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - - if (mResult || //already found a node, don't check any more - (group->getOctreeNode()->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isOcclusionState(LLSpatialGroup::OCCLUDED))) - { - return true; - } - - return false; - } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - if (base_group->isVisible()) - { - mResult = TRUE; - } - } - - BOOL mResult; + LLOctreeCullDetectVisible(LLCamera* camera) + : LLOctreeCullShadow(camera), mResult(FALSE) { } + + virtual bool earlyFail(LLViewerOctreeGroup* base_group) + { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + if (mResult || //already found a node, don't check any more + (group->getOctreeNode()->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isOcclusionState(LLSpatialGroup::OCCLUDED))) + { + return true; + } + + return false; + } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + if (base_group->isVisible()) + { + mResult = TRUE; + } + } + + BOOL mResult; }; class LLOctreeSelect : public LLOctreeCull { public: - LLOctreeSelect(LLCamera* camera, std::vector* results) - : LLOctreeCull(camera), mResults(results) { } - - virtual bool earlyFail(LLViewerOctreeGroup* group) { return false; } - virtual void preprocess(LLViewerOctreeGroup* group) { } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - LLSpatialGroup* group = (LLSpatialGroup*)base_group; - OctreeNode* branch = group->getOctreeNode(); - - for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - if (!drawable->isDead()) - { - if (drawable->isSpatialBridge()) - { - drawable->setVisible(*mCamera, mResults, TRUE); - } - else - { - mResults->push_back(drawable); - } - } - } - } - - std::vector* mResults; + LLOctreeSelect(LLCamera* camera, std::vector* results) + : LLOctreeCull(camera), mResults(results) { } + + virtual bool earlyFail(LLViewerOctreeGroup* group) { return false; } + virtual void preprocess(LLViewerOctreeGroup* group) { } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + OctreeNode* branch = group->getOctreeNode(); + + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + if (!drawable->isDead()) + { + if (drawable->isSpatialBridge()) + { + drawable->setVisible(*mCamera, mResults, TRUE); + } + else + { + mResults->push_back(drawable); + } + } + } + } + + std::vector* mResults; }; void drawBox(const LLVector3& c, const LLVector3& r) { - LLVertexBuffer::unbind(); - - gGL.begin(LLRender::TRIANGLE_STRIP); - //left front - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); - //right front - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); - //right back - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); - //left back - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); - //left front - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); - gGL.end(); - - //bottom - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); - gGL.end(); - - //top - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); - gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); - gGL.end(); + LLVertexBuffer::unbind(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + //left front + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + //right front + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); + //right back + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); + //left back + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); + //left front + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + gGL.end(); + + //bottom + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); + gGL.end(); + + //top + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); + gGL.end(); } void drawBox(const LLVector4a& c, const LLVector4a& r) { - drawBox(reinterpret_cast(c), reinterpret_cast(r)); + drawBox(reinterpret_cast(c), reinterpret_cast(r)); } void drawBoxOutline(const LLVector3& pos, const LLVector3& size) @@ -1325,53 +1325,53 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size) if (!pos.isFinite() || !size.isFinite()) return; - LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); - LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1)); - LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); - LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); - - gGL.begin(LLRender::LINES); - - //top - gGL.vertex3fv((pos+v1).mV); - gGL.vertex3fv((pos+v2).mV); - gGL.vertex3fv((pos+v2).mV); - gGL.vertex3fv((pos+v3).mV); - gGL.vertex3fv((pos+v3).mV); - gGL.vertex3fv((pos+v4).mV); - gGL.vertex3fv((pos+v4).mV); - gGL.vertex3fv((pos+v1).mV); - - //bottom - gGL.vertex3fv((pos-v1).mV); - gGL.vertex3fv((pos-v2).mV); - gGL.vertex3fv((pos-v2).mV); - gGL.vertex3fv((pos-v3).mV); - gGL.vertex3fv((pos-v3).mV); - gGL.vertex3fv((pos-v4).mV); - gGL.vertex3fv((pos-v4).mV); - gGL.vertex3fv((pos-v1).mV); - - //right - gGL.vertex3fv((pos+v1).mV); - gGL.vertex3fv((pos-v3).mV); - - gGL.vertex3fv((pos+v4).mV); - gGL.vertex3fv((pos-v2).mV); - - //left - gGL.vertex3fv((pos+v2).mV); - gGL.vertex3fv((pos-v4).mV); - - gGL.vertex3fv((pos+v3).mV); - gGL.vertex3fv((pos-v1).mV); - - gGL.end(); + LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); + LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1)); + LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); + LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); + + gGL.begin(LLRender::LINES); + + //top + gGL.vertex3fv((pos+v1).mV); + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos+v1).mV); + + //bottom + gGL.vertex3fv((pos-v1).mV); + gGL.vertex3fv((pos-v2).mV); + gGL.vertex3fv((pos-v2).mV); + gGL.vertex3fv((pos-v3).mV); + gGL.vertex3fv((pos-v3).mV); + gGL.vertex3fv((pos-v4).mV); + gGL.vertex3fv((pos-v4).mV); + gGL.vertex3fv((pos-v1).mV); + + //right + gGL.vertex3fv((pos+v1).mV); + gGL.vertex3fv((pos-v3).mV); + + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos-v2).mV); + + //left + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos-v4).mV); + + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos-v1).mV); + + gGL.end(); } void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) { - drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); + drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); } @@ -1382,49 +1382,49 @@ void LLSpatialPartition::restoreGL() BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; - LLVector4a visMina, visMaxa; - visMina.load3(visMin.mV); - visMaxa.load3(visMax.mV); + LLVector4a visMina, visMaxa; + visMina.load3(visMin.mV); + visMaxa.load3(visMax.mV); - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); - group->rebound(); - } + { + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); + } - LLOctreeCullVisExtents vis(&camera, visMina, visMaxa); - vis.traverse(mOctree); + LLOctreeCullVisExtents vis(&camera, visMina, visMaxa); + vis.traverse(mOctree); - visMin.set(visMina.getF32ptr()); - visMax.set(visMaxa.getF32ptr()); - return vis.mEmpty; + visMin.set(visMina.getF32ptr()); + visMax.set(visMaxa.getF32ptr()); + return vis.mEmpty; } BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) { - LLOctreeCullDetectVisible vis(&camera); - vis.traverse(mOctree); - return vis.mResult; + LLOctreeCullDetectVisible vis(&camera); + vis.traverse(mOctree); + return vis.mResult; } S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; #if LL_OCTREE_PARANOIA_CHECK - ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); - group->rebound(); - } + { + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); + } #if LL_OCTREE_PARANOIA_CHECK - ((LLSpatialGroup*)mOctree->getListener(0))->validate(); + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif - LLOctreeSelect selecter(&camera, results); - selecter.traverse(mOctree); - - return 0; + LLOctreeSelect selecter(&camera, results); + selecter.traverse(mOctree); + + return 0; } extern BOOL gCubeSnapshot; @@ -1433,13 +1433,13 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; #if LL_OCTREE_PARANOIA_CHECK - ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif - LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); - group->rebound(); + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); #if LL_OCTREE_PARANOIA_CHECK - ((LLSpatialGroup*)mOctree->getListener(0))->validate(); + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif if (LLPipeline::sShadowRender) @@ -1457,132 +1457,132 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) LLOctreeCull culler(&camera); culler.traverse(mOctree); } - - return 0; + + return 0; } void pushVerts(LLDrawInfo* params) { - LLRenderPass::applyModelMatrix(*params); - params->mVertexBuffer->setBuffer(); - params->mVertexBuffer->drawRange(LLRender::TRIANGLES, - params->mStart, params->mEnd, params->mCount, params->mOffset); + LLRenderPass::applyModelMatrix(*params); + params->mVertexBuffer->setBuffer(); + params->mVertexBuffer->drawRange(LLRender::TRIANGLES, + params->mStart, params->mEnd, params->mCount, params->mOffset); } void pushVerts(LLSpatialGroup* group) { - LLDrawInfo* params = NULL; + LLDrawInfo* params = NULL; - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) - { - params = *j; - pushVerts(params); - } - } + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + params = *j; + pushVerts(params); + } + } } void pushVerts(LLFace* face) { - if (face) - { - llassert(face->verify()); + if (face) + { + llassert(face->verify()); face->renderIndexed(); - } + } } void pushVerts(LLDrawable* drawable) { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - pushVerts(drawable->getFace(i)); - } + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + pushVerts(drawable->getFace(i)); + } } void pushVerts(LLVolume* volume) { - LLVertexBuffer::unbind(); - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices); - } + LLVertexBuffer::unbind(); + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices); + } } void pushBufferVerts(LLVertexBuffer* buffer) { - if (buffer) - { - buffer->setBuffer(); - buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); - } + if (buffer) + { + buffer->setBuffer(); + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + } } void pushBufferVerts(LLSpatialGroup* group, bool push_alpha = true) { - if (group->getSpatialPartition()->mRenderByGroup) - { - if (!group->mDrawMap.empty()) - { - LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); - LLRenderPass::applyModelMatrix(*params); - - if (push_alpha) - { - pushBufferVerts(group->mVertexBuffer); - } - - for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) - { - for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j) - { - for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k) - { - pushBufferVerts(*k); - } - } - } - } - } - /*else - { - //const LLVector4a* bounds = group->getBounds(); - //drawBox(bounds[0], bounds[1]); - }*/ + if (group->getSpatialPartition()->mRenderByGroup) + { + if (!group->mDrawMap.empty()) + { + LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); + LLRenderPass::applyModelMatrix(*params); + + if (push_alpha) + { + pushBufferVerts(group->mVertexBuffer); + } + + for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + { + for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k) + { + pushBufferVerts(*k); + } + } + } + } + } + /*else + { + //const LLVector4a* bounds = group->getBounds(); + //drawBox(bounds[0], bounds[1]); + }*/ } void pushVertsColorCoded(LLSpatialGroup* group) { - LLDrawInfo* params = NULL; - - static const LLColor4 colors[] = { - LLColor4::green, - LLColor4::green1, - LLColor4::green2, - LLColor4::green3, - LLColor4::green4, - LLColor4::green5, - LLColor4::green6 - }; - - static const U32 col_count = LL_ARRAY_SIZE(colors); - - U32 col = 0; - - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) - { - params = *j; - LLRenderPass::applyModelMatrix(*params); - gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); - params->mVertexBuffer->setBuffer(); - params->mVertexBuffer->drawRange(LLRender::TRIANGLES, - params->mStart, params->mEnd, params->mCount, params->mOffset); - col = (col+1)%col_count; - } - } + LLDrawInfo* params = NULL; + + static const LLColor4 colors[] = { + LLColor4::green, + LLColor4::green1, + LLColor4::green2, + LLColor4::green3, + LLColor4::green4, + LLColor4::green5, + LLColor4::green6 + }; + + static const U32 col_count = LL_ARRAY_SIZE(colors); + + U32 col = 0; + + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + params = *j; + LLRenderPass::applyModelMatrix(*params); + gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); + params->mVertexBuffer->setBuffer(); + params->mVertexBuffer->drawRange(LLRender::TRIANGLES, + params->mStart, params->mEnd, params->mCount, params->mOffset); + col = (col+1)%col_count; + } + } } // return false if drawable is rigged and: @@ -1630,7 +1630,7 @@ bool check_rigged_group(LLDrawable* drawable) last_draw_index = face->getDrawOrderIndex(); } } - + if (child->mDrawable->getSpatialGroup() != group) { llassert(false); @@ -1644,49 +1644,49 @@ bool check_rigged_group(LLDrawable* drawable) void renderOctree(LLSpatialGroup* group) { - //render solid object bounding box, color - //coded by buffer usage and activity - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - LLVector4 col; - if (group->mBuilt > 0.f) - { - group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); - col.setVec(0.1f,0.1f,1,0.1f); - - { - LLGLDepthTest gl_depth(FALSE, FALSE); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - gGL.diffuseColor4f(1,0,0,group->mBuilt); - gGL.flush(); - glLineWidth(5.f); - - const LLVector4a* bounds = group->getObjectBounds(); - drawBoxOutline(bounds[0], bounds[1]); - gGL.flush(); - glLineWidth(1.f); - gGL.flush(); + //render solid object bounding box, color + //coded by buffer usage and activity + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + LLVector4 col; + if (group->mBuilt > 0.f) + { + group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); + col.setVec(0.1f,0.1f,1,0.1f); + + { + LLGLDepthTest gl_depth(FALSE, FALSE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + gGL.diffuseColor4f(1,0,0,group->mBuilt); + gGL.flush(); + glLineWidth(5.f); + + const LLVector4a* bounds = group->getObjectBounds(); + drawBoxOutline(bounds[0], bounds[1]); + gGL.flush(); + glLineWidth(1.f); + gGL.flush(); LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable || drawable->getNumFaces() == 0) - { - continue; - } + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable || drawable->getNumFaces() == 0) + { + continue; + } llassert(check_rigged_group(drawable)); - if (!group->getSpatialPartition()->isBridge()) - { - gGL.pushMatrix(); - LLVector3 trans = drawable->getRegion()->getOriginAgent(); - gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - } - + if (!group->getSpatialPartition()->isBridge()) + { + gGL.pushMatrix(); + LLVector3 trans = drawable->getRegion()->getOriginAgent(); + gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); + } + LLFace* face = drawable->getFace(0); bool rigged = face->isState(LLFace::RIGGED); gDebugProgram.bind(rigged); @@ -1708,11 +1708,11 @@ void renderOctree(LLSpatialGroup* group) lastMeshId = face->mSkinInfo->mHash; } } - for (S32 j = 0; j < drawable->getNumFaces(); j++) - { - LLFace* face = drawable->getFace(j); - if (face && face->getVertexBuffer()) - { + for (S32 j = 0; j < drawable->getNumFaces(); j++) + { + LLFace* face = drawable->getFace(j); + if (face && face->getVertexBuffer()) + { LLVOVolume* vol = drawable->getVOVolume(); if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) @@ -1742,40 +1742,40 @@ void renderOctree(LLSpatialGroup* group) continue; } - face->getVertexBuffer()->setBuffer(); - face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); - } - } + face->getVertexBuffer()->setBuffer(); + face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); + } + } if (rigged) { gGL.popMatrix(); } - if (!group->getSpatialPartition()->isBridge()) - { - gGL.popMatrix(); - } - } - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (!group->getSpatialPartition()->isBridge()) + { + gGL.popMatrix(); + } + } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); gDebugProgram.bind(); // make sure non-rigged variant is bound - gGL.diffuseColor4f(1,1,1,1); - } - } + gGL.diffuseColor4f(1,1,1,1); + } + } - gGL.diffuseColor4fv(col.mV); - LLVector4a fudge; - fudge.splat(0.001f); + gGL.diffuseColor4fv(col.mV); + LLVector4a fudge; + fudge.splat(0.001f); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - { - //draw opaque outline - gGL.diffuseColor4f(0,1,1,1); + { + //draw opaque outline + gGL.diffuseColor4f(0,1,1,1); - const LLVector4a* bounds = group->getBounds(); - drawBoxOutline(bounds[0], bounds[1]); - } + const LLVector4a* bounds = group->getBounds(); + drawBoxOutline(bounds[0], bounds[1]); + } } std::set visible_selected_groups; @@ -1784,263 +1784,263 @@ std::set visible_selected_groups; void renderXRay(LLSpatialGroup* group, LLCamera* camera) { - BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && - !group->isEmpty(); - - if (render_objects) - { - pushBufferVerts(group, false); - - bool selected = false; - - for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter) - { - LLDrawable* drawable = (LLDrawable*)(*iter)->getDrawable(); - if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected()) - { - selected = true; - break; - } - } - - if (selected) - { //store for rendering occlusion volume as overlay - - if (!group->getSpatialPartition()->isBridge()) - { - visible_selected_groups.insert(group); - } - else - { - visible_selected_groups.insert(group->getSpatialPartition()->asBridge()->getSpatialGroup()); - } - } - } + BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && + !group->isEmpty(); + + if (render_objects) + { + pushBufferVerts(group, false); + + bool selected = false; + + for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter) + { + LLDrawable* drawable = (LLDrawable*)(*iter)->getDrawable(); + if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected()) + { + selected = true; + break; + } + } + + if (selected) + { //store for rendering occlusion volume as overlay + + if (!group->getSpatialPartition()->isBridge()) + { + visible_selected_groups.insert(group); + } + else + { + visible_selected_groups.insert(group->getSpatialPartition()->asBridge()->getSpatialGroup()); + } + } + } } void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color) { - gGL.color4fv(color.mV); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV); - gGL.vertex3fv((position + LLVector3(size, 0.f, 0.f)).mV); - gGL.vertex3fv((position - LLVector3(0.f, size, 0.f)).mV); - gGL.vertex3fv((position + LLVector3(0.f, size, 0.f)).mV); - gGL.vertex3fv((position - LLVector3(0.f, 0.f, size)).mV); - gGL.vertex3fv((position + LLVector3(0.f, 0.f, size)).mV); - } - gGL.end(); + gGL.color4fv(color.mV); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV); + gGL.vertex3fv((position + LLVector3(size, 0.f, 0.f)).mV); + gGL.vertex3fv((position - LLVector3(0.f, size, 0.f)).mV); + gGL.vertex3fv((position + LLVector3(0.f, size, 0.f)).mV); + gGL.vertex3fv((position - LLVector3(0.f, 0.f, size)).mV); + gGL.vertex3fv((position + LLVector3(0.f, 0.f, size)).mV); + } + gGL.end(); } void renderUpdateType(LLDrawable* drawablep) { - LLViewerObject* vobj = drawablep->getVObj(); - if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType()) - { - return; - } - LLGLEnable blend(GL_BLEND); - switch (vobj->getLastUpdateType()) - { - case OUT_FULL: - gGL.diffuseColor4f(0,1,0,0.5f); - break; - case OUT_TERSE_IMPROVED: - gGL.diffuseColor4f(0,1,1,0.5f); - break; - case OUT_FULL_COMPRESSED: - if (vobj->getLastUpdateCached()) - { - gGL.diffuseColor4f(1,0,0,0.5f); - } - else - { - gGL.diffuseColor4f(1,1,0,0.5f); - } - break; - case OUT_FULL_CACHED: - gGL.diffuseColor4f(0,0,1,0.5f); - break; - default: - LL_WARNS() << "Unknown update_type " << vobj->getLastUpdateType() << LL_ENDL; - break; - }; - S32 num_faces = drawablep->getNumFaces(); - if (num_faces) - { - for (S32 i = 0; i < num_faces; ++i) - { - pushVerts(drawablep->getFace(i)); - } - } -} - -void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) -{ - if (set_color) - { - if (drawable->isSpatialBridge()) - { - gGL.diffuseColor4f(1,0.5f,0,1); // orange - } - else if (drawable->getVOVolume()) - { - if (drawable->isRoot()) - { - gGL.diffuseColor4f(1,1,0,1); // yellow - } - else - { - gGL.diffuseColor4f(0,1,0,1); // green - } - } - else if (drawable->getVObj()) - { - switch (drawable->getVObj()->getPCode()) - { - case LLViewerObject::LL_VO_SURFACE_PATCH: - gGL.diffuseColor4f(0,1,1,1); // cyan - break; - case LLViewerObject::LL_VO_CLOUDS: - // no longer used - break; - case LLViewerObject::LL_VO_PART_GROUP: - case LLViewerObject::LL_VO_HUD_PART_GROUP: - gGL.diffuseColor4f(0,0,1,1); // blue - break; - case LLViewerObject::LL_VO_VOID_WATER: - case LLViewerObject::LL_VO_WATER: - gGL.diffuseColor4f(0,0.5f,1,1); // medium blue - break; - case LL_PCODE_LEGACY_TREE: - gGL.diffuseColor4f(0,0.5f,0,1); // dark green - break; - default: - LLControlAvatar *cav = dynamic_cast(drawable->getVObj()->asAvatar()); - if (cav) - { - bool has_pos_constraint = (cav->mPositionConstraintFixup != LLVector3()); - bool has_scale_constraint = (cav->mScaleConstraintFixup != 1.0f); - if (has_pos_constraint || has_scale_constraint) - { - gGL.diffuseColor4f(1,0,0,1); - } - else - { - gGL.diffuseColor4f(0,1,0.5,1); - } - } - else - { - gGL.diffuseColor4f(1,0,1,1); // magenta - } - break; - } - } - else - { - gGL.diffuseColor4f(1,0,0,1); - } - } - - const LLVector4a* ext; - LLVector4a pos, size; - - if (drawable->getVOVolume()) - { - //render face bounding boxes - for (S32 i = 0; i < drawable->getNumFaces(); i++) - { - LLFace* facep = drawable->getFace(i); - if (facep) - { - ext = facep->mExtents; - - pos.setAdd(ext[0], ext[1]); - pos.mul(0.5f); - size.setSub(ext[1], ext[0]); - size.mul(0.5f); - - drawBoxOutline(pos,size); - } - } - } - - //render drawable bounding box - ext = drawable->getSpatialExtents(); - - pos.setAdd(ext[0], ext[1]); - pos.mul(0.5f); - size.setSub(ext[1], ext[0]); - size.mul(0.5f); - - LLViewerObject* vobj = drawable->getVObj(); - if (vobj && vobj->onActiveList()) - { - gGL.flush(); - glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f)); - //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f)); - stop_glerror(); - drawBoxOutline(pos,size); - gGL.flush(); - glLineWidth(1.f); - } - else - { - drawBoxOutline(pos,size); - } -} -// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different -// code path which uses a shader - it was tested to be faster than mapping a -// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well -// to simplify and speed up this debug code. Alternatively, a compute shader is -// likely faster. -Cosmic,2023-09-28 -void renderNormals(LLDrawable *drawablep) -{ - if (!drawablep->isVisible()) + LLViewerObject* vobj = drawablep->getVObj(); + if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType()) + { return; - - LLVertexBuffer::unbind(); - - LLViewerObject* obj = drawablep->getVObj(); - LLVOVolume *vol = drawablep->getVOVolume(); - - if (obj) + } + LLGLEnable blend(GL_BLEND); + switch (vobj->getLastUpdateType()) { - LLGLEnable blend(GL_BLEND); - LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE); - - // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied. - // - // SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't - // work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose - // transform. We get that effect here by pre-applying the inverse scale (twice, because - // one forward scale will be re-applied via the MVP in the vertex shader) - - LLVector4a inv_scale; - float scale_len; - if (vol) + case OUT_FULL: + gGL.diffuseColor4f(0,1,0,0.5f); + break; + case OUT_TERSE_IMPROVED: + gGL.diffuseColor4f(0,1,1,0.5f); + break; + case OUT_FULL_COMPRESSED: + if (vobj->getLastUpdateCached()) { - LLVector3 scale_v3 = vol->getScale(); - LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]); - obj_scale.normalize3(); - - // Create inverse-scale vector for normals - inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0); - inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice - - inv_scale.normalize3fast(); - scale_len = scale_v3.length(); + gGL.diffuseColor4f(1,0,0,0.5f); } else { - inv_scale.set(1.0, 1.0, 1.0, 0.0); - scale_len = 1.0; + gGL.diffuseColor4f(1,1,0,0.5f); } - - gGL.pushMatrix(); - if (vol) + break; + case OUT_FULL_CACHED: + gGL.diffuseColor4f(0,0,1,0.5f); + break; + default: + LL_WARNS() << "Unknown update_type " << vobj->getLastUpdateType() << LL_ENDL; + break; + }; + S32 num_faces = drawablep->getNumFaces(); + if (num_faces) + { + for (S32 i = 0; i < num_faces; ++i) + { + pushVerts(drawablep->getFace(i)); + } + } +} + +void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) +{ + if (set_color) + { + if (drawable->isSpatialBridge()) + { + gGL.diffuseColor4f(1,0.5f,0,1); // orange + } + else if (drawable->getVOVolume()) + { + if (drawable->isRoot()) + { + gGL.diffuseColor4f(1,1,0,1); // yellow + } + else + { + gGL.diffuseColor4f(0,1,0,1); // green + } + } + else if (drawable->getVObj()) + { + switch (drawable->getVObj()->getPCode()) + { + case LLViewerObject::LL_VO_SURFACE_PATCH: + gGL.diffuseColor4f(0,1,1,1); // cyan + break; + case LLViewerObject::LL_VO_CLOUDS: + // no longer used + break; + case LLViewerObject::LL_VO_PART_GROUP: + case LLViewerObject::LL_VO_HUD_PART_GROUP: + gGL.diffuseColor4f(0,0,1,1); // blue + break; + case LLViewerObject::LL_VO_VOID_WATER: + case LLViewerObject::LL_VO_WATER: + gGL.diffuseColor4f(0,0.5f,1,1); // medium blue + break; + case LL_PCODE_LEGACY_TREE: + gGL.diffuseColor4f(0,0.5f,0,1); // dark green + break; + default: + LLControlAvatar *cav = dynamic_cast(drawable->getVObj()->asAvatar()); + if (cav) + { + bool has_pos_constraint = (cav->mPositionConstraintFixup != LLVector3()); + bool has_scale_constraint = (cav->mScaleConstraintFixup != 1.0f); + if (has_pos_constraint || has_scale_constraint) + { + gGL.diffuseColor4f(1,0,0,1); + } + else + { + gGL.diffuseColor4f(0,1,0.5,1); + } + } + else + { + gGL.diffuseColor4f(1,0,1,1); // magenta + } + break; + } + } + else + { + gGL.diffuseColor4f(1,0,0,1); + } + } + + const LLVector4a* ext; + LLVector4a pos, size; + + if (drawable->getVOVolume()) + { + //render face bounding boxes + for (S32 i = 0; i < drawable->getNumFaces(); i++) + { + LLFace* facep = drawable->getFace(i); + if (facep) + { + ext = facep->mExtents; + + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + + drawBoxOutline(pos,size); + } + } + } + + //render drawable bounding box + ext = drawable->getSpatialExtents(); + + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + + LLViewerObject* vobj = drawable->getVObj(); + if (vobj && vobj->onActiveList()) + { + gGL.flush(); + glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f)); + //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f)); + stop_glerror(); + drawBoxOutline(pos,size); + gGL.flush(); + glLineWidth(1.f); + } + else + { + drawBoxOutline(pos,size); + } +} +// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different +// code path which uses a shader - it was tested to be faster than mapping a +// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well +// to simplify and speed up this debug code. Alternatively, a compute shader is +// likely faster. -Cosmic,2023-09-28 +void renderNormals(LLDrawable *drawablep) +{ + if (!drawablep->isVisible()) + return; + + LLVertexBuffer::unbind(); + + LLViewerObject* obj = drawablep->getVObj(); + LLVOVolume *vol = drawablep->getVOVolume(); + + if (obj) + { + LLGLEnable blend(GL_BLEND); + LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE); + + // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied. + // + // SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't + // work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose + // transform. We get that effect here by pre-applying the inverse scale (twice, because + // one forward scale will be re-applied via the MVP in the vertex shader) + + LLVector4a inv_scale; + float scale_len; + if (vol) + { + LLVector3 scale_v3 = vol->getScale(); + LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]); + obj_scale.normalize3(); + + // Create inverse-scale vector for normals + inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0); + inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice + + inv_scale.normalize3fast(); + scale_len = scale_v3.length(); + } + else + { + inv_scale.set(1.0, 1.0, 1.0, 0.0); + scale_len = 1.0; + } + + gGL.pushMatrix(); + if (vol) { gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix); } @@ -2052,7 +2052,7 @@ void renderNormals(LLDrawable *drawablep) float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len; std::vector* faces = nullptr; - std::vector* drawable_faces = nullptr; + std::vector* drawable_faces = nullptr; if (vol) { LLVolume* volume = vol->getVolume(); @@ -2060,67 +2060,67 @@ void renderNormals(LLDrawable *drawablep) } else { - drawable_faces = &drawablep->getFaces(); + drawable_faces = &drawablep->getFaces(); } - if (faces) - { - for (auto it = faces->begin(); it != faces->end(); ++it) - { - const LLVolumeFace& face = *it; - - gGL.flush(); - gGL.diffuseColor4f(1, 1, 0, 1); - gGL.begin(LLRender::LINES); - for (S32 j = 0; j < face.mNumVertices; ++j) - { - LLVector4a n, p; - - n.setMul(face.mNormals[j], 1.0); - n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP - n.normalize3fast(); - n.mul(draw_length); - p.setAdd(face.mPositions[j], n); - - gGL.vertex3fv(face.mPositions[j].getF32ptr()); - gGL.vertex3fv(p.getF32ptr()); - } - gGL.end(); - - // Tangents are simple vectors and do not require reorientation via pre-scaling - if (face.mTangents) - { - gGL.flush(); - gGL.diffuseColor4f(0, 1, 1, 1); - gGL.begin(LLRender::LINES); - for (S32 j = 0; j < face.mNumVertices; ++j) - { - LLVector4a t, p; - - t.setMul(face.mTangents[j], 1.0f); - t.normalize3fast(); - t.mul(draw_length); - p.setAdd(face.mPositions[j], t); - - gGL.vertex3fv(face.mPositions[j].getF32ptr()); - gGL.vertex3fv(p.getF32ptr()); - } - gGL.end(); - } - } - } - else if (drawable_faces) - { - // *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present - llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram); - LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr; + if (faces) + { + for (auto it = faces->begin(); it != faces->end(); ++it) + { + const LLVolumeFace& face = *it; + + gGL.flush(); + gGL.diffuseColor4f(1, 1, 0, 1); + gGL.begin(LLRender::LINES); + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a n, p; + + n.setMul(face.mNormals[j], 1.0); + n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP + n.normalize3fast(); + n.mul(draw_length); + p.setAdd(face.mPositions[j], n); + + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + } + gGL.end(); + + // Tangents are simple vectors and do not require reorientation via pre-scaling + if (face.mTangents) + { + gGL.flush(); + gGL.diffuseColor4f(0, 1, 1, 1); + gGL.begin(LLRender::LINES); + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a t, p; + + t.setMul(face.mTangents[j], 1.0f); + t.normalize3fast(); + t.mul(draw_length); + p.setAdd(face.mPositions[j], t); + + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + } + gGL.end(); + } + } + } + else if (drawable_faces) + { + // *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present + llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram); + LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr; for (auto it = drawable_faces->begin(); it != drawable_faces->end(); ++it) { LLFace* facep = *it; LLFace& face = **it; LLVertexBuffer* buf = face.getVertexBuffer(); if (!buf) { continue; } - U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL; + U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL; if ((buf->getTypeMask() & mask_vn) != mask_vn) { continue; } LLGLSLShader* shader; @@ -2143,11 +2143,11 @@ void renderNormals(LLDrawable *drawablep) // *NOTE: For terrain normal debug, this seems to also include vertices for water, which is technically not part of the terrain. Should fix that at some point. buf->drawRange(LLRender::TRIANGLES, face.getGeomIndex(), face.getGeomIndex() + face.getGeomCount()-1, face.getIndicesCount(), face.getIndicesStart()); } - if (prev_shader) - { - prev_shader->bind(); - } - } + if (prev_shader) + { + prev_shader->bind(); + } + } gGL.popMatrix(); } @@ -2155,278 +2155,278 @@ void renderNormals(LLDrawable *drawablep) S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale) { - const S32 DEFAULT_DETAIL = 1; - const F32 LARGE_THRESHOLD = 5.f; - const F32 MEGA_THRESHOLD = 25.f; + const S32 DEFAULT_DETAIL = 1; + const F32 LARGE_THRESHOLD = 5.f; + const F32 MEGA_THRESHOLD = 25.f; - S32 detail = DEFAULT_DETAIL; - F32 avg_scale = (scale[0]+scale[1]+scale[2])/3.f; + S32 detail = DEFAULT_DETAIL; + F32 avg_scale = (scale[0]+scale[1]+scale[2])/3.f; - if (avg_scale > LARGE_THRESHOLD) - { - detail += 1; - if (avg_scale > MEGA_THRESHOLD) - { - detail += 1; - } - } + if (avg_scale > LARGE_THRESHOLD) + { + detail += 1; + if (avg_scale > MEGA_THRESHOLD) + { + detail += 1; + } + } - return detail; + return detail; } void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color) { - LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); - LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); + LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); - const LLVector3 center(0,0,0); - const LLVector3 size(0.25f,0.25f,0.25f); + const LLVector3 center(0,0,0); + const LLVector3 size(0.25f,0.25f,0.25f); - if (decomp) - { - if (!decomp->mBaseHullMesh.empty()) - { + if (decomp) + { + if (!decomp->mBaseHullMesh.empty()) + { gGL.diffuseColor4fv(color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions); - } - else - { - gMeshRepo.buildPhysicsMesh(*decomp); - gGL.diffuseColor4f(0,1,1,1); - drawBoxOutline(center, size); - } - - } - else - { - gGL.diffuseColor3f(1,0,1); - drawBoxOutline(center, size); - } + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions); + } + else + { + gMeshRepo.buildPhysicsMesh(*decomp); + gGL.diffuseColor4f(0,1,1,1); + drawBoxOutline(center, size); + } + + } + else + { + gGL.diffuseColor3f(1,0,1); + drawBoxOutline(center, size); + } } void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color) { gGL.diffuseColor4fv(color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions); } void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe) { - U8 physics_type = volume->getPhysicsShapeType(); + U8 physics_type = volume->getPhysicsShapeType(); - if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible()) - { - return; - } + if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible()) + { + return; + } - //not allowed to return at this point without rendering *something* + //not allowed to return at this point without rendering *something* - F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold"); - F32 cost = volume->getObjectCost(); + F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold"); + F32 cost = volume->getObjectCost(); - LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor"); - LLColor4 mid = gSavedSettings.getColor4("ObjectCostMidColor"); - LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor"); + LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor"); + LLColor4 mid = gSavedSettings.getColor4("ObjectCostMidColor"); + LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor"); - F32 normalizedCost = 1.f - exp( -(cost / threshold) ); + F32 normalizedCost = 1.f - exp( -(cost / threshold) ); - LLColor4 color; - if ( normalizedCost <= 0.5f ) - { - color = lerp( low, mid, 2.f * normalizedCost ); - } - else - { - color = lerp( mid, high, 2.f * ( normalizedCost - 0.5f ) ); - } + LLColor4 color; + if ( normalizedCost <= 0.5f ) + { + color = lerp( low, mid, 2.f * normalizedCost ); + } + else + { + color = lerp( mid, high, 2.f * ( normalizedCost - 0.5f ) ); + } if (wireframe) { color = color * 0.5f; } - U32 data_mask = LLVertexBuffer::MAP_VERTEX; + U32 data_mask = LLVertexBuffer::MAP_VERTEX; + + LLVolumeParams volume_params = volume->getVolume()->getParams(); - LLVolumeParams volume_params = volume->getVolume()->getParams(); + LLPhysicsVolumeParams physics_params(volume_params, + physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); - LLPhysicsVolumeParams physics_params(volume_params, - physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec; + LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec); - LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec; - LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec); + U32 type = physics_spec.getType(); - U32 type = physics_spec.getType(); + LLVector3 center(0,0,0); + LLVector3 size(0.25f,0.25f,0.25f); - LLVector3 center(0,0,0); - LLVector3 size(0.25f,0.25f,0.25f); + gGL.pushMatrix(); + gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); - gGL.pushMatrix(); - gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); - - if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) - { - LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); - LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); - - if (decomp) - { //render a physics based mesh - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) + { + LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); + LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + + if (decomp) + { //render a physics based mesh - if (!decomp->mHull.empty()) - { //decomposition exists, use that + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (decomp->mMesh.empty()) - { - gMeshRepo.buildPhysicsMesh(*decomp); - } + if (!decomp->mHull.empty()) + { //decomposition exists, use that + + if (decomp->mMesh.empty()) + { + gMeshRepo.buildPhysicsMesh(*decomp); + } - for (U32 i = 0; i < decomp->mMesh.size(); ++i) - { - render_hull(decomp->mMesh[i], color); - } - } - else if (!decomp->mPhysicsShapeMesh.empty()) - { - //decomp has physics mesh, render that mesh + for (U32 i = 0; i < decomp->mMesh.size(); ++i) + { + render_hull(decomp->mMesh[i], color); + } + } + else if (!decomp->mPhysicsShapeMesh.empty()) + { + //decomp has physics mesh, render that mesh gGL.diffuseColor4fv(color.mV); LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions); - } - else - { //no mesh or decomposition, render base hull - renderMeshBaseHull(volume, data_mask, color); - - if (decomp->mPhysicsShapeMesh.empty()) - { - //attempt to fetch physics shape mesh if available - gMeshRepo.fetchPhysicsShape(mesh_id); - } - } - } - else - { - gGL.diffuseColor3f(1,1,0); - drawBoxOutline(center, size); - } - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_CONVEX || - type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX) - { - if (volume->isMesh()) - { - renderMeshBaseHull(volume, data_mask, color); - } - else - { - LLVolumeParams volume_params = volume->getVolume()->getParams(); - S32 detail = get_physics_detail(volume_params, volume->getScale()); - LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); - - if (!phys_volume->mHullPoints) - { //build convex hull - std::vector pos; - std::vector index; - - S32 index_offset = 0; - - for (S32 i = 0; i < phys_volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = phys_volume->getVolumeFace(i); - if (index_offset + face.mNumVertices > 65535) - { - continue; - } - - for (S32 j = 0; j < face.mNumVertices; ++j) - { - pos.push_back(LLVector3(face.mPositions[j].getF32ptr())); - } - - for (S32 j = 0; j < face.mNumIndices; ++j) - { - index.push_back(face.mIndices[j]+index_offset); - } - - index_offset += face.mNumVertices; - } - - if (!pos.empty() && !index.empty()) - { - LLCDMeshData mesh; - mesh.mIndexBase = &index[0]; - mesh.mVertexBase = pos[0].mV; - mesh.mNumVertices = pos.size(); - mesh.mVertexStrideBytes = 12; - mesh.mIndexStrideBytes = 6; - mesh.mIndexType = LLCDMeshData::INT_16; - - mesh.mNumTriangles = index.size()/3; - - LLCDMeshData res; - - LLConvexDecomposition::getInstance()->generateSingleHullMeshFromMesh( &mesh, &res ); - - //copy res into phys_volume - phys_volume->mHullPoints = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*res.mNumVertices); - phys_volume->mNumHullPoints = res.mNumVertices; - - S32 idx_size = (res.mNumTriangles*3*2+0xF) & ~0xF; - phys_volume->mHullIndices = (U16*) ll_aligned_malloc_16(idx_size); - phys_volume->mNumHullIndices = res.mNumTriangles*3; - - const F32* v = res.mVertexBase; - - for (S32 i = 0; i < res.mNumVertices; ++i) - { - F32* p = (F32*) ((U8*)v+i*res.mVertexStrideBytes); - phys_volume->mHullPoints[i].load3(p); - } - - if (res.mIndexType == LLCDMeshData::INT_16) - { - for (S32 i = 0; i < res.mNumTriangles; ++i) - { - U16* idx = (U16*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes); - - phys_volume->mHullIndices[i*3+0] = idx[0]; - phys_volume->mHullIndices[i*3+1] = idx[1]; - phys_volume->mHullIndices[i*3+2] = idx[2]; - } - } - else - { - for (S32 i = 0; i < res.mNumTriangles; ++i) - { - U32* idx = (U32*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes); - - phys_volume->mHullIndices[i*3+0] = (U16) idx[0]; - phys_volume->mHullIndices[i*3+1] = (U16) idx[1]; - phys_volume->mHullIndices[i*3+2] = (U16) idx[2]; - } - } - } - } - - if (phys_volume->mHullPoints) - { - //render hull + } + else + { //no mesh or decomposition, render base hull + renderMeshBaseHull(volume, data_mask, color); + + if (decomp->mPhysicsShapeMesh.empty()) + { + //attempt to fetch physics shape mesh if available + gMeshRepo.fetchPhysicsShape(mesh_id); + } + } + } + else + { + gGL.diffuseColor3f(1,1,0); + drawBoxOutline(center, size); + } + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_CONVEX || + type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX) + { + if (volume->isMesh()) + { + renderMeshBaseHull(volume, data_mask, color); + } + else + { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + S32 detail = get_physics_detail(volume_params, volume->getScale()); + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + + if (!phys_volume->mHullPoints) + { //build convex hull + std::vector pos; + std::vector index; + + S32 index_offset = 0; + + for (S32 i = 0; i < phys_volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = phys_volume->getVolumeFace(i); + if (index_offset + face.mNumVertices > 65535) + { + continue; + } + + for (S32 j = 0; j < face.mNumVertices; ++j) + { + pos.push_back(LLVector3(face.mPositions[j].getF32ptr())); + } + + for (S32 j = 0; j < face.mNumIndices; ++j) + { + index.push_back(face.mIndices[j]+index_offset); + } + + index_offset += face.mNumVertices; + } + + if (!pos.empty() && !index.empty()) + { + LLCDMeshData mesh; + mesh.mIndexBase = &index[0]; + mesh.mVertexBase = pos[0].mV; + mesh.mNumVertices = pos.size(); + mesh.mVertexStrideBytes = 12; + mesh.mIndexStrideBytes = 6; + mesh.mIndexType = LLCDMeshData::INT_16; + + mesh.mNumTriangles = index.size()/3; + + LLCDMeshData res; + + LLConvexDecomposition::getInstance()->generateSingleHullMeshFromMesh( &mesh, &res ); + + //copy res into phys_volume + phys_volume->mHullPoints = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*res.mNumVertices); + phys_volume->mNumHullPoints = res.mNumVertices; + + S32 idx_size = (res.mNumTriangles*3*2+0xF) & ~0xF; + phys_volume->mHullIndices = (U16*) ll_aligned_malloc_16(idx_size); + phys_volume->mNumHullIndices = res.mNumTriangles*3; + + const F32* v = res.mVertexBase; + + for (S32 i = 0; i < res.mNumVertices; ++i) + { + F32* p = (F32*) ((U8*)v+i*res.mVertexStrideBytes); + phys_volume->mHullPoints[i].load3(p); + } + + if (res.mIndexType == LLCDMeshData::INT_16) + { + for (S32 i = 0; i < res.mNumTriangles; ++i) + { + U16* idx = (U16*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes); + + phys_volume->mHullIndices[i*3+0] = idx[0]; + phys_volume->mHullIndices[i*3+1] = idx[1]; + phys_volume->mHullIndices[i*3+2] = idx[2]; + } + } + else + { + for (S32 i = 0; i < res.mNumTriangles; ++i) + { + U32* idx = (U32*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes); + + phys_volume->mHullIndices[i*3+0] = (U16) idx[0]; + phys_volume->mHullIndices[i*3+1] = (U16) idx[1]; + phys_volume->mHullIndices[i*3+2] = (U16) idx[2]; + } + } + } + } + + if (phys_volume->mHullPoints) + { + //render hull gGL.diffuseColor4fv(color.mV); LLVertexBuffer::unbind(); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); - } - else - { - gGL.diffuseColor4f(1,0,1,1); - drawBoxOutline(center, size); - } - - LLPrimitive::sVolumeManager->unrefVolume(phys_volume); - } - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX) - { + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + } + else + { + gGL.diffuseColor4f(1,0,1,1); + drawBoxOutline(center, size); + } + + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); + } + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX) + { if (!wireframe) { LLVector3 center = physics_spec.getCenter(); @@ -2437,9 +2437,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe gGL.diffuseColor4fv(color.mV); drawBox(center, scale); } - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE) - { + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE) + { if (!wireframe) { LLVolumeParams volume_params; @@ -2454,9 +2454,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe pushVerts(sphere); LLPrimitive::sVolumeManager->unrefVolume(sphere); } - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER) - { + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER) + { if (!wireframe) { LLVolumeParams volume_params; @@ -2471,244 +2471,244 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe pushVerts(cylinder); LLPrimitive::sVolumeManager->unrefVolume(cylinder); } - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH) - { - LLVolumeParams volume_params = volume->getVolume()->getParams(); - S32 detail = get_physics_detail(volume_params, volume->getScale()); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH) + { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + S32 detail = get_physics_detail(volume_params, volume->getScale()); - LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); gGL.diffuseColor4fv(color.mV); - pushVerts(phys_volume); + pushVerts(phys_volume); + + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX) + { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + S32 detail = get_physics_detail(volume_params, volume->getScale()); - LLPrimitive::sVolumeManager->unrefVolume(phys_volume); - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX) - { - LLVolumeParams volume_params = volume->getVolume()->getParams(); - S32 detail = get_physics_detail(volume_params, volume->getScale()); + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); - LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + if (phys_volume->mHullPoints && phys_volume->mHullIndices) + { - if (phys_volume->mHullPoints && phys_volume->mHullIndices) - { - - llassert(LLGLSLShader::sCurBoundShader != 0); - LLVertexBuffer::unbind(); - glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); + llassert(LLGLSLShader::sCurBoundShader != 0); + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); gGL.diffuseColor4fv(color.mV); gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); - } - else - { - gGL.diffuseColor3f(1,0,1); - drawBoxOutline(center, size); - gMeshRepo.buildHull(volume_params, detail); - } - LLPrimitive::sVolumeManager->unrefVolume(phys_volume); - } - else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SCULPT) - { - //TODO: implement sculpted prim physics display - } - else - { - LL_ERRS() << "Unhandled type" << LL_ENDL; - } - - gGL.popMatrix(); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } + else + { + gGL.diffuseColor3f(1,0,1); + drawBoxOutline(center, size); + gMeshRepo.buildHull(volume_params, detail); + } + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SCULPT) + { + //TODO: implement sculpted prim physics display + } + else + { + LL_ERRS() << "Unhandled type" << LL_ENDL; + } + + gGL.popMatrix(); } void renderPhysicsShapes(LLSpatialGroup* group, bool wireframe) { - for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - - if (drawable->isSpatialBridge()) - { - LLSpatialBridge* bridge = drawable->asPartition()->asBridge(); - - if (bridge) - { - gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - bridge->renderPhysicsShapes(wireframe); - gGL.popMatrix(); - } - } - else - { - LLVOVolume* volume = drawable->getVOVolume(); - if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) - { - if (!group->getSpatialPartition()->isBridge()) - { - gGL.pushMatrix(); - LLVector3 trans = drawable->getRegion()->getOriginAgent(); - gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - renderPhysicsShape(drawable, volume, wireframe); - gGL.popMatrix(); - } - else - { - renderPhysicsShape(drawable, volume, wireframe); - } - } - else - { -#if 0 - LLViewerObject* object = drawable->getVObj(); - if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) - { - gGL.pushMatrix(); - gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); - //push face vertices for terrain - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - if (face) - { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - buff->setBuffer(); - gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f); - buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); - - gGL.diffuseColor4f(0.2f, 1.f, 0.3f, 0.75f); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); - } - } - } - gGL.popMatrix(); - } + for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + + if (drawable->isSpatialBridge()) + { + LLSpatialBridge* bridge = drawable->asPartition()->asBridge(); + + if (bridge) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderPhysicsShapes(wireframe); + gGL.popMatrix(); + } + } + else + { + LLVOVolume* volume = drawable->getVOVolume(); + if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) + { + if (!group->getSpatialPartition()->isBridge()) + { + gGL.pushMatrix(); + LLVector3 trans = drawable->getRegion()->getOriginAgent(); + gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); + renderPhysicsShape(drawable, volume, wireframe); + gGL.popMatrix(); + } + else + { + renderPhysicsShape(drawable, volume, wireframe); + } + } + else + { +#if 0 + LLViewerObject* object = drawable->getVObj(); + if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); + //push face vertices for terrain + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + buff->setBuffer(); + gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f); + buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); + + gGL.diffuseColor4f(0.2f, 1.f, 0.3f, 0.75f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); + } + } + } + gGL.popMatrix(); + } #endif - } - } - } + } + } + } } void renderTexturePriority(LLDrawable* drawable) { - for (int face=0; facegetNumFaces(); ++face) - { - LLFace *facep = drawable->getFace(face); - - LLVector4 cold(0,0,0.25f); - LLVector4 hot(1,0.25f,0.25f); - - LLVector4 boost_cold(0,0,0,0); - LLVector4 boost_hot(0,1,0,1); - - LLGLDisable blend(GL_BLEND); - - //LLViewerTexture* imagep = facep->getTexture(); - //if (imagep) - if (facep) - { - - //F32 vsize = imagep->mMaxVirtualSize; - F32 vsize = facep->getPixelArea(); - - if (vsize > sCurMaxTexPriority) - { - sCurMaxTexPriority = vsize; - } - - F32 t = vsize/sLastMaxTexPriority; - - LLVector4 col = lerp(cold, hot, t); - gGL.diffuseColor4fv(col.mV); - } - //else - //{ - // gGL.diffuseColor4f(1,0,1,1); - //} - - LLVector4a center; - center.setAdd(facep->mExtents[1],facep->mExtents[0]); - center.mul(0.5f); - LLVector4a size; - size.setSub(facep->mExtents[1],facep->mExtents[0]); - size.mul(0.5f); - size.add(LLVector4a(0.01f)); - drawBox(center, size); - - /*S32 boost = imagep->getBoostLevel(); - if (boost>LLGLTexture::BOOST_NONE) - { - F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1); - LLVector4 col = lerp(boost_cold, boost_hot, t); - LLGLEnable blend_on(GL_BLEND); - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); - gGL.diffuseColor4fv(col.mV); - drawBox(center, size); - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - }*/ - } + for (int face=0; facegetNumFaces(); ++face) + { + LLFace *facep = drawable->getFace(face); + + LLVector4 cold(0,0,0.25f); + LLVector4 hot(1,0.25f,0.25f); + + LLVector4 boost_cold(0,0,0,0); + LLVector4 boost_hot(0,1,0,1); + + LLGLDisable blend(GL_BLEND); + + //LLViewerTexture* imagep = facep->getTexture(); + //if (imagep) + if (facep) + { + + //F32 vsize = imagep->mMaxVirtualSize; + F32 vsize = facep->getPixelArea(); + + if (vsize > sCurMaxTexPriority) + { + sCurMaxTexPriority = vsize; + } + + F32 t = vsize/sLastMaxTexPriority; + + LLVector4 col = lerp(cold, hot, t); + gGL.diffuseColor4fv(col.mV); + } + //else + //{ + // gGL.diffuseColor4f(1,0,1,1); + //} + + LLVector4a center; + center.setAdd(facep->mExtents[1],facep->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(facep->mExtents[1],facep->mExtents[0]); + size.mul(0.5f); + size.add(LLVector4a(0.01f)); + drawBox(center, size); + + /*S32 boost = imagep->getBoostLevel(); + if (boost>LLGLTexture::BOOST_NONE) + { + F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1); + LLVector4 col = lerp(boost_cold, boost_hot, t); + LLGLEnable blend_on(GL_BLEND); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.diffuseColor4fv(col.mV); + drawBox(center, size); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + }*/ + } } void renderPoints(LLDrawable* drawablep) { - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - if (drawablep->getNumFaces()) - { - gGL.begin(LLRender::POINTS); - gGL.diffuseColor3f(1,1,1); - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace * face = drawablep->getFace(i); - if (face) - { - gGL.vertex3fv(face->mCenterLocal.mV); - } - } - gGL.end(); - } + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + if (drawablep->getNumFaces()) + { + gGL.begin(LLRender::POINTS); + gGL.diffuseColor3f(1,1,1); + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + LLFace * face = drawablep->getFace(i); + if (face) + { + gGL.vertex3fv(face->mCenterLocal.mV); + } + } + gGL.end(); + } } void renderTextureAnim(LLDrawInfo* params) { - if (!params->mTextureMatrix) - { - return; - } - - LLGLEnable blend(GL_BLEND); - gGL.diffuseColor4f(1,1,0,0.5f); - pushVerts(params); + if (!params->mTextureMatrix) + { + return; + } + + LLGLEnable blend(GL_BLEND); + gGL.diffuseColor4f(1,1,0,0.5f); + pushVerts(params); } void renderBatchSize(LLDrawInfo* params) { - LLGLEnable offset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.f, 1.f); + LLGLEnable offset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.f, 1.f); LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr; bool bind = false; if (params->mAvatar) - { + { gGL.pushMatrix(); gGL.loadMatrix(gGLModelView); bind = true; old_shader->mRiggedVariant->bind(); LLRenderPass::uploadMatrixPalette(*params); } - - + + gGL.diffuseColor4ubv(params->getDebugColor().mV); - pushVerts(params); + pushVerts(params); if (bind) { @@ -2719,220 +2719,220 @@ void renderBatchSize(LLDrawInfo* params) void renderTexelDensity(LLDrawable* drawable) { - if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF - || LLViewerTexture::sCheckerBoardImagep.isNull()) - { - return; - } - - LLGLEnable _(GL_BLEND); - - LLMatrix4 checkerboard_matrix; - S32 discard_level = -1; - - for (S32 f = 0; f < drawable->getNumFaces(); f++) - { - LLFace* facep = drawable->getFace(f); - LLVertexBuffer* buffer = facep->getVertexBuffer(); - LLViewerTexture* texturep = facep->getTexture(); - - if (texturep == NULL) continue; - - switch(LLViewerTexture::sDebugTexelsMode) - { - case LLViewerTexture::DEBUG_TEXELS_CURRENT: - discard_level = -1; - break; - case LLViewerTexture::DEBUG_TEXELS_DESIRED: - { - LLViewerFetchedTexture* fetched_texturep = dynamic_cast(texturep); - discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; - break; - } - default: - case LLViewerTexture::DEBUG_TEXELS_FULL: - discard_level = 0; - break; - } - - checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); - - gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix); - - if (buffer && (facep->getGeomCount() >= 3)) - { - buffer->setBuffer(); - U16 start = facep->getGeomStart(); - U16 end = start + facep->getGeomCount()-1; - U32 count = facep->getIndicesCount(); - U16 offset = facep->getIndicesStart(); - buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); - } - - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - - //S32 num_textures = llmax(1, (S32)params->mTextureList.size()); - - //for (S32 i = 0; i < num_textures; i++) - //{ - // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get(); - // if (texturep == NULL) continue; - - // LLMatrix4 checkboard_matrix; - // S32 discard_level = -1; - // switch(LLViewerTexture::sDebugTexelsMode) - // { - // case LLViewerTexture::DEBUG_TEXELS_CURRENT: - // discard_level = -1; - // break; - // case LLViewerTexture::DEBUG_TEXELS_DESIRED: - // { - // LLViewerFetchedTexture* fetched_texturep = dynamic_cast(texturep); - // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; - // break; - // } - // default: - // case LLViewerTexture::DEBUG_TEXELS_FULL: - // discard_level = 0; - // break; - // } - - // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); - // gGL.getTexUnit(i)->activate(); - - // glMatrixMode(GL_TEXTURE); - // glPushMatrix(); - // glLoadIdentity(); - // //gGL.matrixMode(LLRender::MM_TEXTURE); - // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix); - - // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); - - // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); - - // glPopMatrix(); - // glMatrixMode(GL_MODELVIEW); - // //gGL.matrixMode(LLRender::MM_MODELVIEW); - //} + if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF + || LLViewerTexture::sCheckerBoardImagep.isNull()) + { + return; + } + + LLGLEnable _(GL_BLEND); + + LLMatrix4 checkerboard_matrix; + S32 discard_level = -1; + + for (S32 f = 0; f < drawable->getNumFaces(); f++) + { + LLFace* facep = drawable->getFace(f); + LLVertexBuffer* buffer = facep->getVertexBuffer(); + LLViewerTexture* texturep = facep->getTexture(); + + if (texturep == NULL) continue; + + switch(LLViewerTexture::sDebugTexelsMode) + { + case LLViewerTexture::DEBUG_TEXELS_CURRENT: + discard_level = -1; + break; + case LLViewerTexture::DEBUG_TEXELS_DESIRED: + { + LLViewerFetchedTexture* fetched_texturep = dynamic_cast(texturep); + discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + break; + } + default: + case LLViewerTexture::DEBUG_TEXELS_FULL: + discard_level = 0; + break; + } + + checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + + gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix); + + if (buffer && (facep->getGeomCount() >= 3)) + { + buffer->setBuffer(); + U16 start = facep->getGeomStart(); + U16 end = start + facep->getGeomCount()-1; + U32 count = facep->getIndicesCount(); + U16 offset = facep->getIndicesStart(); + buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + } + + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + + //S32 num_textures = llmax(1, (S32)params->mTextureList.size()); + + //for (S32 i = 0; i < num_textures; i++) + //{ + // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get(); + // if (texturep == NULL) continue; + + // LLMatrix4 checkboard_matrix; + // S32 discard_level = -1; + // switch(LLViewerTexture::sDebugTexelsMode) + // { + // case LLViewerTexture::DEBUG_TEXELS_CURRENT: + // discard_level = -1; + // break; + // case LLViewerTexture::DEBUG_TEXELS_DESIRED: + // { + // LLViewerFetchedTexture* fetched_texturep = dynamic_cast(texturep); + // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + // break; + // } + // default: + // case LLViewerTexture::DEBUG_TEXELS_FULL: + // discard_level = 0; + // break; + // } + + // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + // gGL.getTexUnit(i)->activate(); + + // glMatrixMode(GL_TEXTURE); + // glPushMatrix(); + // glLoadIdentity(); + // //gGL.matrixMode(LLRender::MM_TEXTURE); + // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix); + + // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + + // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); + + // glPopMatrix(); + // glMatrixMode(GL_MODELVIEW); + // //gGL.matrixMode(LLRender::MM_MODELVIEW); + //} } void renderLights(LLDrawable* drawablep) { - if (!drawablep->isLight()) - { - return; - } - - if (drawablep->getNumFaces()) - { - LLGLEnable blend(GL_BLEND); - gGL.diffuseColor4f(0,1,1,0.5f); - - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace * face = drawablep->getFace(i); - if (face) - { - pushVerts(face); - } - } - - const LLVector4a* ext = drawablep->getSpatialExtents(); - - LLVector4a pos; - pos.setAdd(ext[0], ext[1]); - pos.mul(0.5f); - LLVector4a size; - size.setSub(ext[1], ext[0]); - size.mul(0.5f); - - { - LLGLDepthTest depth(GL_FALSE, GL_TRUE); - gGL.diffuseColor4f(1,1,1,1); - drawBoxOutline(pos, size); - } - - gGL.diffuseColor4f(1,1,0,1); - F32 rad = drawablep->getVOVolume()->getLightRadius(); - drawBoxOutline(pos, LLVector4a(rad)); - } + if (!drawablep->isLight()) + { + return; + } + + if (drawablep->getNumFaces()) + { + LLGLEnable blend(GL_BLEND); + gGL.diffuseColor4f(0,1,1,0.5f); + + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + LLFace * face = drawablep->getFace(i); + if (face) + { + pushVerts(face); + } + } + + const LLVector4a* ext = drawablep->getSpatialExtents(); + + LLVector4a pos; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + + { + LLGLDepthTest depth(GL_FALSE, GL_TRUE); + gGL.diffuseColor4f(1,1,1,1); + drawBoxOutline(pos, size); + } + + gGL.diffuseColor4f(1,1,0,1); + F32 rad = drawablep->getVOVolume()->getLightRadius(); + drawBoxOutline(pos, LLVector4a(rad)); + } } class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect { public: - LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t) - : LLOctreeTriangleRayIntersect(start, dir, nullptr, closest_t, NULL, NULL, NULL, NULL) - { + LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t) + : LLOctreeTriangleRayIntersect(start, dir, nullptr, closest_t, NULL, NULL, NULL, NULL) + { - } + } void visit(const LLOctreeNode* branch) - { - LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); - - LLVector3 center, size; - - if (branch->isEmpty()) - { - gGL.diffuseColor3f(1.f,0.2f,0.f); - center.set(branch->getCenter().getF32ptr()); - size.set(branch->getSize().getF32ptr()); - } - else - { - gGL.diffuseColor3f(0.75f, 1.f, 0.f); - center.set(vl->mBounds[0].getF32ptr()); - size.set(vl->mBounds[1].getF32ptr()); - } - - drawBoxOutline(center, size); - - for (U32 i = 0; i < 2; i++) - { - LLGLDepthTest depth(GL_TRUE, GL_FALSE, i == 1 ? GL_LEQUAL : GL_GREATER); - - if (i == 1) - { - gGL.diffuseColor4f(0,1,1,0.5f); - } - else - { - gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f); - drawBoxOutline(center, size); - } - - if (i == 1) - { - gGL.flush(); - glLineWidth(3.f); - } - - gGL.begin(LLRender::TRIANGLES); + { + LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); + + LLVector3 center, size; + + if (branch->isEmpty()) + { + gGL.diffuseColor3f(1.f,0.2f,0.f); + center.set(branch->getCenter().getF32ptr()); + size.set(branch->getSize().getF32ptr()); + } + else + { + gGL.diffuseColor3f(0.75f, 1.f, 0.f); + center.set(vl->mBounds[0].getF32ptr()); + size.set(vl->mBounds[1].getF32ptr()); + } + + drawBoxOutline(center, size); + + for (U32 i = 0; i < 2; i++) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE, i == 1 ? GL_LEQUAL : GL_GREATER); + + if (i == 1) + { + gGL.diffuseColor4f(0,1,1,0.5f); + } + else + { + gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f); + drawBoxOutline(center, size); + } + + if (i == 1) + { + gGL.flush(); + glLineWidth(3.f); + } + + gGL.begin(LLRender::TRIANGLES); for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); - iter != branch->getDataEnd(); - ++iter) - { - const LLVolumeTriangle* tri = *iter; - - gGL.vertex3fv(tri->mV[0]->getF32ptr()); - gGL.vertex3fv(tri->mV[1]->getF32ptr()); - gGL.vertex3fv(tri->mV[2]->getF32ptr()); - } - gGL.end(); - - if (i == 1) - { - gGL.flush(); - glLineWidth(1.f); - } - } - } + iter != branch->getDataEnd(); + ++iter) + { + const LLVolumeTriangle* tri = *iter; + + gGL.vertex3fv(tri->mV[0]->getF32ptr()); + gGL.vertex3fv(tri->mV[1]->getF32ptr()); + gGL.vertex3fv(tri->mV[2]->getF32ptr()); + } + gGL.end(); + + if (i == 1) + { + gGL.flush(); + glLineWidth(1.f); + } + } + } }; void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree) @@ -2944,161 +2944,161 @@ void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const L void renderRaycast(LLDrawable* drawablep) { - if (drawablep->getNumFaces()) - { - LLGLEnable blend(GL_BLEND); - gGL.diffuseColor4f(0,1,1,0.5f); - - LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj && !vobj->isDead()) - { - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - //pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX); - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - LLVolume* volume = vobj->getVolume(); - - bool transform = true; - if (drawablep->isState(LLDrawable::RIGGED)) - { - volume = vobj->getRiggedVolume(); - transform = false; - } - - if (volume) - { - LLVector3 trans = drawablep->getRegion()->getOriginAgent(); - - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - - gGL.pushMatrix(); - gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); - - LLVector4a start, end; - if (transform) - { - LLVector3 v_start(gDebugRaycastStart.getF32ptr()); - LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); - - v_start = vobj->agentPositionToVolume(v_start); - v_end = vobj->agentPositionToVolume(v_end); - - start.load3(v_start.mV); - end.load3(v_end.mV); - } - else - { - start = gDebugRaycastStart; - end = gDebugRaycastEnd; - } - - LLVector4a dir; - dir.setSub(end, start); - - gGL.flush(); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - { - //render face positions - //gGL.diffuseColor4f(0,1,1,0.5f); + if (drawablep->getNumFaces()) + { + LLGLEnable blend(GL_BLEND); + gGL.diffuseColor4f(0,1,1,0.5f); + + LLVOVolume* vobj = drawablep->getVOVolume(); + if (vobj && !vobj->isDead()) + { + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + //pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX); + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + LLVolume* volume = vobj->getVolume(); + + bool transform = true; + if (drawablep->isState(LLDrawable::RIGGED)) + { + volume = vobj->getRiggedVolume(); + transform = false; + } + + if (volume) + { + LLVector3 trans = drawablep->getRegion()->getOriginAgent(); + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + + gGL.pushMatrix(); + gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); + gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + + LLVector4a start, end; + if (transform) + { + LLVector3 v_start(gDebugRaycastStart.getF32ptr()); + LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); + + v_start = vobj->agentPositionToVolume(v_start); + v_end = vobj->agentPositionToVolume(v_end); + + start.load3(v_start.mV); + end.load3(v_end.mV); + } + else + { + start = gDebugRaycastStart; + end = gDebugRaycastEnd; + } + + LLVector4a dir; + dir.setSub(end, start); + + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + { + //render face positions + //gGL.diffuseColor4f(0,1,1,0.5f); //LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, nullptr, face.mNumIndices, face.mIndices); - } - - if (!volume->isUnique()) - { + } + + if (!volume->isUnique()) + { if (!face.getOctree()) - { - ((LLVolumeFace*) &face)->createOctree(); - } + { + ((LLVolumeFace*) &face)->createOctree(); + } renderOctreeRaycast(start, end, face.getOctree()); - } - - gGL.popMatrix(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - } - } - else if (drawablep->isAvatar()) - { - if (drawablep->getVObj() == gDebugRaycastObject) - { - LLGLDepthTest depth(GL_FALSE); - LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get(); - av->renderCollisionVolumes(); - } - } - - if (drawablep->getVObj() == gDebugRaycastObject) - { - // draw intersection point - gGL.pushMatrix(); - gGL.loadMatrix(gGLModelView); - LLVector3 translate(gDebugRaycastIntersection.getF32ptr()); - gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]); - LLCoordFrame orient; - LLVector4a debug_binormal; - - debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); - debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); - - LLVector3 normal(gDebugRaycastNormal.getF32ptr()); - LLVector3 binormal(debug_binormal.getF32ptr()); - - orient.lookDir(normal, binormal); - LLMatrix4 rotation; - orient.getRotMatrixToParent(rotation); - gGL.multMatrix((float*)rotation.mMatrix); - - gGL.diffuseColor4f(1,0,0,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); - gGL.diffuseColor4f(0,1,0,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f)); - gGL.diffuseColor4f(0,0,1,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f)); - gGL.popMatrix(); - - // draw bounding box of prim - const LLVector4a* ext = drawablep->getSpatialExtents(); - - LLVector4a pos; - pos.setAdd(ext[0], ext[1]); - pos.mul(0.5f); - LLVector4a size; - size.setSub(ext[1], ext[0]); - size.mul(0.5f); - - LLGLDepthTest depth(GL_FALSE, GL_TRUE); - gGL.diffuseColor4f(0,0.5f,0.5f,1); - drawBoxOutline(pos, size); - } - } + } + + gGL.popMatrix(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } + } + else if (drawablep->isAvatar()) + { + if (drawablep->getVObj() == gDebugRaycastObject) + { + LLGLDepthTest depth(GL_FALSE); + LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get(); + av->renderCollisionVolumes(); + } + } + + if (drawablep->getVObj() == gDebugRaycastObject) + { + // draw intersection point + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + LLVector3 translate(gDebugRaycastIntersection.getF32ptr()); + gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]); + LLCoordFrame orient; + LLVector4a debug_binormal; + + debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); + debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); + + LLVector3 normal(gDebugRaycastNormal.getF32ptr()); + LLVector3 binormal(debug_binormal.getF32ptr()); + + orient.lookDir(normal, binormal); + LLMatrix4 rotation; + orient.getRotMatrixToParent(rotation); + gGL.multMatrix((float*)rotation.mMatrix); + + gGL.diffuseColor4f(1,0,0,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); + gGL.diffuseColor4f(0,1,0,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f)); + gGL.diffuseColor4f(0,0,1,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f)); + gGL.popMatrix(); + + // draw bounding box of prim + const LLVector4a* ext = drawablep->getSpatialExtents(); + + LLVector4a pos; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + + LLGLDepthTest depth(GL_FALSE, GL_TRUE); + gGL.diffuseColor4f(0,0.5f,0.5f,1); + drawBoxOutline(pos, size); + } + } } void renderAvatarCollisionVolumes(LLVOAvatar* avatar) { - avatar->renderCollisionVolumes(); + avatar->renderCollisionVolumes(); } void renderAvatarBones(LLVOAvatar* avatar) { - avatar->renderBones(); + avatar->renderBones(); } void renderAgentTarget(LLVOAvatar* avatar) { - // render these for self only (why, i don't know) - if (avatar->isSelf()) - { - renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); - renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f)); - renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); - renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f)); - } + // render these for self only (why, i don't know) + if (avatar->isSelf()) + { + renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); + renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f)); + renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); + renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f)); + } } static void setTextureAreaDebugText(LLDrawable* drawablep) @@ -3140,686 +3140,686 @@ static void setTextureAreaDebugText(LLDrawable* drawablep) { str << llformat("\nS - %.2f", sqrtf(imagep->getMaxVirtualSize())); } - - str << "\n\n"; + + str << "\n\n"; + } + + vobjp->setDebugText(str.str()); + } + } + } + else + { + vobjp->setDebugText("."); + } + } +} + +class LLOctreeRenderNonOccluded : public OctreeTraveler +{ +public: + LLCamera* mCamera; + LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} + + virtual void traverse(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) + { + node->accept(this); + stop_glerror(); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + stop_glerror(); + } + + //draw tight fit bounding boxes for spatial group + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) + { + group->rebuildGeom(); + group->rebuildMesh(); + + renderOctree(group); + stop_glerror(); + } + } + } + + virtual void visit(const OctreeNode* branch) + { + LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) + { + return; + } + + group->rebuildGeom(); + group->rebuildMesh(); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + if (!group->isEmpty()) + { + gGL.diffuseColor3f(0,0,1); + const LLVector4a* obj_bounds = group->getObjectBounds(); + drawBoxOutline(obj_bounds[0], obj_bounds[1]); + } + } + + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable || drawable->isDead()) + { + continue; + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + renderBoundingBox(drawable); + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS)) + { + renderNormals(drawable); + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setTextureAreaDebugText(drawable); + } + + /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + renderTexturePriority(drawable); + }*/ + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) + { + renderPoints(drawable); + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS)) + { + renderLights(drawable); + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) + { + renderRaycast(drawable); + } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE)) + { + renderUpdateType(drawable); + } + if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + renderTexelDensity(drawable); + } + + LLVOAvatar* avatar = dynamic_cast(drawable->getVObj().get()); + + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) + { + renderAvatarCollisionVolumes(avatar); + } + + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS)) + { + renderAvatarBones(avatar); + } + + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) + { + renderAgentTarget(avatar); + } + +#if 0 + if (gDebugGL) + { + for (U32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* facep = drawable->getFace(i); + if (facep) + { + U8 index = facep->getTextureIndex(); + if (facep->mDrawInfo) + { + if (index < FACE_DO_NOT_BATCH_TEXTURES) + { + if (facep->mDrawInfo->mTextureList.size() <= index) + { + LL_ERRS() << "Face texture index out of bounds." << LL_ENDL; + } + else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) + { + LL_ERRS() << "Face texture index incorrect." << LL_ENDL; + } + } + } } - - vobjp->setDebugText(str.str()); } } +#endif } - else + + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) { - vobjp->setDebugText("."); + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* draw_info = *j; + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)) + { + renderTextureAnim(draw_info); + } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE)) + { + renderBatchSize(draw_info); + } + } } } -} +}; -class LLOctreeRenderNonOccluded : public OctreeTraveler +class LLOctreeRenderXRay : public OctreeTraveler { public: - LLCamera* mCamera; - LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} - - virtual void traverse(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - const LLVector4a* bounds = group->getBounds(); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) - { - node->accept(this); - stop_glerror(); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - stop_glerror(); - } - - //draw tight fit bounding boxes for spatial group - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) - { - group->rebuildGeom(); - group->rebuildMesh(); - - renderOctree(group); - stop_glerror(); - } - } - } - - virtual void visit(const OctreeNode* branch) - { - LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - const LLVector4a* bounds = group->getBounds(); - if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) - { - return; - } - - group->rebuildGeom(); - group->rebuildMesh(); - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) - { - if (!group->isEmpty()) - { - gGL.diffuseColor3f(0,0,1); - const LLVector4a* obj_bounds = group->getObjectBounds(); - drawBoxOutline(obj_bounds[0], obj_bounds[1]); - } - } - - for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable || drawable->isDead()) - { - continue; - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) - { - renderBoundingBox(drawable); - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS)) - { - renderNormals(drawable); - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + LLCamera* mCamera; + LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {} + + virtual void traverse(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) + { + node->accept(this); + stop_glerror(); + + for (U32 i = 0; i < node->getChildCount(); i++) { - setTextureAreaDebugText(drawable); + traverse(node->getChild(i)); + stop_glerror(); } - /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - renderTexturePriority(drawable); - }*/ - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) - { - renderPoints(drawable); - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS)) - { - renderLights(drawable); - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) - { - renderRaycast(drawable); - } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE)) - { - renderUpdateType(drawable); - } - if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) - { - renderTexelDensity(drawable); - } - - LLVOAvatar* avatar = dynamic_cast(drawable->getVObj().get()); - - if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) - { - renderAvatarCollisionVolumes(avatar); - } - - if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS)) - { - renderAvatarBones(avatar); - } - - if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) - { - renderAgentTarget(avatar); - } - -#if 0 - if (gDebugGL) - { - for (U32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* facep = drawable->getFace(i); - if (facep) - { - U8 index = facep->getTextureIndex(); - if (facep->mDrawInfo) - { - if (index < FACE_DO_NOT_BATCH_TEXTURES) - { - if (facep->mDrawInfo->mTextureList.size() <= index) - { - LL_ERRS() << "Face texture index out of bounds." << LL_ENDL; - } - else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) - { - LL_ERRS() << "Face texture index incorrect." << LL_ENDL; - } - } - } - } - } - } -#endif - } - - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; - for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) - { - LLDrawInfo* draw_info = *j; - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)) - { - renderTextureAnim(draw_info); - } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE)) - { - renderBatchSize(draw_info); - } - } - } - } -}; + //render visibility wireframe + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + group->rebuildGeom(); + group->rebuildMesh(); + + gGL.flush(); + gGL.pushMatrix(); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + renderXRay(group, mCamera); + stop_glerror(); + gGLLastMatrix = NULL; + gGL.popMatrix(); + } + } + } -class LLOctreeRenderXRay : public OctreeTraveler -{ -public: - LLCamera* mCamera; - LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {} - - virtual void traverse(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - const LLVector4a* bounds = group->getBounds(); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) - { - node->accept(this); - stop_glerror(); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - stop_glerror(); - } - - //render visibility wireframe - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) - { - group->rebuildGeom(); - group->rebuildMesh(); - - gGL.flush(); - gGL.pushMatrix(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - renderXRay(group, mCamera); - stop_glerror(); - gGLLastMatrix = NULL; - gGL.popMatrix(); - } - } - } - - virtual void visit(const OctreeNode* node) {} + virtual void visit(const OctreeNode* node) {} }; class LLOctreeRenderPhysicsShapes : public OctreeTraveler { public: - LLCamera* mCamera; + LLCamera* mCamera; bool mWireframe; - LLOctreeRenderPhysicsShapes(LLCamera* camera, bool wireframe): mCamera(camera), mWireframe(wireframe) {} - - virtual void traverse(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - const LLVector4a* bounds = group->getBounds(); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) - { - node->accept(this); - stop_glerror(); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - stop_glerror(); - } - - group->rebuildGeom(); - group->rebuildMesh(); - - renderPhysicsShapes(group, mWireframe); - } - } - - virtual void visit(const OctreeNode* branch) - { - - } + LLOctreeRenderPhysicsShapes(LLCamera* camera, bool wireframe): mCamera(camera), mWireframe(wireframe) {} + + virtual void traverse(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) + { + node->accept(this); + stop_glerror(); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + stop_glerror(); + } + + group->rebuildGeom(); + group->rebuildMesh(); + + renderPhysicsShapes(group, mWireframe); + } + } + + virtual void visit(const OctreeNode* branch) + { + + } }; class LLOctreePushBBoxVerts : public OctreeTraveler { public: - LLCamera* mCamera; - LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} - - virtual void traverse(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - const LLVector4a* bounds = group->getBounds(); - if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1])) - { - node->accept(this); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - } - } - } - - virtual void visit(const OctreeNode* branch) - { - LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - const LLVector4a* bounds = group->getBounds(); - if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) - { - return; - } - - for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - renderBoundingBox(drawable, FALSE); - } - } + LLCamera* mCamera; + LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} + + virtual void traverse(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1])) + { + node->accept(this); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + } + } + + virtual void visit(const OctreeNode* branch) + { + LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); + + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) + { + return; + } + + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + renderBoundingBox(drawable, FALSE); + } + } }; void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) { - LLOctreePushBBoxVerts pusher(camera); - pusher.traverse(mOctree); + LLOctreePushBBoxVerts pusher(camera); + pusher.traverse(mOctree); } class LLOctreeStateCheck : public OctreeTraveler { public: - U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; - - LLOctreeStateCheck() - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mInheritedMask[i] = 0; - } - } - - virtual void traverse(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - node->accept(this); - - - U32 temp[LLViewerCamera::NUM_CAMERAS]; - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - temp[i] = mInheritedMask[i]; - mInheritedMask[i] |= group->mOcclusionState[i] & LLSpatialGroup::OCCLUDED; - } - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - } - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mInheritedMask[i] = temp[i]; - } - } - - - virtual void visit(const OctreeNode* state) - { - LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i])) - { - LL_ERRS() << "Spatial group failed inherited mask test." << LL_ENDL; - } - } - - if (group->hasState(LLSpatialGroup::DIRTY)) - { - assert_parent_state(group, LLSpatialGroup::DIRTY); - } - } - - void assert_parent_state(LLSpatialGroup* group, U32 state) - { - LLSpatialGroup* parent = group->getParent(); - while (parent) - { - if (!parent->hasState(state)) - { - LL_ERRS() << "Spatial group failed parent state check." << LL_ENDL; - } - parent = parent->getParent(); - } - } + U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; + + LLOctreeStateCheck() + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mInheritedMask[i] = 0; + } + } + + virtual void traverse(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + node->accept(this); + + + U32 temp[LLViewerCamera::NUM_CAMERAS]; + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + temp[i] = mInheritedMask[i]; + mInheritedMask[i] |= group->mOcclusionState[i] & LLSpatialGroup::OCCLUDED; + } + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mInheritedMask[i] = temp[i]; + } + } + + + virtual void visit(const OctreeNode* state) + { + LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i])) + { + LL_ERRS() << "Spatial group failed inherited mask test." << LL_ENDL; + } + } + + if (group->hasState(LLSpatialGroup::DIRTY)) + { + assert_parent_state(group, LLSpatialGroup::DIRTY); + } + } + + void assert_parent_state(LLSpatialGroup* group, U32 state) + { + LLSpatialGroup* parent = group->getParent(); + while (parent) + { + if (!parent->hasState(state)) + { + LL_ERRS() << "Spatial group failed parent state check." << LL_ENDL; + } + parent = parent->getParent(); + } + } }; void LLSpatialPartition::renderPhysicsShapes(bool wireframe) { - LLSpatialBridge* bridge = asBridge(); - LLCamera* camera = LLViewerCamera::getInstance(); - - if (bridge) - { - camera = NULL; - } - - gGL.flush(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLOctreeRenderPhysicsShapes render_physics(camera, wireframe); - render_physics.traverse(mOctree); - gGL.flush(); + LLSpatialBridge* bridge = asBridge(); + LLCamera* camera = LLViewerCamera::getInstance(); + + if (bridge) + { + camera = NULL; + } + + gGL.flush(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLOctreeRenderPhysicsShapes render_physics(camera, wireframe); + render_physics.traverse(mOctree); + gGL.flush(); } void LLSpatialPartition::renderDebug() { - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | - LLPipeline::RENDER_DEBUG_OCCLUSION | - LLPipeline::RENDER_DEBUG_LIGHTS | - LLPipeline::RENDER_DEBUG_BATCH_SIZE | - LLPipeline::RENDER_DEBUG_UPDATE_TYPE | - LLPipeline::RENDER_DEBUG_BBOXES | - LLPipeline::RENDER_DEBUG_NORMALS | - LLPipeline::RENDER_DEBUG_POINTS | + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | + LLPipeline::RENDER_DEBUG_OCCLUSION | + LLPipeline::RENDER_DEBUG_LIGHTS | + LLPipeline::RENDER_DEBUG_BATCH_SIZE | + LLPipeline::RENDER_DEBUG_UPDATE_TYPE | + LLPipeline::RENDER_DEBUG_BBOXES | + LLPipeline::RENDER_DEBUG_NORMALS | + LLPipeline::RENDER_DEBUG_POINTS | LLPipeline::RENDER_DEBUG_TEXTURE_AREA | - LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | - LLPipeline::RENDER_DEBUG_RAYCAST | - LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | - LLPipeline::RENDER_DEBUG_AVATAR_JOINTS | - LLPipeline::RENDER_DEBUG_AGENT_TARGET | - LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | - LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) - { - return; - } - - gDebugProgram.bind(); - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); - sLastMaxTexPriority = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); - sCurMaxTexPriority = 0.f; - } - - LLGLDisable cullface(GL_CULL_FACE); - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gPipeline.disableLights(); - - LLSpatialBridge* bridge = asBridge(); - LLCamera* camera = LLViewerCamera::getInstance(); - - if (bridge) - { - camera = NULL; - } - - LLOctreeStateCheck checker; - checker.traverse(mOctree); - - LLOctreeRenderNonOccluded render_debug(camera); - render_debug.traverse(mOctree); - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) - { - { - LLGLEnable cull(GL_CULL_FACE); - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f); - - LLGLEnable offset(GL_POLYGON_OFFSET_LINE); - glPolygonOffset(-1.f, -1.f); - - LLOctreeRenderXRay xray(camera); - xray.traverse(mOctree); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - } - gDebugProgram.unbind(); + LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | + LLPipeline::RENDER_DEBUG_RAYCAST | + LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | + LLPipeline::RENDER_DEBUG_AVATAR_JOINTS | + LLPipeline::RENDER_DEBUG_AGENT_TARGET | + LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | + LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + return; + } + + gDebugProgram.bind(); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); + sLastMaxTexPriority = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); + sCurMaxTexPriority = 0.f; + } + + LLGLDisable cullface(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gPipeline.disableLights(); + + LLSpatialBridge* bridge = asBridge(); + LLCamera* camera = LLViewerCamera::getInstance(); + + if (bridge) + { + camera = NULL; + } + + LLOctreeStateCheck checker; + checker.traverse(mOctree); + + LLOctreeRenderNonOccluded render_debug(camera); + render_debug.traverse(mOctree); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + { + LLGLEnable cull(GL_CULL_FACE); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f); + + LLGLEnable offset(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-1.f, -1.f); + + LLOctreeRenderXRay xray(camera); + xray.traverse(mOctree); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } + gDebugProgram.unbind(); } void LLSpatialGroup::drawObjectBox(LLColor4 col) { - gGL.diffuseColor4fv(col.mV); - LLVector4a size; - size = mObjectBounds[1]; - size.mul(1.01f); - size.add(LLVector4a(0.001f)); - drawBox(mObjectBounds[0], size); + gGL.diffuseColor4fv(col.mV); + LLVector4a size; + size = mObjectBounds[1]; + size.mul(1.01f); + size.add(LLVector4a(0.001f)); + drawBox(mObjectBounds[0], size); } -bool LLSpatialPartition::isHUDPartition() -{ - return mPartitionType == LLViewerRegion::PARTITION_HUD ; -} +bool LLSpatialPartition::isHUDPartition() +{ + return mPartitionType == LLViewerRegion::PARTITION_HUD ; +} BOOL LLSpatialPartition::isVisible(const LLVector3& v) { - if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f)) - { - return FALSE; - } + if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f)) + { + return FALSE; + } - return TRUE; + return TRUE; } LL_ALIGN_PREFIX(16) class LLOctreeIntersect : public LLOctreeTraveler> { public: - LL_ALIGN_16(LLVector4a mStart); - LL_ALIGN_16(LLVector4a mEnd); - - S32 *mFaceHit; - LLVector4a *mIntersection; - LLVector2 *mTexCoord; - LLVector4a *mNormal; - LLVector4a *mTangent; - LLDrawable* mHit; - BOOL mPickTransparent; - BOOL mPickRigged; + LL_ALIGN_16(LLVector4a mStart); + LL_ALIGN_16(LLVector4a mEnd); + + S32 *mFaceHit; + LLVector4a *mIntersection; + LLVector2 *mTexCoord; + LLVector4a *mNormal; + LLVector4a *mTangent; + LLDrawable* mHit; + BOOL mPickTransparent; + BOOL mPickRigged; BOOL mPickUnselectable; BOOL mPickReflectionProbe; - LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe, - S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) - : mStart(start), - mEnd(end), - mFaceHit(face_hit), - mIntersection(intersection), - mTexCoord(tex_coord), - mNormal(normal), - mTangent(tangent), - mHit(NULL), - mPickTransparent(pick_transparent), - mPickRigged(pick_rigged), + LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe, + S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + : mStart(start), + mEnd(end), + mFaceHit(face_hit), + mIntersection(intersection), + mTexCoord(tex_coord), + mNormal(normal), + mTangent(tangent), + mHit(NULL), + mPickTransparent(pick_transparent), + mPickRigged(pick_rigged), mPickUnselectable(pick_unselectable), mPickReflectionProbe(pick_reflection_probe) - { - } - - virtual void visit(const OctreeNode* branch) - { - for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) - { - check(*i); - } - } - - virtual LLDrawable* check(const OctreeNode* node) - { - node->accept(this); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - const OctreeNode* child = node->getChild(i); - LLVector3 res; - - LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); - - LLVector4a size; - LLVector4a center; - - const LLVector4a* bounds = group->getBounds(); - size = bounds[1]; - center = bounds[0]; - - LLVector4a local_start = mStart; - LLVector4a local_end = mEnd; - - if (group->getSpatialPartition()->isBridge()) - { - LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix(); - local_matrix.invert(); - - LLMatrix4a local_matrix4a; - local_matrix4a.loadu(local_matrix); - - local_matrix4a.affineTransform(mStart, local_start); - local_matrix4a.affineTransform(mEnd, local_end); - } - - if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) - { - check(child); - } - } - - return mHit; - } - - virtual bool check(LLViewerOctreeEntry* entry) - { - LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); - - if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible()) - { - return false; - } - - if (drawable->isSpatialBridge()) - { - LLSpatialPartition *part = drawable->asPartition(); - LLSpatialBridge* bridge = part->asBridge(); - if (bridge && gPipeline.hasRenderType(bridge->mDrawableType)) - { - check(part->mOctree); - } - } - else - { - LLViewerObject* vobj = drawable->getVObj(); + { + } + + virtual void visit(const OctreeNode* branch) + { + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + { + check(*i); + } + } + + virtual LLDrawable* check(const OctreeNode* node) + { + node->accept(this); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + const OctreeNode* child = node->getChild(i); + LLVector3 res; + + LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); + + LLVector4a size; + LLVector4a center; + + const LLVector4a* bounds = group->getBounds(); + size = bounds[1]; + center = bounds[0]; + + LLVector4a local_start = mStart; + LLVector4a local_end = mEnd; + + if (group->getSpatialPartition()->isBridge()) + { + LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix(); + local_matrix.invert(); + + LLMatrix4a local_matrix4a; + local_matrix4a.loadu(local_matrix); + + local_matrix4a.affineTransform(mStart, local_start); + local_matrix4a.affineTransform(mEnd, local_end); + } + + if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) + { + check(child); + } + } + + return mHit; + } + + virtual bool check(LLViewerOctreeEntry* entry) + { + LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); + + if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible()) + { + return false; + } + + if (drawable->isSpatialBridge()) + { + LLSpatialPartition *part = drawable->asPartition(); + LLSpatialBridge* bridge = part->asBridge(); + if (bridge && gPipeline.hasRenderType(bridge->mDrawableType)) + { + check(part->mOctree); + } + } + else + { + LLViewerObject* vobj = drawable->getVObj(); if (vobj && (!vobj->isReflectionProbe() || mPickReflectionProbe)) - { - if (vobj->getClickAction() == CLICK_ACTION_IGNORE && !LLFloater::isVisible(gFloaterTools)) - { - return false; - } - - LLVector4a intersection; - bool skip_check = false; - if (vobj->isAvatar()) - { - LLVOAvatar* avatar = (LLVOAvatar*) vobj; - if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) - { - LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent); - if (hit) - { - mEnd = intersection; - if (mIntersection) - { - *mIntersection = intersection; - } - - mHit = hit->mDrawable; - skip_check = true; - } - - } - } - - if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, + { + if (vobj->getClickAction() == CLICK_ACTION_IGNORE && !LLFloater::isVisible(gFloaterTools)) + { + return false; + } + + LLVector4a intersection; + bool skip_check = false; + if (vobj->isAvatar()) + { + LLVOAvatar* avatar = (LLVOAvatar*) vobj; + if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) + { + LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent); + if (hit) + { + mEnd = intersection; + if (mIntersection) + { + *mIntersection = intersection; + } + + mHit = hit->mDrawable; + skip_check = true; + } + + } + } + + if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, (mPickReflectionProbe && vobj->isReflectionProbe()) ? TRUE : mPickTransparent, // always pick transparent when picking selection probe mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent)) - { - mEnd = intersection; // shorten ray so we only find CLOSER hits - if (mIntersection) - { - *mIntersection = intersection; - } - - mHit = vobj->mDrawable; - } - } - } - - return false; - } + { + mEnd = intersection; // shorten ray so we only find CLOSER hits + if (mIntersection) + { + *mIntersection = intersection; + } + + mHit = vobj->mDrawable; + } + } + } + + return false; + } } LL_ALIGN_POSTFIX(16); LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - BOOL pick_transparent, - BOOL pick_rigged, + BOOL pick_transparent, + BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe, - S32* face_hit, // return the face hit - LLVector4a* intersection, // return the intersection point - LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point - ) + S32* face_hit, // return the face hit + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point + ) { - LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent); - LLDrawable* drawable = intersect.check(mOctree); + LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent); + LLDrawable* drawable = intersect.check(mOctree); - return drawable; + return drawable; } LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, @@ -3831,7 +3831,7 @@ LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point ) { @@ -3841,32 +3841,32 @@ LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const return drawable; } -LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerTexture* texture, LLVertexBuffer* buffer, - bool fullbright, U8 bump) -: mVertexBuffer(buffer), - mTexture(texture), - mStart(start), - mEnd(end), - mCount(count), - mOffset(offset), - mFullbright(fullbright), - mBump(bump), - mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA), - mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA), - mHasGlow(false), - mEnvIntensity(0.0f), - mAlphaMaskCutoff(0.5f) -{ - mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); +LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, + LLViewerTexture* texture, LLVertexBuffer* buffer, + bool fullbright, U8 bump) +: mVertexBuffer(buffer), + mTexture(texture), + mStart(start), + mEnd(end), + mCount(count), + mOffset(offset), + mFullbright(fullbright), + mBump(bump), + mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA), + mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA), + mHasGlow(false), + mEnvIntensity(0.0f), + mAlphaMaskCutoff(0.5f) +{ + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); } -LLDrawInfo::~LLDrawInfo() +LLDrawInfo::~LLDrawInfo() { - if (gDebugGL) - { - gPipeline.checkReferences(this); - } + if (gDebugGL) + { + gPipeline.checkReferences(this); + } } LLColor4U LLDrawInfo::getDebugColor() const @@ -3879,13 +3879,13 @@ LLColor4U LLDrawInfo::getDebugColor() const *((U32*) color.mV) = hash.getCRC(); color.mV[3] = 200; - + return color; } void LLDrawInfo::validate() { - mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); } U64 LLDrawInfo::getSkinHash() @@ -3893,110 +3893,110 @@ U64 LLDrawInfo::getSkinHash() return mSkinInfo ? mSkinInfo->mHash : 0; } -LLCullResult::LLCullResult() +LLCullResult::LLCullResult() { - mVisibleGroupsAllocated = 0; - mAlphaGroupsAllocated = 0; + mVisibleGroupsAllocated = 0; + mAlphaGroupsAllocated = 0; mRiggedAlphaGroupsAllocated = 0; - mOcclusionGroupsAllocated = 0; - mDrawableGroupsAllocated = 0; - mVisibleListAllocated = 0; - mVisibleBridgeAllocated = 0; - - mVisibleGroups.clear(); - mVisibleGroups.push_back(NULL); - mVisibleGroupsEnd = &mVisibleGroups[0]; - mAlphaGroups.clear(); - mAlphaGroups.push_back(NULL); - mAlphaGroupsEnd = &mAlphaGroups[0]; + mOcclusionGroupsAllocated = 0; + mDrawableGroupsAllocated = 0; + mVisibleListAllocated = 0; + mVisibleBridgeAllocated = 0; + + mVisibleGroups.clear(); + mVisibleGroups.push_back(NULL); + mVisibleGroupsEnd = &mVisibleGroups[0]; + mAlphaGroups.clear(); + mAlphaGroups.push_back(NULL); + mAlphaGroupsEnd = &mAlphaGroups[0]; mRiggedAlphaGroups.clear(); mRiggedAlphaGroups.push_back(NULL); mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0]; - mOcclusionGroups.clear(); - mOcclusionGroups.push_back(NULL); - mOcclusionGroupsEnd = &mOcclusionGroups[0]; - mDrawableGroups.clear(); - mDrawableGroups.push_back(NULL); - mDrawableGroupsEnd = &mDrawableGroups[0]; - mVisibleList.clear(); - mVisibleList.push_back(NULL); - mVisibleListEnd = &mVisibleList[0]; - mVisibleBridge.clear(); - mVisibleBridge.push_back(NULL); - mVisibleBridgeEnd = &mVisibleBridge[0]; - - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) - { - mRenderMap[i].clear(); - mRenderMap[i].push_back(NULL); - mRenderMapEnd[i] = &mRenderMap[i][0]; - mRenderMapAllocated[i] = 0; - } - - clear(); + mOcclusionGroups.clear(); + mOcclusionGroups.push_back(NULL); + mOcclusionGroupsEnd = &mOcclusionGroups[0]; + mDrawableGroups.clear(); + mDrawableGroups.push_back(NULL); + mDrawableGroupsEnd = &mDrawableGroups[0]; + mVisibleList.clear(); + mVisibleList.push_back(NULL); + mVisibleListEnd = &mVisibleList[0]; + mVisibleBridge.clear(); + mVisibleBridge.push_back(NULL); + mVisibleBridgeEnd = &mVisibleBridge[0]; + + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + mRenderMap[i].clear(); + mRenderMap[i].push_back(NULL); + mRenderMapEnd[i] = &mRenderMap[i][0]; + mRenderMapAllocated[i] = 0; + } + + clear(); } -template +template void LLCullResult::pushBack(T& head, U32& count, V* val) { - head[count] = val; - head.push_back(NULL); - count++; + head[count] = val; + head.push_back(NULL); + count++; } void LLCullResult::clear() { - mVisibleGroupsSize = 0; - mVisibleGroupsEnd = &mVisibleGroups[0]; + mVisibleGroupsSize = 0; + mVisibleGroupsEnd = &mVisibleGroups[0]; - mAlphaGroupsSize = 0; - mAlphaGroupsEnd = &mAlphaGroups[0]; + mAlphaGroupsSize = 0; + mAlphaGroupsEnd = &mAlphaGroups[0]; mRiggedAlphaGroupsSize = 0; mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0]; - mOcclusionGroupsSize = 0; - mOcclusionGroupsEnd = &mOcclusionGroups[0]; + mOcclusionGroupsSize = 0; + mOcclusionGroupsEnd = &mOcclusionGroups[0]; - mDrawableGroupsSize = 0; - mDrawableGroupsEnd = &mDrawableGroups[0]; + mDrawableGroupsSize = 0; + mDrawableGroupsEnd = &mDrawableGroups[0]; - mVisibleListSize = 0; - mVisibleListEnd = &mVisibleList[0]; + mVisibleListSize = 0; + mVisibleListEnd = &mVisibleList[0]; - mVisibleBridgeSize = 0; - mVisibleBridgeEnd = &mVisibleBridge[0]; + mVisibleBridgeSize = 0; + mVisibleBridgeEnd = &mVisibleBridge[0]; - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) - { - for (U32 j = 0; j < mRenderMapSize[i]; j++) - { - mRenderMap[i][j] = 0; - } - mRenderMapSize[i] = 0; - mRenderMapEnd[i] = &(mRenderMap[i][0]); - } + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + for (U32 j = 0; j < mRenderMapSize[i]; j++) + { + mRenderMap[i][j] = 0; + } + mRenderMapSize[i] = 0; + mRenderMapEnd[i] = &(mRenderMap[i][0]); + } } LLCullResult::sg_iterator LLCullResult::beginVisibleGroups() { - return &mVisibleGroups[0]; + return &mVisibleGroups[0]; } LLCullResult::sg_iterator LLCullResult::endVisibleGroups() { - return mVisibleGroupsEnd; + return mVisibleGroupsEnd; } LLCullResult::sg_iterator LLCullResult::beginAlphaGroups() { - return &mAlphaGroups[0]; + return &mAlphaGroups[0]; } LLCullResult::sg_iterator LLCullResult::endAlphaGroups() { - return mAlphaGroupsEnd; + return mAlphaGroupsEnd; } LLCullResult::sg_iterator LLCullResult::beginRiggedAlphaGroups() @@ -4011,80 +4011,80 @@ LLCullResult::sg_iterator LLCullResult::endRiggedAlphaGroups() LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() { - return &mOcclusionGroups[0]; + return &mOcclusionGroups[0]; } LLCullResult::sg_iterator LLCullResult::endOcclusionGroups() { - return mOcclusionGroupsEnd; + return mOcclusionGroupsEnd; } LLCullResult::sg_iterator LLCullResult::beginDrawableGroups() { - return &mDrawableGroups[0]; + return &mDrawableGroups[0]; } LLCullResult::sg_iterator LLCullResult::endDrawableGroups() { - return mDrawableGroupsEnd; + return mDrawableGroupsEnd; } LLCullResult::drawable_iterator LLCullResult::beginVisibleList() { - return &mVisibleList[0]; + return &mVisibleList[0]; } LLCullResult::drawable_iterator LLCullResult::endVisibleList() { - return mVisibleListEnd; + return mVisibleListEnd; } LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge() { - return &mVisibleBridge[0]; + return &mVisibleBridge[0]; } LLCullResult::bridge_iterator LLCullResult::endVisibleBridge() { - return mVisibleBridgeEnd; + return mVisibleBridgeEnd; } LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type) { - return &mRenderMap[type][0]; + return &mRenderMap[type][0]; } LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type) { - return mRenderMapEnd[type]; + return mRenderMapEnd[type]; } void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) { - if (mVisibleGroupsSize < mVisibleGroupsAllocated) - { - mVisibleGroups[mVisibleGroupsSize] = group; - } - else - { - pushBack(mVisibleGroups, mVisibleGroupsAllocated, group); - } - ++mVisibleGroupsSize; - mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize]; + if (mVisibleGroupsSize < mVisibleGroupsAllocated) + { + mVisibleGroups[mVisibleGroupsSize] = group; + } + else + { + pushBack(mVisibleGroups, mVisibleGroupsAllocated, group); + } + ++mVisibleGroupsSize; + mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize]; } void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) { - if (mAlphaGroupsSize < mAlphaGroupsAllocated) - { - mAlphaGroups[mAlphaGroupsSize] = group; - } - else - { - pushBack(mAlphaGroups, mAlphaGroupsAllocated, group); - } - ++mAlphaGroupsSize; - mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize]; + if (mAlphaGroupsSize < mAlphaGroupsAllocated) + { + mAlphaGroups[mAlphaGroupsSize] = group; + } + else + { + pushBack(mAlphaGroups, mAlphaGroupsAllocated, group); + } + ++mAlphaGroupsSize; + mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize]; } void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group) @@ -4103,16 +4103,16 @@ void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group) void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) { - if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) - { - mOcclusionGroups[mOcclusionGroupsSize] = group; - } - else - { - pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group); - } - ++mOcclusionGroupsSize; - mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize]; + if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) + { + mOcclusionGroups[mOcclusionGroupsSize] = group; + } + else + { + pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group); + } + ++mOcclusionGroupsSize; + mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize]; } void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) @@ -4121,16 +4121,16 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) // group must NOT be in the drawble groups list already llassert(std::find(&mDrawableGroups[0], mDrawableGroupsEnd, group) == mDrawableGroupsEnd); #endif - if (mDrawableGroupsSize < mDrawableGroupsAllocated) - { - mDrawableGroups[mDrawableGroupsSize] = group; - } - else - { - pushBack(mDrawableGroups, mDrawableGroupsAllocated, group); - } - ++mDrawableGroupsSize; - mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize]; + if (mDrawableGroupsSize < mDrawableGroupsAllocated) + { + mDrawableGroups[mDrawableGroupsSize] = group; + } + else + { + pushBack(mDrawableGroups, mDrawableGroupsAllocated, group); + } + ++mDrawableGroupsSize; + mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize]; } void LLCullResult::pushDrawable(LLDrawable* drawable) @@ -4139,56 +4139,56 @@ void LLCullResult::pushDrawable(LLDrawable* drawable) // drawable must NOT be in the visible list already llassert(std::find(&mVisibleList[0], mVisibleListEnd, drawable) == mVisibleListEnd); #endif - if (mVisibleListSize < mVisibleListAllocated) - { - mVisibleList[mVisibleListSize] = drawable; - } - else - { - pushBack(mVisibleList, mVisibleListAllocated, drawable); - } - ++mVisibleListSize; - mVisibleListEnd = &mVisibleList[mVisibleListSize]; + if (mVisibleListSize < mVisibleListAllocated) + { + mVisibleList[mVisibleListSize] = drawable; + } + else + { + pushBack(mVisibleList, mVisibleListAllocated, drawable); + } + ++mVisibleListSize; + mVisibleListEnd = &mVisibleList[mVisibleListSize]; } void LLCullResult::pushBridge(LLSpatialBridge* bridge) { - if (mVisibleBridgeSize < mVisibleBridgeAllocated) - { - mVisibleBridge[mVisibleBridgeSize] = bridge; - } - else - { - pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge); - } - ++mVisibleBridgeSize; - mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize]; + if (mVisibleBridgeSize < mVisibleBridgeAllocated) + { + mVisibleBridge[mVisibleBridgeSize] = bridge; + } + else + { + pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge); + } + ++mVisibleBridgeSize; + mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize]; } void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) { - if (mRenderMapSize[type] < mRenderMapAllocated[type]) - { - mRenderMap[type][mRenderMapSize[type]] = draw_info; - } - else - { - pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info); - } - ++mRenderMapSize[type]; - mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]); + if (mRenderMapSize[type] < mRenderMapAllocated[type]) + { + mRenderMap[type][mRenderMapSize[type]] = draw_info; + } + else + { + pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info); + } + ++mRenderMapSize[type]; + mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]); } void LLCullResult::assertDrawMapsEmpty() { - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) - { - if (mRenderMapSize[i] != 0) - { - LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!" - << " (mRenderMapSize[" << i << "] = " << mRenderMapSize[i] << ")" << LL_ENDL; - } - } + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + if (mRenderMapSize[i] != 0) + { + LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!" + << " (mRenderMapSize[" << i << "] = " << mRenderMapSize[i] << ")" << LL_ENDL; + } + } } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 804afe6266..55ecc7ccc5 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llsurface.cpp * @brief Implementation of LLSurface class * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -66,82 +66,82 @@ S32 LLSurface::sTextureSize = 256; // ---------------- LLSurface:: Public Members --------------- LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) : - mGridsPerEdge(0), - mOOGridsPerEdge(0.f), - mPatchesPerEdge(0), - mNumberOfPatches(0), - mType(type), - mDetailTextureScale(0.f), - mOriginGlobal(0.0, 0.0, 0.0), - mSTexturep(NULL), - mWaterTexturep(NULL), - mGridsPerPatchEdge(0), - mMetersPerGrid(1.0f), - mMetersPerEdge(1.0f), - mRegionp(regionp) + mGridsPerEdge(0), + mOOGridsPerEdge(0.f), + mPatchesPerEdge(0), + mNumberOfPatches(0), + mType(type), + mDetailTextureScale(0.f), + mOriginGlobal(0.0, 0.0, 0.0), + mSTexturep(NULL), + mWaterTexturep(NULL), + mGridsPerPatchEdge(0), + mMetersPerGrid(1.0f), + mMetersPerEdge(1.0f), + mRegionp(regionp) { - // Surface data - mSurfaceZ = NULL; - mNorm = NULL; + // Surface data + mSurfaceZ = NULL; + mNorm = NULL; - // Patch data - mPatchList = NULL; + // Patch data + mPatchList = NULL; - // One of each for each camera - mVisiblePatchCount = 0; + // One of each for each camera + mVisiblePatchCount = 0; - mHasZData = FALSE; - // "uninitialized" min/max z - mMinZ = 10000.f; - mMaxZ = -10000.f; + mHasZData = FALSE; + // "uninitialized" min/max z + mMinZ = 10000.f; + mMaxZ = -10000.f; - mWaterObjp = NULL; + mWaterObjp = NULL; - // In here temporarily. - mSurfacePatchUpdateCount = 0; + // In here temporarily. + mSurfacePatchUpdateCount = 0; - for (S32 i = 0; i < 8; i++) - { - mNeighbors[i] = NULL; - } + for (S32 i = 0; i < 8; i++) + { + mNeighbors[i] = NULL; + } } LLSurface::~LLSurface() { - delete [] mSurfaceZ; - mSurfaceZ = NULL; - - delete [] mNorm; - - mGridsPerEdge = 0; - mGridsPerPatchEdge = 0; - mPatchesPerEdge = 0; - mNumberOfPatches = 0; - destroyPatchData(); - - LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep); - if (!poolp) - { - LL_WARNS() << "No pool for terrain on destruction!" << LL_ENDL; - } - else if (poolp->mReferences.empty()) - { - gPipeline.removePool(poolp); - // Don't enable this until we blitz the draw pool for it as well. -- djs - if (mSTexturep) - { - mSTexturep = NULL; - } - if (mWaterTexturep) - { - mWaterTexturep = NULL; - } - } - else - { - LL_ERRS() << "Terrain pool not empty!" << LL_ENDL; - } + delete [] mSurfaceZ; + mSurfaceZ = NULL; + + delete [] mNorm; + + mGridsPerEdge = 0; + mGridsPerPatchEdge = 0; + mPatchesPerEdge = 0; + mNumberOfPatches = 0; + destroyPatchData(); + + LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep); + if (!poolp) + { + LL_WARNS() << "No pool for terrain on destruction!" << LL_ENDL; + } + else if (poolp->mReferences.empty()) + { + gPipeline.removePool(poolp); + // Don't enable this until we blitz the draw pool for it as well. -- djs + if (mSTexturep) + { + mSTexturep = NULL; + } + if (mWaterTexturep) + { + mWaterTexturep = NULL; + } + } + else + { + LL_ERRS() << "Terrain pool not empty!" << LL_ENDL; + } } void LLSurface::initClasses() @@ -150,538 +150,538 @@ void LLSurface::initClasses() void LLSurface::setRegion(LLViewerRegion *regionp) { - mRegionp = regionp; - mWaterObjp = NULL; // depends on regionp, needs recreating + mRegionp = regionp; + mWaterObjp = NULL; // depends on regionp, needs recreating } // Assumes that arguments are powers of 2, and that -// grids_per_edge / grids_per_patch_edge = power of 2 +// grids_per_edge / grids_per_patch_edge = power of 2 void LLSurface::create(const S32 grids_per_edge, - const S32 grids_per_patch_edge, - const LLVector3d &origin_global, - const F32 width) + const S32 grids_per_patch_edge, + const LLVector3d &origin_global, + const F32 width) { - // Initialize various constants for the surface - mGridsPerEdge = grids_per_edge + 1; // Add 1 for the east and north buffer - mOOGridsPerEdge = 1.f / mGridsPerEdge; - mGridsPerPatchEdge = grids_per_patch_edge; - mPatchesPerEdge = (mGridsPerEdge - 1) / mGridsPerPatchEdge; - mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge; - mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1)); - mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1); - - mOriginGlobal.setVec(origin_global); - - mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale()); - - S32 number_of_grids = mGridsPerEdge * mGridsPerEdge; - - ///////////////////////////////////// - // - // Initialize data arrays for surface - /// - mSurfaceZ = new F32[number_of_grids]; - mNorm = new LLVector3[number_of_grids]; - - // Reset the surface to be a flat square grid - for(S32 i=0; i < number_of_grids; i++) - { - // Surface is flat and zero - // Normals all point up - mSurfaceZ[i] = 0.0f; - mNorm[i].setVec(0.f, 0.f, 1.f); - } + // Initialize various constants for the surface + mGridsPerEdge = grids_per_edge + 1; // Add 1 for the east and north buffer + mOOGridsPerEdge = 1.f / mGridsPerEdge; + mGridsPerPatchEdge = grids_per_patch_edge; + mPatchesPerEdge = (mGridsPerEdge - 1) / mGridsPerPatchEdge; + mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge; + mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1)); + mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1); + + mOriginGlobal.setVec(origin_global); + + mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale()); + + S32 number_of_grids = mGridsPerEdge * mGridsPerEdge; + + ///////////////////////////////////// + // + // Initialize data arrays for surface + /// + mSurfaceZ = new F32[number_of_grids]; + mNorm = new LLVector3[number_of_grids]; + + // Reset the surface to be a flat square grid + for(S32 i=0; i < number_of_grids; i++) + { + // Surface is flat and zero + // Normals all point up + mSurfaceZ[i] = 0.0f; + mNorm[i].setVec(0.f, 0.f, 1.f); + } - mVisiblePatchCount = 0; + mVisiblePatchCount = 0; - /////////////////////// - // - // Initialize textures - // + /////////////////////// + // + // Initialize textures + // - initTextures(); + initTextures(); - // Has to be done after texture initialization - createPatchData(); + // Has to be done after texture initialization + createPatchData(); } LLViewerTexture* LLSurface::getSTexture() { - if (mSTexturep.notNull() && !mSTexturep->hasGLTexture()) - { - createSTexture(); - } - return mSTexturep; + if (mSTexturep.notNull() && !mSTexturep->hasGLTexture()) + { + createSTexture(); + } + return mSTexturep; } LLViewerTexture* LLSurface::getWaterTexture() { - if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture()) - { - createWaterTexture(); - } - return mWaterTexturep; + if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture()) + { + createWaterTexture(); + } + return mWaterTexturep; } void LLSurface::createSTexture() { - if (!mSTexturep) - { - // Fill with dummy gray data. - // GL NOT ACTIVE HERE - LLPointer raw = new LLImageRaw(sTextureSize, sTextureSize, 3); - U8 *default_texture = raw->getData(); - for (S32 i = 0; i < sTextureSize; i++) - { - for (S32 j = 0; j < sTextureSize; j++) - { - *(default_texture + (i*sTextureSize + j)*3) = 128; - *(default_texture + (i*sTextureSize + j)*3 + 1) = 128; - *(default_texture + (i*sTextureSize + j)*3 + 2) = 128; - } - } - - mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); - mSTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mSTexturep); - mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - } + if (!mSTexturep) + { + // Fill with dummy gray data. + // GL NOT ACTIVE HERE + LLPointer raw = new LLImageRaw(sTextureSize, sTextureSize, 3); + U8 *default_texture = raw->getData(); + for (S32 i = 0; i < sTextureSize; i++) + { + for (S32 j = 0; j < sTextureSize; j++) + { + *(default_texture + (i*sTextureSize + j)*3) = 128; + *(default_texture + (i*sTextureSize + j)*3 + 1) = 128; + *(default_texture + (i*sTextureSize + j)*3 + 2) = 128; + } + } + + mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + mSTexturep->dontDiscard(); + gGL.getTexUnit(0)->bind(mSTexturep); + mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + } } void LLSurface::createWaterTexture() { - if (!mWaterTexturep) - { - // Create the water texture - LLPointer raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4); - U8 *default_texture = raw->getData(); - for (S32 i = 0; i < sTextureSize/2; i++) - { - for (S32 j = 0; j < sTextureSize/2; j++) - { - *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; - } - } - - mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); - mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep); - mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - } + if (!mWaterTexturep) + { + // Create the water texture + LLPointer raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4); + U8 *default_texture = raw->getData(); + for (S32 i = 0; i < sTextureSize/2; i++) + { + for (S32 j = 0; j < sTextureSize/2; j++) + { + *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0]; + *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1]; + *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2]; + *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; + } + } + + mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + mWaterTexturep->dontDiscard(); + gGL.getTexUnit(0)->bind(mWaterTexturep); + mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + } } void LLSurface::initTextures() { - /////////////////////// - // - // Main surface texture - // - createSTexture(); - - /////////////////////// - // - // Water texture - // - if (gSavedSettings.getBOOL("RenderWater") ) - { - createWaterTexture(); - mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); - gPipeline.createObject(mWaterObjp); - LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); - water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet - mWaterObjp->setPositionGlobal(water_pos_global); - } + /////////////////////// + // + // Main surface texture + // + createSTexture(); + + /////////////////////// + // + // Water texture + // + if (gSavedSettings.getBOOL("RenderWater") ) + { + createWaterTexture(); + mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); + gPipeline.createObject(mWaterObjp); + LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); + water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet + mWaterObjp->setPositionGlobal(water_pos_global); + } } -void LLSurface::setOriginGlobal(const LLVector3d &origin_global) +void LLSurface::setOriginGlobal(const LLVector3d &origin_global) { - LLVector3d new_origin_global; - mOriginGlobal = origin_global; - LLSurfacePatch *patchp; - S32 i, j; - // Need to update the southwest corners of the patches - for (j=0; jgetOriginGlobal(); - - new_origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge; - new_origin_global.mdV[1] = mOriginGlobal.mdV[1] + j * mMetersPerGrid * mGridsPerPatchEdge; - patchp->setOriginGlobal(new_origin_global); - } - } - - // Hack! - if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull()) - { - const F64 x = origin_global.mdV[VX] + 128.0; - const F64 y = origin_global.mdV[VY] + 128.0; - const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ]; - - LLVector3d water_origin_global(x, y, z); - - mWaterObjp->setPositionGlobal(water_origin_global); - } + LLVector3d new_origin_global; + mOriginGlobal = origin_global; + LLSurfacePatch *patchp; + S32 i, j; + // Need to update the southwest corners of the patches + for (j=0; jgetOriginGlobal(); + + new_origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge; + new_origin_global.mdV[1] = mOriginGlobal.mdV[1] + j * mMetersPerGrid * mGridsPerPatchEdge; + patchp->setOriginGlobal(new_origin_global); + } + } + + // Hack! + if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull()) + { + const F64 x = origin_global.mdV[VX] + 128.0; + const F64 y = origin_global.mdV[VY] + 128.0; + const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ]; + + LLVector3d water_origin_global(x, y, z); + + mWaterObjp->setPositionGlobal(water_origin_global); + } } void LLSurface::getNeighboringRegions( std::vector& uniqueRegions ) { - S32 i; - for (i = 0; i < 8; i++) - { - if ( mNeighbors[i] != NULL ) - { - uniqueRegions.push_back( mNeighbors[i]->getRegion() ); - } - } + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + uniqueRegions.push_back( mNeighbors[i]->getRegion() ); + } + } } void LLSurface::getNeighboringRegionsStatus( std::vector& regions ) { - S32 i; - for (i = 0; i < 8; i++) - { - if ( mNeighbors[i] != NULL ) - { - regions.push_back( i ); - } - } + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + regions.push_back( i ); + } + } } void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { - S32 i; - LLSurfacePatch *patchp, *neighbor_patchp; - - mNeighbors[direction] = neighborp; - neighborp->mNeighbors[gDirOpposite[direction]] = this; - - // Connect patches - if (NORTHEAST == direction) - { - patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(0, 0); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - patchp->updateNorthEdge(); // Only update one of north or east. - patchp->dirtyZ(); - } - else if (NORTHWEST == direction) - { - patchp = getPatch(0, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - } - else if (SOUTHWEST == direction) - { - patchp = getPatch(0, 0); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - neighbor_patchp->updateNorthEdge(); // Only update one of north or east. - neighbor_patchp->dirtyZ(); - } - else if (SOUTHEAST == direction) - { - patchp = getPatch(mPatchesPerEdge - 1, 0); - neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - } - else if (EAST == direction) - { - // Do east/west connections, first - for (i = 0; i < (S32)mPatchesPerEdge; i++) - { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - patchp->updateEastEdge(); - patchp->dirtyZ(); - } - - // Now do northeast/southwest connections - for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) - { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i+1); - - patchp->connectNeighbor(neighbor_patchp, NORTHEAST); - neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); - } - // Now do southeast/northwest connections - for (i = 1; i < (S32)mPatchesPerEdge; i++) - { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i-1); - - patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); - neighbor_patchp->connectNeighbor(patchp, NORTHWEST); - } - } - else if (NORTH == direction) - { - // Do north/south connections, first - for (i = 0; i < (S32)mPatchesPerEdge; i++) - { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i, 0); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - patchp->updateNorthEdge(); - patchp->dirtyZ(); - } - - // Do northeast/southwest connections - for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) - { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i+1, 0); - - patchp->connectNeighbor(neighbor_patchp, NORTHEAST); - neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); - } - // Do southeast/northwest connections - for (i = 1; i < (S32)mPatchesPerEdge; i++) - { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i-1, 0); - - patchp->connectNeighbor(neighbor_patchp, NORTHWEST); - neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); - } - } - else if (WEST == direction) - { - // Do east/west connections, first - for (i = 0; i < mPatchesPerEdge; i++) - { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - neighbor_patchp->updateEastEdge(); - neighbor_patchp->dirtyZ(); - } - - // Now do northeast/southwest connections - for (i = 1; i < mPatchesPerEdge; i++) - { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1); - - patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); - neighbor_patchp->connectNeighbor(patchp, NORTHEAST); - } - - // Now do northwest/southeast connections - for (i = 0; i < mPatchesPerEdge - 1; i++) - { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1); - - patchp->connectNeighbor(neighbor_patchp, NORTHWEST); - neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); - } - } - else if (SOUTH == direction) - { - // Do north/south connections, first - for (i = 0; i < mPatchesPerEdge; i++) - { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1); - - patchp->connectNeighbor(neighbor_patchp, direction); - neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - - neighbor_patchp->updateNorthEdge(); - neighbor_patchp->dirtyZ(); - } - - // Now do northeast/southwest connections - for (i = 1; i < mPatchesPerEdge; i++) - { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1); - - patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); - neighbor_patchp->connectNeighbor(patchp, NORTHEAST); - } - // Now do northeast/southwest connections - for (i = 0; i < mPatchesPerEdge - 1; i++) - { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1); - - patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); - neighbor_patchp->connectNeighbor(patchp, NORTHWEST); - } - } + S32 i; + LLSurfacePatch *patchp, *neighbor_patchp; + + mNeighbors[direction] = neighborp; + neighborp->mNeighbors[gDirOpposite[direction]] = this; + + // Connect patches + if (NORTHEAST == direction) + { + patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(0, 0); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + patchp->updateNorthEdge(); // Only update one of north or east. + patchp->dirtyZ(); + } + else if (NORTHWEST == direction) + { + patchp = getPatch(0, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + } + else if (SOUTHWEST == direction) + { + patchp = getPatch(0, 0); + neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + neighbor_patchp->updateNorthEdge(); // Only update one of north or east. + neighbor_patchp->dirtyZ(); + } + else if (SOUTHEAST == direction) + { + patchp = getPatch(mPatchesPerEdge - 1, 0); + neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + } + else if (EAST == direction) + { + // Do east/west connections, first + for (i = 0; i < (S32)mPatchesPerEdge; i++) + { + patchp = getPatch(mPatchesPerEdge - 1, i); + neighbor_patchp = neighborp->getPatch(0, i); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + patchp->updateEastEdge(); + patchp->dirtyZ(); + } + + // Now do northeast/southwest connections + for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) + { + patchp = getPatch(mPatchesPerEdge - 1, i); + neighbor_patchp = neighborp->getPatch(0, i+1); + + patchp->connectNeighbor(neighbor_patchp, NORTHEAST); + neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); + } + // Now do southeast/northwest connections + for (i = 1; i < (S32)mPatchesPerEdge; i++) + { + patchp = getPatch(mPatchesPerEdge - 1, i); + neighbor_patchp = neighborp->getPatch(0, i-1); + + patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); + neighbor_patchp->connectNeighbor(patchp, NORTHWEST); + } + } + else if (NORTH == direction) + { + // Do north/south connections, first + for (i = 0; i < (S32)mPatchesPerEdge; i++) + { + patchp = getPatch(i, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i, 0); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + patchp->updateNorthEdge(); + patchp->dirtyZ(); + } + + // Do northeast/southwest connections + for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) + { + patchp = getPatch(i, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i+1, 0); + + patchp->connectNeighbor(neighbor_patchp, NORTHEAST); + neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); + } + // Do southeast/northwest connections + for (i = 1; i < (S32)mPatchesPerEdge; i++) + { + patchp = getPatch(i, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i-1, 0); + + patchp->connectNeighbor(neighbor_patchp, NORTHWEST); + neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); + } + } + else if (WEST == direction) + { + // Do east/west connections, first + for (i = 0; i < mPatchesPerEdge; i++) + { + patchp = getPatch(0, i); + neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + neighbor_patchp->updateEastEdge(); + neighbor_patchp->dirtyZ(); + } + + // Now do northeast/southwest connections + for (i = 1; i < mPatchesPerEdge; i++) + { + patchp = getPatch(0, i); + neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1); + + patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); + neighbor_patchp->connectNeighbor(patchp, NORTHEAST); + } + + // Now do northwest/southeast connections + for (i = 0; i < mPatchesPerEdge - 1; i++) + { + patchp = getPatch(0, i); + neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1); + + patchp->connectNeighbor(neighbor_patchp, NORTHWEST); + neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); + } + } + else if (SOUTH == direction) + { + // Do north/south connections, first + for (i = 0; i < mPatchesPerEdge; i++) + { + patchp = getPatch(i, 0); + neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1); + + patchp->connectNeighbor(neighbor_patchp, direction); + neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); + + neighbor_patchp->updateNorthEdge(); + neighbor_patchp->dirtyZ(); + } + + // Now do northeast/southwest connections + for (i = 1; i < mPatchesPerEdge; i++) + { + patchp = getPatch(i, 0); + neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1); + + patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); + neighbor_patchp->connectNeighbor(patchp, NORTHEAST); + } + // Now do northeast/southwest connections + for (i = 0; i < mPatchesPerEdge - 1; i++) + { + patchp = getPatch(i, 0); + neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1); + + patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); + neighbor_patchp->connectNeighbor(patchp, NORTHWEST); + } + } } void LLSurface::disconnectNeighbor(LLSurface *surfacep) { - S32 i; - for (i = 0; i < 8; i++) - { - if (surfacep == mNeighbors[i]) - { - mNeighbors[i] = NULL; - } - } - - // Iterate through surface patches, removing any connectivity to removed surface. - for (i = 0; i < mNumberOfPatches; i++) - { - (mPatchList + i)->disconnectNeighbor(surfacep); - } + S32 i; + for (i = 0; i < 8; i++) + { + if (surfacep == mNeighbors[i]) + { + mNeighbors[i] = NULL; + } + } + + // Iterate through surface patches, removing any connectivity to removed surface. + for (i = 0; i < mNumberOfPatches; i++) + { + (mPatchList + i)->disconnectNeighbor(surfacep); + } } void LLSurface::disconnectAllNeighbors() { - S32 i; - for (i = 0; i < 8; i++) - { - if (mNeighbors[i]) - { - mNeighbors[i]->disconnectNeighbor(this); - mNeighbors[i] = NULL; - } - } + S32 i; + for (i = 0; i < 8; i++) + { + if (mNeighbors[i]) + { + mNeighbors[i]->disconnectNeighbor(this); + mNeighbors[i] = NULL; + } + } } const LLVector3d &LLSurface::getOriginGlobal() const { - return mOriginGlobal; + return mOriginGlobal; } LLVector3 LLSurface::getOriginAgent() const { - return gAgent.getPosAgentFromGlobal(mOriginGlobal); + return gAgent.getPosAgentFromGlobal(mOriginGlobal); } F32 LLSurface::getMetersPerGrid() const { - return mMetersPerGrid; + return mMetersPerGrid; } S32 LLSurface::getGridsPerEdge() const { - return mGridsPerEdge; + return mGridsPerEdge; } S32 LLSurface::getPatchesPerEdge() const { - return mPatchesPerEdge; + return mPatchesPerEdge; } S32 LLSurface::getGridsPerPatchEdge() const { - return mGridsPerPatchEdge; + return mGridsPerPatchEdge; } void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta) { - llassert(x >= 0); - llassert(y >= 0); - llassert(x < mGridsPerEdge); - llassert(y < mGridsPerEdge); - mSurfaceZ[x + y*mGridsPerEdge] += delta; + llassert(x >= 0); + llassert(y >= 0); + llassert(x < mGridsPerEdge); + llassert(y < mGridsPerEdge); + mSurfaceZ[x + y*mGridsPerEdge] += delta; } -void LLSurface::updatePatchVisibilities(LLAgent &agent) +void LLSurface::updatePatchVisibilities(LLAgent &agent) { - if (gShiftFrame) - { - return; - } - - LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); - - LLSurfacePatch *patchp; - - mVisiblePatchCount = 0; - for (S32 i=0; iupdateVisibility(); - if (patchp->getVisible()) - { - mVisiblePatchCount++; - patchp->updateCameraDistanceRegion(pos_region); - } - } + if (gShiftFrame) + { + return; + } + + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); + + LLSurfacePatch *patchp; + + mVisiblePatchCount = 0; + for (S32 i=0; iupdateVisibility(); + if (patchp->getVisible()) + { + mVisiblePatchCount++; + patchp->updateCameraDistanceRegion(pos_region); + } + } } template bool LLSurface::idleUpdate(F32 max_update_time) { - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) - { - return false; - } - - // Perform idle time update of non-critical stuff. - // In this case, texture and normal updates. - LLTimer update_timer; - bool did_update = false; - - // If the Z height data has changed, we need to rebuild our - // property line vertex arrays. - if (mDirtyPatchList.size() > 0) - { - getRegion()->dirtyHeights(); - } - - // Always call updateNormals() / updateVerticalStats() - // every frame to avoid artifacts - for(std::set::iterator iter = mDirtyPatchList.begin(); - iter != mDirtyPatchList.end(); ) - { - std::set::iterator curiter = iter++; - LLSurfacePatch *patchp = *curiter; - patchp->updateNormals(); - patchp->updateVerticalStats(); - if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time) - { - if (patchp->updateTexture()) - { - did_update = true; - patchp->clearDirty(); - mDirtyPatchList.erase(curiter); - } - } - } + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) + { + return false; + } + + // Perform idle time update of non-critical stuff. + // In this case, texture and normal updates. + LLTimer update_timer; + bool did_update = false; + + // If the Z height data has changed, we need to rebuild our + // property line vertex arrays. + if (mDirtyPatchList.size() > 0) + { + getRegion()->dirtyHeights(); + } + + // Always call updateNormals() / updateVerticalStats() + // every frame to avoid artifacts + for(std::set::iterator iter = mDirtyPatchList.begin(); + iter != mDirtyPatchList.end(); ) + { + std::set::iterator curiter = iter++; + LLSurfacePatch *patchp = *curiter; + patchp->updateNormals(); + patchp->updateVerticalStats(); + if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time) + { + if (patchp->updateTexture()) + { + did_update = true; + patchp->clearDirty(); + mDirtyPatchList.erase(curiter); + } + } + } if (did_update) { @@ -689,76 +689,76 @@ bool LLSurface::idleUpdate(F32 max_update_time) mRegionp->updateReflectionProbes(); } - return did_update; + return did_update; } template bool LLSurface::idleUpdate(F32 max_update_time); template bool LLSurface::idleUpdate(F32 max_update_time); -void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch) +void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch) { - LLPatchHeader ph; - S32 j, i; - S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; - LLSurfacePatch *patchp; - - init_patch_decompressor(gopp->patch_size); - gopp->stride = mGridsPerEdge; - set_group_of_patch_header(gopp); - - while (1) - { - decode_patch_header(bitpack, &ph); - if (ph.quant_wbits == END_OF_PATCHES) - { - break; - } - - i = ph.patchids >> 5; - j = ph.patchids & 0x1F; - - if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge)) - { - LL_WARNS() << "Received invalid terrain packet - patch header patch ID incorrect!" - << " patches per edge " << mPatchesPerEdge - << " i " << i - << " j " << j - << " dc_offset " << ph.dc_offset - << " range " << (S32)ph.range - << " quant_wbits " << (S32)ph.quant_wbits - << " patchids " << (S32)ph.patchids - << LL_ENDL; - return; - } - - patchp = &mPatchList[j*mPatchesPerEdge + i]; - - - decode_patch(bitpack, patch); - decompress_patch(patchp->getDataZ(), patch, &ph); - - // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats. - patchp->updateNorthEdge(); - patchp->updateEastEdge(); - if (patchp->getNeighborPatch(WEST)) - { - patchp->getNeighborPatch(WEST)->updateEastEdge(); - } - if (patchp->getNeighborPatch(SOUTHWEST)) - { - patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge(); - patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge(); - } - if (patchp->getNeighborPatch(SOUTH)) - { - patchp->getNeighborPatch(SOUTH)->updateNorthEdge(); - } - - // Dirty patch statistics, and flag that the patch has data. - patchp->dirtyZ(); - patchp->setHasReceivedData(); - } + LLPatchHeader ph; + S32 j, i; + S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; + LLSurfacePatch *patchp; + + init_patch_decompressor(gopp->patch_size); + gopp->stride = mGridsPerEdge; + set_group_of_patch_header(gopp); + + while (1) + { + decode_patch_header(bitpack, &ph); + if (ph.quant_wbits == END_OF_PATCHES) + { + break; + } + + i = ph.patchids >> 5; + j = ph.patchids & 0x1F; + + if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge)) + { + LL_WARNS() << "Received invalid terrain packet - patch header patch ID incorrect!" + << " patches per edge " << mPatchesPerEdge + << " i " << i + << " j " << j + << " dc_offset " << ph.dc_offset + << " range " << (S32)ph.range + << " quant_wbits " << (S32)ph.quant_wbits + << " patchids " << (S32)ph.patchids + << LL_ENDL; + return; + } + + patchp = &mPatchList[j*mPatchesPerEdge + i]; + + + decode_patch(bitpack, patch); + decompress_patch(patchp->getDataZ(), patch, &ph); + + // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats. + patchp->updateNorthEdge(); + patchp->updateEastEdge(); + if (patchp->getNeighborPatch(WEST)) + { + patchp->getNeighborPatch(WEST)->updateEastEdge(); + } + if (patchp->getNeighborPatch(SOUTHWEST)) + { + patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge(); + patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge(); + } + if (patchp->getNeighborPatch(SOUTH)) + { + patchp->getNeighborPatch(SOUTH)->updateNorthEdge(); + } + + // Dirty patch statistics, and flag that the patch has data. + patchp->dirtyZ(); + patchp->setHasReceivedData(); + } } @@ -766,157 +766,157 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL // "position" is region-local BOOL LLSurface::containsPosition(const LLVector3 &position) { - if (position.mV[VX] < 0.0f || position.mV[VX] > mMetersPerEdge || - position.mV[VY] < 0.0f || position.mV[VY] > mMetersPerEdge) - { - return FALSE; - } - return TRUE; + if (position.mV[VX] < 0.0f || position.mV[VX] > mMetersPerEdge || + position.mV[VY] < 0.0f || position.mV[VY] > mMetersPerEdge) + { + return FALSE; + } + return TRUE; } F32 LLSurface::resolveHeightRegion(const F32 x, const F32 y) const { - F32 height = 0.0f; - F32 oometerspergrid = 1.f/mMetersPerGrid; - - // Check to see if v is actually above surface - // We use (mGridsPerEdge-1) below rather than (mGridsPerEdge) - // becuase of the east and north buffers - - if (x >= 0.f && - x <= mMetersPerEdge && - y >= 0.f && - y <= mMetersPerEdge) - { - const S32 left = llfloor(x * oometerspergrid); - const S32 bottom = llfloor(y * oometerspergrid); - - // Don't walk off the edge of the array! - const S32 right = ( left+1 < (S32)mGridsPerEdge-1 ? left+1 : left ); - const S32 top = ( bottom+1 < (S32)mGridsPerEdge-1 ? bottom+1 : bottom ); - - // Figure out if v is in first or second triangle of the square - // and calculate the slopes accordingly - // | | - // -(i,j+1)---(i+1,j+1)-- - // | 1 / | ^ - // | / 2 | | - // | / | j - // --(i,j)----(i+1,j)-- - // | | - // - // i -> - // where N = mGridsPerEdge - - const F32 left_bottom = getZ( left, bottom ); - const F32 right_bottom = getZ( right, bottom ); - const F32 left_top = getZ( left, top ); - const F32 right_top = getZ( right, top ); - - // dx and dy are incremental steps from (mSurface + k) - F32 dx = x - left * mMetersPerGrid; - F32 dy = y - bottom * mMetersPerGrid; - - if (dy > dx) - { - // triangle 1 - dy *= left_top - left_bottom; - dx *= right_top - left_top; - } - else - { - // triangle 2 - dx *= right_bottom - left_bottom; - dy *= right_top - right_bottom; - } - height = left_bottom + (dx + dy) * oometerspergrid; - } - return height; + F32 height = 0.0f; + F32 oometerspergrid = 1.f/mMetersPerGrid; + + // Check to see if v is actually above surface + // We use (mGridsPerEdge-1) below rather than (mGridsPerEdge) + // becuase of the east and north buffers + + if (x >= 0.f && + x <= mMetersPerEdge && + y >= 0.f && + y <= mMetersPerEdge) + { + const S32 left = llfloor(x * oometerspergrid); + const S32 bottom = llfloor(y * oometerspergrid); + + // Don't walk off the edge of the array! + const S32 right = ( left+1 < (S32)mGridsPerEdge-1 ? left+1 : left ); + const S32 top = ( bottom+1 < (S32)mGridsPerEdge-1 ? bottom+1 : bottom ); + + // Figure out if v is in first or second triangle of the square + // and calculate the slopes accordingly + // | | + // -(i,j+1)---(i+1,j+1)-- + // | 1 / | ^ + // | / 2 | | + // | / | j + // --(i,j)----(i+1,j)-- + // | | + // + // i -> + // where N = mGridsPerEdge + + const F32 left_bottom = getZ( left, bottom ); + const F32 right_bottom = getZ( right, bottom ); + const F32 left_top = getZ( left, top ); + const F32 right_top = getZ( right, top ); + + // dx and dy are incremental steps from (mSurface + k) + F32 dx = x - left * mMetersPerGrid; + F32 dy = y - bottom * mMetersPerGrid; + + if (dy > dx) + { + // triangle 1 + dy *= left_top - left_bottom; + dx *= right_top - left_top; + } + else + { + // triangle 2 + dx *= right_bottom - left_bottom; + dy *= right_top - right_bottom; + } + height = left_bottom + (dx + dy) * oometerspergrid; + } + return height; } F32 LLSurface::resolveHeightGlobal(const LLVector3d& v) const { - if (!mRegionp) - { - return 0.f; - } - - LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(v); - - return resolveHeightRegion(pos_region); + if (!mRegionp) + { + return 0.f; + } + + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(v); + + return resolveHeightRegion(pos_region); } LLVector3 LLSurface::resolveNormalGlobal(const LLVector3d& pos_global) const { - if (!mSurfaceZ) - { - // Hmm. Uninitialized surface! - return LLVector3::z_axis; - } - // - // Returns the vector normal to a surface at location specified by vector v - // - F32 oometerspergrid = 1.f/mMetersPerGrid; - LLVector3 normal; - F32 dzx, dzy; - - if (pos_global.mdV[VX] >= mOriginGlobal.mdV[VX] && - pos_global.mdV[VX] < mOriginGlobal.mdV[VX] + mMetersPerEdge && - pos_global.mdV[VY] >= mOriginGlobal.mdV[VY] && - pos_global.mdV[VY] < mOriginGlobal.mdV[VY] + mMetersPerEdge) - { - U32 i, j, k; - F32 dx, dy; - i = (U32) ((pos_global.mdV[VX] - mOriginGlobal.mdV[VX]) * oometerspergrid); - j = (U32) ((pos_global.mdV[VY] - mOriginGlobal.mdV[VY]) * oometerspergrid ); - k = i + j*mGridsPerEdge; - - // Figure out if v is in first or second triangle of the square - // and calculate the slopes accordingly - // | | - // -(k+N)---(k+1+N)-- - // | 1 / | ^ - // | / 2 | | - // | / | j - // --(k)----(k+1)-- - // | | - // - // i -> - // where N = mGridsPerEdge - - // dx and dy are incremental steps from (mSurface + k) - dx = (F32)(pos_global.mdV[VX] - i*mMetersPerGrid - mOriginGlobal.mdV[VX]); - dy = (F32)(pos_global.mdV[VY] - j*mMetersPerGrid - mOriginGlobal.mdV[VY]); - if (dy > dx) - { // triangle 1 - dzx = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + mGridsPerEdge); - dzy = *(mSurfaceZ + k) - *(mSurfaceZ + k + mGridsPerEdge); - normal.setVec(-dzx,dzy,1); - } - else - { // triangle 2 - dzx = *(mSurfaceZ + k) - *(mSurfaceZ + k + 1); - dzy = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + 1); - normal.setVec(dzx,-dzy,1); - } - } - normal.normVec(); - return normal; + if (!mSurfaceZ) + { + // Hmm. Uninitialized surface! + return LLVector3::z_axis; + } + // + // Returns the vector normal to a surface at location specified by vector v + // + F32 oometerspergrid = 1.f/mMetersPerGrid; + LLVector3 normal; + F32 dzx, dzy; + + if (pos_global.mdV[VX] >= mOriginGlobal.mdV[VX] && + pos_global.mdV[VX] < mOriginGlobal.mdV[VX] + mMetersPerEdge && + pos_global.mdV[VY] >= mOriginGlobal.mdV[VY] && + pos_global.mdV[VY] < mOriginGlobal.mdV[VY] + mMetersPerEdge) + { + U32 i, j, k; + F32 dx, dy; + i = (U32) ((pos_global.mdV[VX] - mOriginGlobal.mdV[VX]) * oometerspergrid); + j = (U32) ((pos_global.mdV[VY] - mOriginGlobal.mdV[VY]) * oometerspergrid ); + k = i + j*mGridsPerEdge; + + // Figure out if v is in first or second triangle of the square + // and calculate the slopes accordingly + // | | + // -(k+N)---(k+1+N)-- + // | 1 / | ^ + // | / 2 | | + // | / | j + // --(k)----(k+1)-- + // | | + // + // i -> + // where N = mGridsPerEdge + + // dx and dy are incremental steps from (mSurface + k) + dx = (F32)(pos_global.mdV[VX] - i*mMetersPerGrid - mOriginGlobal.mdV[VX]); + dy = (F32)(pos_global.mdV[VY] - j*mMetersPerGrid - mOriginGlobal.mdV[VY]); + if (dy > dx) + { // triangle 1 + dzx = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + mGridsPerEdge); + dzy = *(mSurfaceZ + k) - *(mSurfaceZ + k + mGridsPerEdge); + normal.setVec(-dzx,dzy,1); + } + else + { // triangle 2 + dzx = *(mSurfaceZ + k) - *(mSurfaceZ + k + 1); + dzy = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + 1); + normal.setVec(dzx,-dzy,1); + } + } + normal.normVec(); + return normal; } LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const { -// x and y should be region-local coordinates. +// x and y should be region-local coordinates. // If x and y are outside of the surface, then the returned // index will be for the nearest boundary patch. // // 12 | 13| 14| 15 -// | | | +// | | | // +---+---+---+---+ // | 12| 13| 14| 15| // ----+---+---+---+---+----- @@ -926,393 +926,393 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const // ----+---+---+---+---+----- // | 0 | 1 | 2 | 3 | // +---+---+---+---+ -// | | | +// | | | // 0 | 1 | 2 | 3 // // When x and y are not region-local do the following first - S32 i, j; - if (x < 0.0f) - { - i = 0; - } - else if (x >= mMetersPerEdge) - { - i = mPatchesPerEdge - 1; - } - else - { - i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge)); - } - - if (y < 0.0f) - { - j = 0; - } - else if (y >= mMetersPerEdge) - { - j = mPatchesPerEdge - 1; - } - else - { - j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge)); - } - - // *NOTE: Super paranoia code follows. - S32 index = i + j * mPatchesPerEdge; - if((index < 0) || (index >= mNumberOfPatches)) - { - if(0 == mNumberOfPatches) - { - LL_WARNS() << "No patches for current region!" << LL_ENDL; - return NULL; - } - S32 old_index = index; - index = llclamp(old_index, 0, (mNumberOfPatches - 1)); - LL_WARNS() << "Clamping out of range patch index " << old_index - << " to " << index << LL_ENDL; - } - return &(mPatchList[index]); + S32 i, j; + if (x < 0.0f) + { + i = 0; + } + else if (x >= mMetersPerEdge) + { + i = mPatchesPerEdge - 1; + } + else + { + i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge)); + } + + if (y < 0.0f) + { + j = 0; + } + else if (y >= mMetersPerEdge) + { + j = mPatchesPerEdge - 1; + } + else + { + j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge)); + } + + // *NOTE: Super paranoia code follows. + S32 index = i + j * mPatchesPerEdge; + if((index < 0) || (index >= mNumberOfPatches)) + { + if(0 == mNumberOfPatches) + { + LL_WARNS() << "No patches for current region!" << LL_ENDL; + return NULL; + } + S32 old_index = index; + index = llclamp(old_index, 0, (mNumberOfPatches - 1)); + LL_WARNS() << "Clamping out of range patch index " << old_index + << " to " << index << LL_ENDL; + } + return &(mPatchList[index]); } LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const { - return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]); + return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]); } LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const { - llassert(mRegionp); - LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global); - return resolvePatchRegion(pos_region); + llassert(mRegionp); + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global); + return resolvePatchRegion(pos_region); } -std::ostream& operator<<(std::ostream &s, const LLSurface &S) +std::ostream& operator<<(std::ostream &s, const LLSurface &S) { - s << "{ \n"; - s << " mGridsPerEdge = " << S.mGridsPerEdge - 1 << " + 1\n"; - s << " mGridsPerPatchEdge = " << S.mGridsPerPatchEdge << "\n"; - s << " mPatchesPerEdge = " << S.mPatchesPerEdge << "\n"; - s << " mOriginGlobal = " << S.mOriginGlobal << "\n"; - s << " mMetersPerGrid = " << S.mMetersPerGrid << "\n"; - s << " mVisiblePatchCount = " << S.mVisiblePatchCount << "\n"; - s << "}"; - return s; + s << "{ \n"; + s << " mGridsPerEdge = " << S.mGridsPerEdge - 1 << " + 1\n"; + s << " mGridsPerPatchEdge = " << S.mGridsPerPatchEdge << "\n"; + s << " mPatchesPerEdge = " << S.mPatchesPerEdge << "\n"; + s << " mOriginGlobal = " << S.mOriginGlobal << "\n"; + s << " mMetersPerGrid = " << S.mMetersPerGrid << "\n"; + s << " mVisiblePatchCount = " << S.mVisiblePatchCount << "\n"; + s << "}"; + return s; } // ---------------- LLSurface:: Protected ---------------- -void LLSurface::createPatchData() +void LLSurface::createPatchData() { - // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set - // TODO -- check for create() called when surface is not empty - S32 i, j; - LLSurfacePatch *patchp; - - // Allocate memory - mPatchList = new LLSurfacePatch[mNumberOfPatches]; - - // One of each for each camera - mVisiblePatchCount = mNumberOfPatches; - - for (j=0; jsetSurface(this); - } - } - - for (j=0; jmHasReceivedData = FALSE; - patchp->mSTexUpdate = TRUE; - - S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge; - - patchp->setDataZ(mSurfaceZ + data_offset); - patchp->setDataNorm(mNorm + data_offset); - - - // We make each patch point to its neighbors so we can do resolution checking - // when butting up different resolutions. Patches that don't have neighbors - // somewhere will point to NULL on that side. - if (i < mPatchesPerEdge-1) - { - patchp->setNeighborPatch(EAST,getPatch(i+1, j)); - } - else - { - patchp->setNeighborPatch(EAST, NULL); - } - - if (j < mPatchesPerEdge-1) - { - patchp->setNeighborPatch(NORTH, getPatch(i, j+1)); - } - else - { - patchp->setNeighborPatch(NORTH, NULL); - } - - if (i > 0) - { - patchp->setNeighborPatch(WEST, getPatch(i - 1, j)); - } - else - { - patchp->setNeighborPatch(WEST, NULL); - } - - if (j > 0) - { - patchp->setNeighborPatch(SOUTH, getPatch(i, j-1)); - } - else - { - patchp->setNeighborPatch(SOUTH, NULL); - } - - if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1)) - { - patchp->setNeighborPatch(NORTHEAST, getPatch(i + 1, j + 1)); - } - else - { - patchp->setNeighborPatch(NORTHEAST, NULL); - } - - if (i > 0 && j < (mPatchesPerEdge-1)) - { - patchp->setNeighborPatch(NORTHWEST, getPatch(i - 1, j + 1)); - } - else - { - patchp->setNeighborPatch(NORTHWEST, NULL); - } - - if (i > 0 && j > 0) - { - patchp->setNeighborPatch(SOUTHWEST, getPatch(i - 1, j - 1)); - } - else - { - patchp->setNeighborPatch(SOUTHWEST, NULL); - } - - if (i < (mPatchesPerEdge-1) && j > 0) - { - patchp->setNeighborPatch(SOUTHEAST, getPatch(i + 1, j - 1)); - } - else - { - patchp->setNeighborPatch(SOUTHEAST, NULL); - } - - LLVector3d origin_global; - origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge; - origin_global.mdV[1] = mOriginGlobal.mdV[0] + j * mMetersPerGrid * mGridsPerPatchEdge; - origin_global.mdV[2] = 0.f; - patchp->setOriginGlobal(origin_global); - } - } + // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set + // TODO -- check for create() called when surface is not empty + S32 i, j; + LLSurfacePatch *patchp; + + // Allocate memory + mPatchList = new LLSurfacePatch[mNumberOfPatches]; + + // One of each for each camera + mVisiblePatchCount = mNumberOfPatches; + + for (j=0; jsetSurface(this); + } + } + + for (j=0; jmHasReceivedData = FALSE; + patchp->mSTexUpdate = TRUE; + + S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge; + + patchp->setDataZ(mSurfaceZ + data_offset); + patchp->setDataNorm(mNorm + data_offset); + + + // We make each patch point to its neighbors so we can do resolution checking + // when butting up different resolutions. Patches that don't have neighbors + // somewhere will point to NULL on that side. + if (i < mPatchesPerEdge-1) + { + patchp->setNeighborPatch(EAST,getPatch(i+1, j)); + } + else + { + patchp->setNeighborPatch(EAST, NULL); + } + + if (j < mPatchesPerEdge-1) + { + patchp->setNeighborPatch(NORTH, getPatch(i, j+1)); + } + else + { + patchp->setNeighborPatch(NORTH, NULL); + } + + if (i > 0) + { + patchp->setNeighborPatch(WEST, getPatch(i - 1, j)); + } + else + { + patchp->setNeighborPatch(WEST, NULL); + } + + if (j > 0) + { + patchp->setNeighborPatch(SOUTH, getPatch(i, j-1)); + } + else + { + patchp->setNeighborPatch(SOUTH, NULL); + } + + if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1)) + { + patchp->setNeighborPatch(NORTHEAST, getPatch(i + 1, j + 1)); + } + else + { + patchp->setNeighborPatch(NORTHEAST, NULL); + } + + if (i > 0 && j < (mPatchesPerEdge-1)) + { + patchp->setNeighborPatch(NORTHWEST, getPatch(i - 1, j + 1)); + } + else + { + patchp->setNeighborPatch(NORTHWEST, NULL); + } + + if (i > 0 && j > 0) + { + patchp->setNeighborPatch(SOUTHWEST, getPatch(i - 1, j - 1)); + } + else + { + patchp->setNeighborPatch(SOUTHWEST, NULL); + } + + if (i < (mPatchesPerEdge-1) && j > 0) + { + patchp->setNeighborPatch(SOUTHEAST, getPatch(i + 1, j - 1)); + } + else + { + patchp->setNeighborPatch(SOUTHEAST, NULL); + } + + LLVector3d origin_global; + origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge; + origin_global.mdV[1] = mOriginGlobal.mdV[0] + j * mMetersPerGrid * mGridsPerPatchEdge; + origin_global.mdV[2] = 0.f; + patchp->setOriginGlobal(origin_global); + } + } } void LLSurface::destroyPatchData() { - // Delete all of the cached patch data for these patches. + // Delete all of the cached patch data for these patches. - delete [] mPatchList; - mPatchList = NULL; - mVisiblePatchCount = 0; + delete [] mPatchList; + mPatchList = NULL; + mVisiblePatchCount = 0; } void LLSurface::setTextureSize(const S32 texture_size) { - sTextureSize = texture_size; + sTextureSize = texture_size; } U32 LLSurface::getRenderLevel(const U32 render_stride) const { - return mPVArray.mRenderLevelp[render_stride]; + return mPVArray.mRenderLevelp[render_stride]; } U32 LLSurface::getRenderStride(const U32 render_level) const { - return mPVArray.mRenderStridep[render_level]; + return mPVArray.mRenderStridep[render_level]; } LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const { - if ((x < 0) || (x >= mPatchesPerEdge)) - { - LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL; - return NULL; - } - if ((y < 0) || (y >= mPatchesPerEdge)) - { - LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL; - return NULL; - } - - return mPatchList + x + y*mPatchesPerEdge; + if ((x < 0) || (x >= mPatchesPerEdge)) + { + LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL; + return NULL; + } + if ((y < 0) || (y >= mPatchesPerEdge)) + { + LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL; + return NULL; + } + + return mPatchList + x + y*mPatchesPerEdge; } void LLSurface::dirtyAllPatches() { - S32 i; - for (i = 0; i < mNumberOfPatches; i++) - { - mPatchList[i].dirtyZ(); - } + S32 i; + for (i = 0; i < mNumberOfPatches; i++) + { + mPatchList[i].dirtyZ(); + } } void LLSurface::dirtySurfacePatch(LLSurfacePatch *patchp) { - // Put surface patch on dirty surface patch list - mDirtyPatchList.insert(patchp); + // Put surface patch on dirty surface patch list + mDirtyPatchList.insert(patchp); } void LLSurface::setWaterHeight(F32 height) { - if (!mWaterObjp.isNull()) - { - LLVector3 water_pos_region = mWaterObjp->getPositionRegion(); - bool changed = water_pos_region.mV[VZ] != height; - water_pos_region.mV[VZ] = height; - mWaterObjp->setPositionRegion(water_pos_region); - if (changed) - { - LLWorld::getInstance()->updateWaterObjects(); - } - } - else - { - LL_WARNS() << "LLSurface::setWaterHeight with no water object!" << LL_ENDL; - } + if (!mWaterObjp.isNull()) + { + LLVector3 water_pos_region = mWaterObjp->getPositionRegion(); + bool changed = water_pos_region.mV[VZ] != height; + water_pos_region.mV[VZ] = height; + mWaterObjp->setPositionRegion(water_pos_region); + if (changed) + { + LLWorld::getInstance()->updateWaterObjects(); + } + } + else + { + LL_WARNS() << "LLSurface::setWaterHeight with no water object!" << LL_ENDL; + } } F32 LLSurface::getWaterHeight() const { - if (!mWaterObjp.isNull()) - { - // we have a water object, the usual case - return mWaterObjp->getPositionRegion().mV[VZ]; - } - else - { - return DEFAULT_WATER_HEIGHT; - } + if (!mWaterObjp.isNull()) + { + // we have a water object, the usual case + return mWaterObjp->getPositionRegion().mV[VZ]; + } + else + { + return DEFAULT_WATER_HEIGHT; + } } BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, - const F32 width, const F32 height) + const F32 width, const F32 height) { - LL_PROFILE_ZONE_SCOPED - if (!getWaterTexture()) - { - return FALSE; - } - - S32 tex_width = mWaterTexturep->getWidth(); - S32 tex_height = mWaterTexturep->getHeight(); - S32 tex_comps = mWaterTexturep->getComponents(); - S32 tex_stride = tex_width * tex_comps; - LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); - U8 *rawp = raw->getData(); - - F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width; - F32 scale_inv = 1.f / scale; - - S32 x_begin, y_begin, x_end, y_end; - - x_begin = ll_round(x * scale_inv); - y_begin = ll_round(y * scale_inv); - x_end = ll_round((x + width) * scale_inv); - y_end = ll_round((y + width) * scale_inv); - - if (x_end > tex_width) - { - x_end = tex_width; - } - if (y_end > tex_width) - { - y_end = tex_width; - } - - // OK, for now, just have the composition value equal the height at the point. - LLVector3 location; - LLColor4U coloru; - - const F32 WATER_HEIGHT = getWaterHeight(); - - S32 i, j, offset; - for (j = y_begin; j < y_end; j++) - { - for (i = x_begin; i < x_end; i++) - { - //F32 nv[2]; - //nv[0] = i/256.f; - //nv[1] = j/256.f; - // const S32 modulation = noise2(nv)*40; - offset = j*tex_stride + i*tex_comps; - location.mV[VX] = i*scale; - location.mV[VY] = j*scale; - - // Sample multiple points - const F32 height = resolveHeightRegion(location); - - if (height > WATER_HEIGHT) - { - // Above water... - coloru = MAX_WATER_COLOR; - coloru.mV[3] = ABOVE_WATERLINE_ALPHA; - *(rawp + offset++) = coloru.mV[0]; - *(rawp + offset++) = coloru.mV[1]; - *(rawp + offset++) = coloru.mV[2]; - *(rawp + offset++) = coloru.mV[3]; - } - else - { - // Want non-linear curve for transparency gradient - coloru = MAX_WATER_COLOR; - const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT)); - S32 alpha = 64 + ll_round((255-64)*frac); - - alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha); - alpha = llmax(64, alpha); - - coloru.mV[3] = alpha; - *(rawp + offset++) = coloru.mV[0]; - *(rawp + offset++) = coloru.mV[1]; - *(rawp + offset++) = coloru.mV[2]; - *(rawp + offset++) = coloru.mV[3]; - } - } - } - - if (!mWaterTexturep->hasGLTexture()) - { - mWaterTexturep->createGLTexture(0, raw); - } - - mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); - return TRUE; + LL_PROFILE_ZONE_SCOPED + if (!getWaterTexture()) + { + return FALSE; + } + + S32 tex_width = mWaterTexturep->getWidth(); + S32 tex_height = mWaterTexturep->getHeight(); + S32 tex_comps = mWaterTexturep->getComponents(); + S32 tex_stride = tex_width * tex_comps; + LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); + U8 *rawp = raw->getData(); + + F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width; + F32 scale_inv = 1.f / scale; + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round(x * scale_inv); + y_begin = ll_round(y * scale_inv); + x_end = ll_round((x + width) * scale_inv); + y_end = ll_round((y + width) * scale_inv); + + if (x_end > tex_width) + { + x_end = tex_width; + } + if (y_end > tex_width) + { + y_end = tex_width; + } + + // OK, for now, just have the composition value equal the height at the point. + LLVector3 location; + LLColor4U coloru; + + const F32 WATER_HEIGHT = getWaterHeight(); + + S32 i, j, offset; + for (j = y_begin; j < y_end; j++) + { + for (i = x_begin; i < x_end; i++) + { + //F32 nv[2]; + //nv[0] = i/256.f; + //nv[1] = j/256.f; + // const S32 modulation = noise2(nv)*40; + offset = j*tex_stride + i*tex_comps; + location.mV[VX] = i*scale; + location.mV[VY] = j*scale; + + // Sample multiple points + const F32 height = resolveHeightRegion(location); + + if (height > WATER_HEIGHT) + { + // Above water... + coloru = MAX_WATER_COLOR; + coloru.mV[3] = ABOVE_WATERLINE_ALPHA; + *(rawp + offset++) = coloru.mV[0]; + *(rawp + offset++) = coloru.mV[1]; + *(rawp + offset++) = coloru.mV[2]; + *(rawp + offset++) = coloru.mV[3]; + } + else + { + // Want non-linear curve for transparency gradient + coloru = MAX_WATER_COLOR; + const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT)); + S32 alpha = 64 + ll_round((255-64)*frac); + + alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha); + alpha = llmax(64, alpha); + + coloru.mV[3] = alpha; + *(rawp + offset++) = coloru.mV[0]; + *(rawp + offset++) = coloru.mV[1]; + *(rawp + offset++) = coloru.mV[2]; + *(rawp + offset++) = coloru.mV[3]; + } + } + } + + if (!mWaterTexturep->hasGLTexture()) + { + mWaterTexturep->createGLTexture(0, raw); + } + + mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); + return TRUE; } diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index b7b47d2a1c..093b141271 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -1,25 +1,25 @@ -/** +/** * @file llsurface.h * @brief Description of LLSurface class * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,9 +52,9 @@ static const U8 NORTH_EDGE = 0x02; static const U8 WEST_EDGE = 0x04; static const U8 SOUTH_EDGE = 0x08; -static const S32 ONE_MORE_THAN_NEIGHBOR = 1; -static const S32 EQUAL_TO_NEIGHBOR = 0; -static const S32 ONE_LESS_THAN_NEIGHBOR = -1; +static const S32 ONE_MORE_THAN_NEIGHBOR = 1; +static const S32 EQUAL_TO_NEIGHBOR = 0; +static const S32 ONE_LESS_THAN_NEIGHBOR = -1; const S32 ABOVE_WATERLINE_ALPHA = 32; // The alpha of water when the land elevation is above the waterline. @@ -63,166 +63,166 @@ class LLSurfacePatch; class LLBitPack; class LLGroupHeader; -class LLSurface +class LLSurface { public: - LLSurface(U32 type, LLViewerRegion *regionp = NULL); - virtual ~LLSurface(); + LLSurface(U32 type, LLViewerRegion *regionp = NULL); + virtual ~LLSurface(); - static void initClasses(); // Do class initialization for LLSurface and its child classes. + static void initClasses(); // Do class initialization for LLSurface and its child classes. - void create(const S32 surface_grid_width, - const S32 surface_patch_width, - const LLVector3d &origin_global, - const F32 width); // Allocates and initializes surface + void create(const S32 surface_grid_width, + const S32 surface_patch_width, + const LLVector3d &origin_global, + const F32 width); // Allocates and initializes surface - void setRegion(LLViewerRegion *regionp); + void setRegion(LLViewerRegion *regionp); - void setOriginGlobal(const LLVector3d &origin_global); + void setOriginGlobal(const LLVector3d &origin_global); - void connectNeighbor(LLSurface *neighborp, U32 direction); - void disconnectNeighbor(LLSurface *neighborp); - void disconnectAllNeighbors(); + void connectNeighbor(LLSurface *neighborp, U32 direction); + void disconnectNeighbor(LLSurface *neighborp); + void disconnectAllNeighbors(); - virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch); - virtual void updatePatchVisibilities(LLAgent &agent); + virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch); + virtual void updatePatchVisibilities(LLAgent &agent); - inline F32 getZ(const U32 k) const { return mSurfaceZ[k]; } - inline F32 getZ(const S32 i, const S32 j) const { return mSurfaceZ[i + j*mGridsPerEdge]; } + inline F32 getZ(const U32 k) const { return mSurfaceZ[k]; } + inline F32 getZ(const S32 i, const S32 j) const { return mSurfaceZ[i + j*mGridsPerEdge]; } - LLVector3 getOriginAgent() const; - const LLVector3d &getOriginGlobal() const; - F32 getMetersPerGrid() const; - S32 getGridsPerEdge() const; - S32 getPatchesPerEdge() const; - S32 getGridsPerPatchEdge() const; - U32 getRenderStride(const U32 render_level) const; - U32 getRenderLevel(const U32 render_stride) const; + LLVector3 getOriginAgent() const; + const LLVector3d &getOriginGlobal() const; + F32 getMetersPerGrid() const; + S32 getGridsPerEdge() const; + S32 getPatchesPerEdge() const; + S32 getGridsPerPatchEdge() const; + U32 getRenderStride(const U32 render_level) const; + U32 getRenderLevel(const U32 render_stride) const; - // Returns the height of the surface immediately above (or below) location, - // or if location is not above surface returns zero. - F32 resolveHeightRegion(const F32 x, const F32 y) const; - F32 resolveHeightRegion(const LLVector3 &location) const - { return resolveHeightRegion( location.mV[VX], location.mV[VY] ); } - F32 resolveHeightGlobal(const LLVector3d &position_global) const; - LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface + // Returns the height of the surface immediately above (or below) location, + // or if location is not above surface returns zero. + F32 resolveHeightRegion(const F32 x, const F32 y) const; + F32 resolveHeightRegion(const LLVector3 &location) const + { return resolveHeightRegion( location.mV[VX], location.mV[VY] ); } + F32 resolveHeightGlobal(const LLVector3d &position_global) const; + LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface - LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const; - LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const; - LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const; + LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const; + LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const; + LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const; - // Update methods (called during idle, normally) + // Update methods (called during idle, normally) template - bool idleUpdate(F32 max_update_time); + bool idleUpdate(F32 max_update_time); + + BOOL containsPosition(const LLVector3 &position); - BOOL containsPosition(const LLVector3 &position); + void moveZ(const S32 x, const S32 y, const F32 delta); - void moveZ(const S32 x, const S32 y, const F32 delta); + LLViewerRegion *getRegion() const { return mRegionp; } - LLViewerRegion *getRegion() const { return mRegionp; } + F32 getMinZ() const { return mMinZ; } + F32 getMaxZ() const { return mMaxZ; } - F32 getMinZ() const { return mMinZ; } - F32 getMaxZ() const { return mMaxZ; } + void setWaterHeight(F32 height); + F32 getWaterHeight() const; - void setWaterHeight(F32 height); - F32 getWaterHeight() const; + LLViewerTexture *getSTexture(); + LLViewerTexture *getWaterTexture(); + BOOL hasZData() const { return mHasZData; } - LLViewerTexture *getSTexture(); - LLViewerTexture *getWaterTexture(); - BOOL hasZData() const { return mHasZData; } + void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters - void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters + void dirtySurfacePatch(LLSurfacePatch *patchp); + LLVOWater *getWaterObj() { return mWaterObjp; } - void dirtySurfacePatch(LLSurfacePatch *patchp); - LLVOWater *getWaterObj() { return mWaterObjp; } + static void setTextureSize(const S32 texture_size); - static void setTextureSize(const S32 texture_size); + friend class LLSurfacePatch; + friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); + + void getNeighboringRegions( std::vector& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector& regions ); - friend class LLSurfacePatch; - friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); - - void getNeighboringRegions( std::vector& uniqueRegions ); - void getNeighboringRegionsStatus( std::vector& regions ); - public: - // Number of grid points on one side of a region, including +1 buffer for - // north and east edge. - S32 mGridsPerEdge; + // Number of grid points on one side of a region, including +1 buffer for + // north and east edge. + S32 mGridsPerEdge; + + F32 mOOGridsPerEdge; // Inverse of grids per edge - F32 mOOGridsPerEdge; // Inverse of grids per edge + S32 mPatchesPerEdge; // Number of patches on one side of a region + S32 mNumberOfPatches; // Total number of patches - S32 mPatchesPerEdge; // Number of patches on one side of a region - S32 mNumberOfPatches; // Total number of patches + // Each surface points at 8 neighbors (or NULL) + // +---+---+---+ + // |NW | N | NE| + // +---+---+---+ + // | W | 0 | E | + // +---+---+---+ + // |SW | S | SE| + // +---+---+---+ + LLSurface *mNeighbors[8]; // Adjacent patches - // Each surface points at 8 neighbors (or NULL) - // +---+---+---+ - // |NW | N | NE| - // +---+---+---+ - // | W | 0 | E | - // +---+---+---+ - // |SW | S | SE| - // +---+---+---+ - LLSurface *mNeighbors[8]; // Adjacent patches + U32 mType; // Useful for identifying derived classes - U32 mType; // Useful for identifying derived classes - - F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface + F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface protected: - void createSTexture(); - void createWaterTexture(); - void initTextures(); - void initWater(); + void createSTexture(); + void createWaterTexture(); + void initTextures(); + void initWater(); - void createPatchData(); // Allocates memory for patches. - void destroyPatchData(); // Deallocates memory for patches. + void createPatchData(); // Allocates memory for patches. + void destroyPatchData(); // Deallocates memory for patches. - BOOL generateWaterTexture(const F32 x, const F32 y, - const F32 width, const F32 height); // Generate texture from composition values. + BOOL generateWaterTexture(const F32 x, const F32 y, + const F32 width, const F32 height); // Generate texture from composition values. - //F32 updateTexture(LLSurfacePatch *ppatch); - - LLSurfacePatch *getPatch(const S32 x, const S32 y) const; + //F32 updateTexture(LLSurfacePatch *ppatch); + + LLSurfacePatch *getPatch(const S32 x, const S32 y) const; protected: - LLVector3d mOriginGlobal; // In absolute frame - LLSurfacePatch *mPatchList; // Array of all patches + LLVector3d mOriginGlobal; // In absolute frame + LLSurfacePatch *mPatchList; // Array of all patches - // Array of grid data, mGridsPerEdge * mGridsPerEdge - F32 *mSurfaceZ; + // Array of grid data, mGridsPerEdge * mGridsPerEdge + F32 *mSurfaceZ; - // Array of grid normals, mGridsPerEdge * mGridsPerEdge - LLVector3 *mNorm; + // Array of grid normals, mGridsPerEdge * mGridsPerEdge + LLVector3 *mNorm; - std::set mDirtyPatchList; + std::set mDirtyPatchList; - // The textures should never be directly initialized - use the setter methods! - LLPointer mSTexturep; // Texture for surface - LLPointer mWaterTexturep; // Water texture + // The textures should never be directly initialized - use the setter methods! + LLPointer mSTexturep; // Texture for surface + LLPointer mWaterTexturep; // Water texture - LLPointer mWaterObjp; + LLPointer mWaterObjp; - // When we want multiple cameras we'll need one of each these for each camera - S32 mVisiblePatchCount; + // When we want multiple cameras we'll need one of each these for each camera + S32 mVisiblePatchCount; - U32 mGridsPerPatchEdge; // Number of grid points on a side of a patch - F32 mMetersPerGrid; // Converts (i,j) indecies to distance - F32 mMetersPerEdge; // = mMetersPerGrid * (mGridsPerEdge-1) + U32 mGridsPerPatchEdge; // Number of grid points on a side of a patch + F32 mMetersPerGrid; // Converts (i,j) indecies to distance + F32 mMetersPerEdge; // = mMetersPerGrid * (mGridsPerEdge-1) - LLPatchVertexArray mPVArray; + LLPatchVertexArray mPVArray; - BOOL mHasZData; // We've received any patch data for this surface. - F32 mMinZ; // min z for this region (during the session) - F32 mMaxZ; // max z for this region (during the session) + BOOL mHasZData; // We've received any patch data for this surface. + F32 mMinZ; // min z for this region (during the session) + F32 mMaxZ; // max z for this region (during the session) - S32 mSurfacePatchUpdateCount; // Number of frames since last update. + S32 mSurfacePatchUpdateCount; // Number of frames since last update. private: - LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using. - static S32 sTextureSize; // Size of the surface texture + LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using. + static S32 sTextureSize; // Size of the surface texture }; extern template bool LLSurface::idleUpdate(F32 max_update_time); @@ -232,33 +232,33 @@ extern template bool LLSurface::idleUpdate(F32 max_update_time); // . __. // Z /|\ /| Y North -// | / +// | / // | / |<----------------- mGridsPerSurfaceEdge --------------->| // | / __________________________________________________________ // |/______\ X /_______________________________________________________ / -// / / / / / / / /M*M-2 /M*M-1 / / -// /______/______/______/______/______/______/______/______/ / -// / / / / / / / / / / -// /______/______/______/______/______/______/______/______/ / -// / / / / / / / / / / -// /______/______/______/______/______/______/______/______/ / -// West / / / / / / / / / / +// / / / / / / / /M*M-2 /M*M-1 / / +// /______/______/______/______/______/______/______/______/ / +// / / / / / / / / / / +// /______/______/______/______/______/______/______/______/ / +// / / / / / / / / / / +// /______/______/______/______/______/______/______/______/ / +// West / / / / / / / / / / // /______/______/______/______/______/______/______/______/ / East -// /... / / / / / / / / / -// /______/______/______/______/______/______/______/______/ / -// _. / 2M / / / / / / / / / -// /| /______/______/______/______/______/______/______/______/ / -// / / M / M+1 / M+2 / ... / / / / 2M-1 / / -// j /______/______/______/______/______/______/______/______/ / -// / 0 / 1 / 2 / ... / / / / M-1 / / -// /______/______/______/______/______/______/______/______/_/ +// /... / / / / / / / / / +// /______/______/______/______/______/______/______/______/ / +// _. / 2M / / / / / / / / / +// /| /______/______/______/______/______/______/______/______/ / +// / / M / M+1 / M+2 / ... / / / / 2M-1 / / +// j /______/______/______/______/______/______/______/______/ / +// / 0 / 1 / 2 / ... / / / / M-1 / / +// /______/______/______/______/______/______/______/______/_/ // South |<-L->| // i --> // // where M = mSurfPatchWidth // and L = mPatchGridWidth -// +// // Notice that mGridsPerSurfaceEdge = a power of two + 1 -// This provides a buffer on the east and north edges that will allow us to +// This provides a buffer on the east and north edges that will allow us to // fill the cracks between adjacent surfaces when rendering. #endif diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 92b1273041..b26d48b07f 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llsurfacepatch.cpp * @brief LLSurfacePatch class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,198 +46,198 @@ extern bool gShiftFrame; extern U64MicrosecondsImplicit gFrameTime; extern LLPipeline gPipeline; -LLSurfacePatch::LLSurfacePatch() -: mHasReceivedData(FALSE), - mSTexUpdate(FALSE), - mDirty(FALSE), - mDirtyZStats(TRUE), - mHeightsGenerated(FALSE), - mDataOffset(0), - mDataZ(NULL), - mDataNorm(NULL), - mVObjp(NULL), - mOriginRegion(0.f, 0.f, 0.f), - mCenterRegion(0.f, 0.f, 0.f), - mMinZ(0.f), - mMaxZ(0.f), - mMeanZ(0.f), - mRadius(0.f), - mMinComposition(0.f), - mMaxComposition(0.f), - mMeanComposition(0.f), - // This flag is used to communicate between adjacent surfaces and is - // set to non-zero values by higher classes. - mConnectedEdge(NO_EDGE), - mLastUpdateTime(0), - mSurfacep(NULL) -{ - S32 i; - for (i = 0; i < 8; i++) - { - setNeighborPatch(i, NULL); - } - for (i = 0; i < 9; i++) - { - mNormalsInvalid[i] = TRUE; - } +LLSurfacePatch::LLSurfacePatch() +: mHasReceivedData(FALSE), + mSTexUpdate(FALSE), + mDirty(FALSE), + mDirtyZStats(TRUE), + mHeightsGenerated(FALSE), + mDataOffset(0), + mDataZ(NULL), + mDataNorm(NULL), + mVObjp(NULL), + mOriginRegion(0.f, 0.f, 0.f), + mCenterRegion(0.f, 0.f, 0.f), + mMinZ(0.f), + mMaxZ(0.f), + mMeanZ(0.f), + mRadius(0.f), + mMinComposition(0.f), + mMaxComposition(0.f), + mMeanComposition(0.f), + // This flag is used to communicate between adjacent surfaces and is + // set to non-zero values by higher classes. + mConnectedEdge(NO_EDGE), + mLastUpdateTime(0), + mSurfacep(NULL) +{ + S32 i; + for (i = 0; i < 8; i++) + { + setNeighborPatch(i, NULL); + } + for (i = 0; i < 9; i++) + { + mNormalsInvalid[i] = TRUE; + } } LLSurfacePatch::~LLSurfacePatch() { - mVObjp = NULL; + mVObjp = NULL; } void LLSurfacePatch::dirty() { - // These are outside of the loop in case we're still waiting for a dirty from the - // texture being updated... - if (mVObjp) - { - mVObjp->dirtyGeom(); - } - else - { - LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL; - } - - mDirtyZStats = TRUE; - mHeightsGenerated = FALSE; - - if (!mDirty) - { - mDirty = TRUE; - mSurfacep->dirtySurfacePatch(this); - } + // These are outside of the loop in case we're still waiting for a dirty from the + // texture being updated... + if (mVObjp) + { + mVObjp->dirtyGeom(); + } + else + { + LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL; + } + + mDirtyZStats = TRUE; + mHeightsGenerated = FALSE; + + if (!mDirty) + { + mDirty = TRUE; + mSurfacep->dirtySurfacePatch(this); + } } void LLSurfacePatch::setSurface(LLSurface *surfacep) { - mSurfacep = surfacep; - if (mVObjp == (LLVOSurfacePatch *)NULL) - { - llassert(mSurfacep->mType == 'l'); - - mVObjp = (LLVOSurfacePatch *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SURFACE_PATCH, mSurfacep->getRegion()); - mVObjp->setPatch(this); - mVObjp->setPositionRegion(mCenterRegion); - gPipeline.createObject(mVObjp); - } -} + mSurfacep = surfacep; + if (mVObjp == (LLVOSurfacePatch *)NULL) + { + llassert(mSurfacep->mType == 'l'); + + mVObjp = (LLVOSurfacePatch *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SURFACE_PATCH, mSurfacep->getRegion()); + mVObjp->setPatch(this); + mVObjp->setPositionRegion(mCenterRegion); + gPipeline.createObject(mVObjp); + } +} void LLSurfacePatch::disconnectNeighbor(LLSurface *surfacep) { - U32 i; - for (i = 0; i < 8; i++) - { - if (getNeighborPatch(i)) - { - if (getNeighborPatch(i)->mSurfacep == surfacep) - { - setNeighborPatch(i, NULL); - mNormalsInvalid[i] = TRUE; - } - } - } - - // Clean up connected edges - if (getNeighborPatch(EAST)) - { - if (getNeighborPatch(EAST)->mSurfacep == surfacep) - { - mConnectedEdge &= ~EAST_EDGE; - } - } - if (getNeighborPatch(NORTH)) - { - if (getNeighborPatch(NORTH)->mSurfacep == surfacep) - { - mConnectedEdge &= ~NORTH_EDGE; - } - } - if (getNeighborPatch(WEST)) - { - if (getNeighborPatch(WEST)->mSurfacep == surfacep) - { - mConnectedEdge &= ~WEST_EDGE; - } - } - if (getNeighborPatch(SOUTH)) - { - if (getNeighborPatch(SOUTH)->mSurfacep == surfacep) - { - mConnectedEdge &= ~SOUTH_EDGE; - } - } + U32 i; + for (i = 0; i < 8; i++) + { + if (getNeighborPatch(i)) + { + if (getNeighborPatch(i)->mSurfacep == surfacep) + { + setNeighborPatch(i, NULL); + mNormalsInvalid[i] = TRUE; + } + } + } + + // Clean up connected edges + if (getNeighborPatch(EAST)) + { + if (getNeighborPatch(EAST)->mSurfacep == surfacep) + { + mConnectedEdge &= ~EAST_EDGE; + } + } + if (getNeighborPatch(NORTH)) + { + if (getNeighborPatch(NORTH)->mSurfacep == surfacep) + { + mConnectedEdge &= ~NORTH_EDGE; + } + } + if (getNeighborPatch(WEST)) + { + if (getNeighborPatch(WEST)->mSurfacep == surfacep) + { + mConnectedEdge &= ~WEST_EDGE; + } + } + if (getNeighborPatch(SOUTH)) + { + if (getNeighborPatch(SOUTH)->mSurfacep == surfacep) + { + mConnectedEdge &= ~SOUTH_EDGE; + } + } } LLVector3 LLSurfacePatch::getPointAgent(const U32 x, const U32 y) const { - U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 point_offset = x + y*surface_stride; - LLVector3 pos; - pos = getOriginAgent(); - pos.mV[VX] += x * mSurfacep->getMetersPerGrid(); - pos.mV[VY] += y * mSurfacep->getMetersPerGrid(); - pos.mV[VZ] = *(mDataZ + point_offset); - return pos; + U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 point_offset = x + y*surface_stride; + LLVector3 pos; + pos = getOriginAgent(); + pos.mV[VX] += x * mSurfacep->getMetersPerGrid(); + pos.mV[VY] += y * mSurfacep->getMetersPerGrid(); + pos.mV[VZ] = *(mDataZ + point_offset); + return pos; } LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const { - U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 point_offset = x + y*surface_stride; - LLVector3 pos, rel_pos; - pos = getOriginAgent(); - pos.mV[VX] += x * mSurfacep->getMetersPerGrid(); - pos.mV[VY] += y * mSurfacep->getMetersPerGrid(); - pos.mV[VZ] = *(mDataZ + point_offset); - rel_pos = pos - mSurfacep->getOriginAgent(); - rel_pos *= 1.f/surface_stride; - return LLVector2(rel_pos.mV[VX], rel_pos.mV[VY]); + U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 point_offset = x + y*surface_stride; + LLVector3 pos, rel_pos; + pos = getOriginAgent(); + pos.mV[VX] += x * mSurfacep->getMetersPerGrid(); + pos.mV[VY] += y * mSurfacep->getMetersPerGrid(); + pos.mV[VZ] = *(mDataZ + point_offset); + rel_pos = pos - mSurfacep->getOriginAgent(); + rel_pos *= 1.f/surface_stride; + return LLVector2(rel_pos.mV[VX], rel_pos.mV[VY]); } void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, - LLVector2 *tex0, LLVector2 *tex1) + LLVector2 *tex0, LLVector2 *tex1) { - if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) - { - return; // failsafe - } - llassert_always(vertex && normal && tex0 && tex1); - - U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 point_offset = x + y*surface_stride; - - *normal = getNormal(x, y); - - LLVector3 pos_agent = getOriginAgent(); - pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid(); - pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid(); - pos_agent.mV[VZ] = *(mDataZ + point_offset); - *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); - - LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it. + if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) + { + return; // failsafe + } + llassert_always(vertex && normal && tex0 && tex1); + + U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 point_offset = x + y*surface_stride; + + *normal = getNormal(x, y); + + LLVector3 pos_agent = getOriginAgent(); + pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid(); + pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid(); + pos_agent.mV[VZ] = *(mDataZ + point_offset); + *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); + + LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); + // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it. // *NOTE: In the future, UVs and horizontal position will no longer have a 1:1 relationship for PBR terrain - LLVector3 tex_pos = rel_pos; - tex0->mV[0] = tex_pos.mV[0]; - tex0->mV[1] = tex_pos.mV[1]; - tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); + LLVector3 tex_pos = rel_pos; + tex0->mV[0] = tex_pos.mV[0]; + tex0->mV[1] = tex_pos.mV[1]; + tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); - const F32 xyScale = 4.9215f*7.f; //0.93284f; - const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f); + const F32 xyScale = 4.9215f*7.f; //0.93284f; + const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f); - F32 vec[3] = { + F32 vec[3] = { (F32)fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), (F32)fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f), - 0.f - }; - F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f); - tex1->mV[1] = rand_val; + 0.f + }; + F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f); + tex1->mV[1] = rand_val; } @@ -246,126 +246,126 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 template<> void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { - U32 patch_width = mSurfacep->mPVArray.mPatchWidth; - U32 surface_stride = mSurfacep->getGridsPerEdge(); - - const F32 mpg = mSurfacep->getMetersPerGrid() * stride; - - S32 poffsets[2][2][2]; - poffsets[0][0][0] = x - stride; - poffsets[0][0][1] = y - stride; - - poffsets[0][1][0] = x - stride; - poffsets[0][1][1] = y + stride; - - poffsets[1][0][0] = x + stride; - poffsets[1][0][1] = y - stride; - - poffsets[1][1][0] = x + stride; - poffsets[1][1][1] = y + stride; - - const LLSurfacePatch *ppatches[2][2]; - - // LLVector3 p1, p2, p3, p4; - - ppatches[0][0] = this; - ppatches[0][1] = this; - ppatches[1][0] = this; - ppatches[1][1] = this; - - U32 i, j; - for (i = 0; i < 2; i++) - { - for (j = 0; j < 2; j++) - { - if (poffsets[i][j][0] < 0) - { - if (!ppatches[i][j]->getNeighborPatch(WEST)) - { - poffsets[i][j][0] = 0; - } - else - { - poffsets[i][j][0] += patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); - } - } - if (poffsets[i][j][1] < 0) - { - if (!ppatches[i][j]->getNeighborPatch(SOUTH)) - { - poffsets[i][j][1] = 0; - } - else - { - poffsets[i][j][1] += patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); - } - } - if (poffsets[i][j][0] >= (S32)patch_width) - { - if (!ppatches[i][j]->getNeighborPatch(EAST)) - { - poffsets[i][j][0] = patch_width - 1; - } - else - { - poffsets[i][j][0] -= patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); - } - } - if (poffsets[i][j][1] >= (S32)patch_width) - { - if (!ppatches[i][j]->getNeighborPatch(NORTH)) - { - poffsets[i][j][1] = patch_width - 1; - } - else - { - poffsets[i][j][1] -= patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); - } - } - } - } - - LLVector3 p00(-mpg,-mpg, - *(ppatches[0][0]->mDataZ - + poffsets[0][0][0] - + poffsets[0][0][1]*surface_stride)); - LLVector3 p01(-mpg,+mpg, - *(ppatches[0][1]->mDataZ - + poffsets[0][1][0] - + poffsets[0][1][1]*surface_stride)); - LLVector3 p10(+mpg,-mpg, - *(ppatches[1][0]->mDataZ - + poffsets[1][0][0] - + poffsets[1][0][1]*surface_stride)); - LLVector3 p11(+mpg,+mpg, - *(ppatches[1][1]->mDataZ - + poffsets[1][1][0] - + poffsets[1][1][1]*surface_stride)); - - LLVector3 c1 = p11 - p00; - LLVector3 c2 = p01 - p10; - - LLVector3 normal = c1; - normal %= c2; - normal.normVec(); - - llassert(mDataNorm); - *(mDataNorm + surface_stride * y + x) = normal; + U32 patch_width = mSurfacep->mPVArray.mPatchWidth; + U32 surface_stride = mSurfacep->getGridsPerEdge(); + + const F32 mpg = mSurfacep->getMetersPerGrid() * stride; + + S32 poffsets[2][2][2]; + poffsets[0][0][0] = x - stride; + poffsets[0][0][1] = y - stride; + + poffsets[0][1][0] = x - stride; + poffsets[0][1][1] = y + stride; + + poffsets[1][0][0] = x + stride; + poffsets[1][0][1] = y - stride; + + poffsets[1][1][0] = x + stride; + poffsets[1][1][1] = y + stride; + + const LLSurfacePatch *ppatches[2][2]; + + // LLVector3 p1, p2, p3, p4; + + ppatches[0][0] = this; + ppatches[0][1] = this; + ppatches[1][0] = this; + ppatches[1][1] = this; + + U32 i, j; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + if (poffsets[i][j][0] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(WEST)) + { + poffsets[i][j][0] = 0; + } + else + { + poffsets[i][j][0] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); + } + } + if (poffsets[i][j][1] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(SOUTH)) + { + poffsets[i][j][1] = 0; + } + else + { + poffsets[i][j][1] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); + } + } + if (poffsets[i][j][0] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(EAST)) + { + poffsets[i][j][0] = patch_width - 1; + } + else + { + poffsets[i][j][0] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); + } + } + if (poffsets[i][j][1] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(NORTH)) + { + poffsets[i][j][1] = patch_width - 1; + } + else + { + poffsets[i][j][1] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); + } + } + } + } + + LLVector3 p00(-mpg,-mpg, + *(ppatches[0][0]->mDataZ + + poffsets[0][0][0] + + poffsets[0][0][1]*surface_stride)); + LLVector3 p01(-mpg,+mpg, + *(ppatches[0][1]->mDataZ + + poffsets[0][1][0] + + poffsets[0][1][1]*surface_stride)); + LLVector3 p10(+mpg,-mpg, + *(ppatches[1][0]->mDataZ + + poffsets[1][0][0] + + poffsets[1][0][1]*surface_stride)); + LLVector3 p11(+mpg,+mpg, + *(ppatches[1][1]->mDataZ + + poffsets[1][1][0] + + poffsets[1][1][1]*surface_stride)); + + LLVector3 c1 = p11 - p00; + LLVector3 c2 = p01 - p10; + + LLVector3 normal = c1; + normal %= c2; + normal.normVec(); + + llassert(mDataNorm); + *(mDataNorm + surface_stride * y + x) = normal; } template<> void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { - llassert(mDataNorm); + llassert(mDataNorm); constexpr U32 index = 0; - const U32 surface_stride = mSurfacep->getGridsPerEdge(); - LLVector3& normal_out = *(mDataNorm + surface_stride * y + x); - calcNormalFlat(normal_out, x, y, index); + const U32 surface_stride = mSurfacep->getGridsPerEdge(); + LLVector3& normal_out = *(mDataNorm + surface_stride * y + x); + calcNormalFlat(normal_out, x, y, index); } // Calculate the flat normal of a triangle whose least coordinate is specified by the given x,y values. @@ -374,120 +374,120 @@ void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U3 { llassert(index == 0 || index == 1); - U32 patch_width = mSurfacep->mPVArray.mPatchWidth; - U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 patch_width = mSurfacep->mPVArray.mPatchWidth; + U32 surface_stride = mSurfacep->getGridsPerEdge(); // Vertex stride is always 1 because we want the flat surface of the current triangle face constexpr U32 stride = 1; - const F32 mpg = mSurfacep->getMetersPerGrid() * stride; - - S32 poffsets[2][2][2]; - poffsets[0][0][0] = x; - poffsets[0][0][1] = y; - - poffsets[0][1][0] = x; - poffsets[0][1][1] = y + stride; - - poffsets[1][0][0] = x + stride; - poffsets[1][0][1] = y; - - poffsets[1][1][0] = x + stride; - poffsets[1][1][1] = y + stride; - - const LLSurfacePatch *ppatches[2][2]; - - // LLVector3 p1, p2, p3, p4; - - ppatches[0][0] = this; - ppatches[0][1] = this; - ppatches[1][0] = this; - ppatches[1][1] = this; - - U32 i, j; - for (i = 0; i < 2; i++) - { - for (j = 0; j < 2; j++) - { - if (poffsets[i][j][0] < 0) - { - if (!ppatches[i][j]->getNeighborPatch(WEST)) - { - poffsets[i][j][0] = 0; - } - else - { - poffsets[i][j][0] += patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); - } - } - if (poffsets[i][j][1] < 0) - { - if (!ppatches[i][j]->getNeighborPatch(SOUTH)) - { - poffsets[i][j][1] = 0; - } - else - { - poffsets[i][j][1] += patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); - } - } - if (poffsets[i][j][0] >= (S32)patch_width) - { - if (!ppatches[i][j]->getNeighborPatch(EAST)) - { - poffsets[i][j][0] = patch_width - 1; - } - else - { - poffsets[i][j][0] -= patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); - } - } - if (poffsets[i][j][1] >= (S32)patch_width) - { - if (!ppatches[i][j]->getNeighborPatch(NORTH)) - { - poffsets[i][j][1] = patch_width - 1; - } - else - { - poffsets[i][j][1] -= patch_width; - ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); - } - } - } - } - - LLVector3 p00(-mpg,-mpg, - *(ppatches[0][0]->mDataZ - + poffsets[0][0][0] - + poffsets[0][0][1]*surface_stride)); - LLVector3 p01(-mpg,+mpg, - *(ppatches[0][1]->mDataZ - + poffsets[0][1][0] - + poffsets[0][1][1]*surface_stride)); - LLVector3 p10(+mpg,-mpg, - *(ppatches[1][0]->mDataZ - + poffsets[1][0][0] - + poffsets[1][0][1]*surface_stride)); - LLVector3 p11(+mpg,+mpg, - *(ppatches[1][1]->mDataZ - + poffsets[1][1][0] - + poffsets[1][1][1]*surface_stride)); - + const F32 mpg = mSurfacep->getMetersPerGrid() * stride; + + S32 poffsets[2][2][2]; + poffsets[0][0][0] = x; + poffsets[0][0][1] = y; + + poffsets[0][1][0] = x; + poffsets[0][1][1] = y + stride; + + poffsets[1][0][0] = x + stride; + poffsets[1][0][1] = y; + + poffsets[1][1][0] = x + stride; + poffsets[1][1][1] = y + stride; + + const LLSurfacePatch *ppatches[2][2]; + + // LLVector3 p1, p2, p3, p4; + + ppatches[0][0] = this; + ppatches[0][1] = this; + ppatches[1][0] = this; + ppatches[1][1] = this; + + U32 i, j; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + if (poffsets[i][j][0] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(WEST)) + { + poffsets[i][j][0] = 0; + } + else + { + poffsets[i][j][0] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); + } + } + if (poffsets[i][j][1] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(SOUTH)) + { + poffsets[i][j][1] = 0; + } + else + { + poffsets[i][j][1] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); + } + } + if (poffsets[i][j][0] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(EAST)) + { + poffsets[i][j][0] = patch_width - 1; + } + else + { + poffsets[i][j][0] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); + } + } + if (poffsets[i][j][1] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(NORTH)) + { + poffsets[i][j][1] = patch_width - 1; + } + else + { + poffsets[i][j][1] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); + } + } + } + } + + LLVector3 p00(-mpg,-mpg, + *(ppatches[0][0]->mDataZ + + poffsets[0][0][0] + + poffsets[0][0][1]*surface_stride)); + LLVector3 p01(-mpg,+mpg, + *(ppatches[0][1]->mDataZ + + poffsets[0][1][0] + + poffsets[0][1][1]*surface_stride)); + LLVector3 p10(+mpg,-mpg, + *(ppatches[1][0]->mDataZ + + poffsets[1][0][0] + + poffsets[1][0][1]*surface_stride)); + LLVector3 p11(+mpg,+mpg, + *(ppatches[1][1]->mDataZ + + poffsets[1][1][0] + + poffsets[1][1][1]*surface_stride)); + // Triangle index / coordinate convention // for a single surface patch // // p01 p11 // - // ^ ._____. - // | |\ | - // | | \ 1 | - // | | \ | - // | 0 \ | - // y |____\| + // ^ ._____. + // | |\ | + // | | \ 1 | + // | | \ | + // | 0 \ | + // y |____\| // // p00 x ---> p10 // @@ -513,268 +513,268 @@ void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U3 normal.normVec(); } - llassert(&normal_out); - normal_out = normal; + llassert(&normal_out); + normal_out = normal; } const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const { - U32 surface_stride = mSurfacep->getGridsPerEdge(); - llassert(mDataNorm); - return *(mDataNorm + surface_stride * y + x); + U32 surface_stride = mSurfacep->getGridsPerEdge(); + llassert(mDataNorm); + return *(mDataNorm + surface_stride * y + x); } void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region) { - if (LLPipeline::sDynamicLOD) - { - if (!gShiftFrame) - { - LLVector3 dv = pos_region; - dv -= mCenterRegion; - mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ - llmax(LLVOSurfacePatch::sLODFactor, 0.1f); - } - } - else - { - mVisInfo.mDistance = 0.f; - } + if (LLPipeline::sDynamicLOD) + { + if (!gShiftFrame) + { + LLVector3 dv = pos_region; + dv -= mCenterRegion; + mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ + llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + } + } + else + { + mVisInfo.mDistance = 0.f; + } } F32 LLSurfacePatch::getDistance() const { - return mVisInfo.mDistance; + return mVisInfo.mDistance; } // Called when a patch has changed its height field // data. -void LLSurfacePatch::updateVerticalStats() +void LLSurfacePatch::updateVerticalStats() { - if (!mDirtyZStats) - { - return; - } - - U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - U32 grids_per_edge = mSurfacep->getGridsPerEdge(); - F32 meters_per_grid = mSurfacep->getMetersPerGrid(); - - U32 i, j, k; - F32 z, total; - - llassert(mDataZ); - z = *(mDataZ); - - mMinZ = z; - mMaxZ = z; - - k = 0; - total = 0.0f; - - // Iterate to +1 because we need to do the edges correctly. - for (j=0; j<(grids_per_patch_edge+1); j++) - { - for (i=0; i<(grids_per_patch_edge+1); i++) - { - z = *(mDataZ + i + j*grids_per_edge); - - if (z < mMinZ) - { - mMinZ = z; - } - if (z > mMaxZ) - { - mMaxZ = z; - } - total += z; - k++; - } - } - mMeanZ = total / (F32) k; - mCenterRegion.mV[VZ] = 0.5f * (mMinZ + mMaxZ); - - LLVector3 diam_vec(meters_per_grid*grids_per_patch_edge, - meters_per_grid*grids_per_patch_edge, - mMaxZ - mMinZ); - mRadius = diam_vec.magVec() * 0.5f; - - mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ); - mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ); - mSurfacep->mHasZData = TRUE; - mSurfacep->getRegion()->calculateCenterGlobal(); - - if (mVObjp) - { - mVObjp->dirtyPatch(); - } - mDirtyZStats = FALSE; + if (!mDirtyZStats) + { + return; + } + + U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); + U32 grids_per_edge = mSurfacep->getGridsPerEdge(); + F32 meters_per_grid = mSurfacep->getMetersPerGrid(); + + U32 i, j, k; + F32 z, total; + + llassert(mDataZ); + z = *(mDataZ); + + mMinZ = z; + mMaxZ = z; + + k = 0; + total = 0.0f; + + // Iterate to +1 because we need to do the edges correctly. + for (j=0; j<(grids_per_patch_edge+1); j++) + { + for (i=0; i<(grids_per_patch_edge+1); i++) + { + z = *(mDataZ + i + j*grids_per_edge); + + if (z < mMinZ) + { + mMinZ = z; + } + if (z > mMaxZ) + { + mMaxZ = z; + } + total += z; + k++; + } + } + mMeanZ = total / (F32) k; + mCenterRegion.mV[VZ] = 0.5f * (mMinZ + mMaxZ); + + LLVector3 diam_vec(meters_per_grid*grids_per_patch_edge, + meters_per_grid*grids_per_patch_edge, + mMaxZ - mMinZ); + mRadius = diam_vec.magVec() * 0.5f; + + mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ); + mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ); + mSurfacep->mHasZData = TRUE; + mSurfacep->getRegion()->calculateCenterGlobal(); + + if (mVObjp) + { + mVObjp->dirtyPatch(); + } + mDirtyZStats = FALSE; } template -void LLSurfacePatch::updateNormals() +void LLSurfacePatch::updateNormals() { - if (mSurfacep->mType == 'w') - { - return; - } - U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - U32 grids_per_edge = mSurfacep->getGridsPerEdge(); - - BOOL dirty_patch = FALSE; - - U32 i, j; - // update the east edge - if (mNormalsInvalid[EAST] || mNormalsInvalid[NORTHEAST] || mNormalsInvalid[SOUTHEAST]) - { - for (j = 0; j <= grids_per_patch_edge; j++) - { - calcNormal(grids_per_patch_edge, j, 2); - calcNormal(grids_per_patch_edge - 1, j, 2); - calcNormal(grids_per_patch_edge - 2, j, 2); - } - - dirty_patch = TRUE; - } - - // update the north edge - if (mNormalsInvalid[NORTHEAST] || mNormalsInvalid[NORTH] || mNormalsInvalid[NORTHWEST]) - { - for (i = 0; i <= grids_per_patch_edge; i++) - { - calcNormal(i, grids_per_patch_edge, 2); - calcNormal(i, grids_per_patch_edge - 1, 2); - calcNormal(i, grids_per_patch_edge - 2, 2); - } - - dirty_patch = TRUE; - } - - // update the west edge - if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST]) - { - for (j = 0; j < grids_per_patch_edge; j++) - { - calcNormal(0, j, 2); - calcNormal(1, j, 2); - } - dirty_patch = TRUE; - } - - // update the south edge - if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST]) - { - for (i = 0; i < grids_per_patch_edge; i++) - { - calcNormal(i, 0, 2); - calcNormal(i, 1, 2); - } - dirty_patch = TRUE; - } - - // Invalidating the northeast corner is different, because depending on what the adjacent neighbors are, - // we'll want to do different things. - if (mNormalsInvalid[NORTHEAST]) - { - if (!getNeighborPatch(NORTHEAST)) - { - if (!getNeighborPatch(NORTH)) - { - if (!getNeighborPatch(EAST)) - { - // No north or east neighbors. Pull from the diagonal in your own patch. - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); - } - else - { - if (getNeighborPatch(EAST)->getHasReceivedData()) - { - // East, but not north. Pull from your east neighbor's northwest point. - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge); - } - else - { - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); - } - } - } - else - { - // We have a north. - if (getNeighborPatch(EAST)) - { - // North and east neighbors, but not northeast. - // Pull from diagonal in your own patch. - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); - } - else - { - if (getNeighborPatch(NORTH)->getHasReceivedData()) - { - // North, but not east. Pull from your north neighbor's southeast corner. - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1)); - } - else - { - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); - } - } - } - } - else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep) - { - if ( - (!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep)) - && - (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep))) - { - *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(NORTHEAST)->mDataZ); - } - } - else - { - // We've got a northeast patch in the same surface. - // The z and normals will be handled by that patch. - } - calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2); - calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2); - calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2); - calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2); - dirty_patch = TRUE; - } - - // update the middle normals - if (mNormalsInvalid[MIDDLE]) - { - for (j=2; j < grids_per_patch_edge - 2; j++) - { - for (i=2; i < grids_per_patch_edge - 2; i++) - { - calcNormal(i, j, 2); - } - } - dirty_patch = TRUE; - } - - if (dirty_patch) - { - mSurfacep->dirtySurfacePatch(this); - } - - for (i = 0; i < 9; i++) - { - mNormalsInvalid[i] = FALSE; - } + if (mSurfacep->mType == 'w') + { + return; + } + U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); + U32 grids_per_edge = mSurfacep->getGridsPerEdge(); + + BOOL dirty_patch = FALSE; + + U32 i, j; + // update the east edge + if (mNormalsInvalid[EAST] || mNormalsInvalid[NORTHEAST] || mNormalsInvalid[SOUTHEAST]) + { + for (j = 0; j <= grids_per_patch_edge; j++) + { + calcNormal(grids_per_patch_edge, j, 2); + calcNormal(grids_per_patch_edge - 1, j, 2); + calcNormal(grids_per_patch_edge - 2, j, 2); + } + + dirty_patch = TRUE; + } + + // update the north edge + if (mNormalsInvalid[NORTHEAST] || mNormalsInvalid[NORTH] || mNormalsInvalid[NORTHWEST]) + { + for (i = 0; i <= grids_per_patch_edge; i++) + { + calcNormal(i, grids_per_patch_edge, 2); + calcNormal(i, grids_per_patch_edge - 1, 2); + calcNormal(i, grids_per_patch_edge - 2, 2); + } + + dirty_patch = TRUE; + } + + // update the west edge + if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST]) + { + for (j = 0; j < grids_per_patch_edge; j++) + { + calcNormal(0, j, 2); + calcNormal(1, j, 2); + } + dirty_patch = TRUE; + } + + // update the south edge + if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST]) + { + for (i = 0; i < grids_per_patch_edge; i++) + { + calcNormal(i, 0, 2); + calcNormal(i, 1, 2); + } + dirty_patch = TRUE; + } + + // Invalidating the northeast corner is different, because depending on what the adjacent neighbors are, + // we'll want to do different things. + if (mNormalsInvalid[NORTHEAST]) + { + if (!getNeighborPatch(NORTHEAST)) + { + if (!getNeighborPatch(NORTH)) + { + if (!getNeighborPatch(EAST)) + { + // No north or east neighbors. Pull from the diagonal in your own patch. + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); + } + else + { + if (getNeighborPatch(EAST)->getHasReceivedData()) + { + // East, but not north. Pull from your east neighbor's northwest point. + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge); + } + else + { + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); + } + } + } + else + { + // We have a north. + if (getNeighborPatch(EAST)) + { + // North and east neighbors, but not northeast. + // Pull from diagonal in your own patch. + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); + } + else + { + if (getNeighborPatch(NORTH)->getHasReceivedData()) + { + // North, but not east. Pull from your north neighbor's southeast corner. + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1)); + } + else + { + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge); + } + } + } + } + else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep) + { + if ( + (!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep)) + && + (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep))) + { + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = + *(getNeighborPatch(NORTHEAST)->mDataZ); + } + } + else + { + // We've got a northeast patch in the same surface. + // The z and normals will be handled by that patch. + } + calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2); + calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2); + calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2); + calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2); + dirty_patch = TRUE; + } + + // update the middle normals + if (mNormalsInvalid[MIDDLE]) + { + for (j=2; j < grids_per_patch_edge - 2; j++) + { + for (i=2; i < grids_per_patch_edge - 2; i++) + { + calcNormal(i, j, 2); + } + } + dirty_patch = TRUE; + } + + if (dirty_patch) + { + mSurfacep->dirtySurfacePatch(this); + } + + for (i = 0; i < 9; i++) + { + mNormalsInvalid[i] = FALSE; + } } template void LLSurfacePatch::updateNormals(); @@ -782,418 +782,418 @@ template void LLSurfacePatch::updateNormals(); void LLSurfacePatch::updateEastEdge() { - U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - U32 grids_per_edge = mSurfacep->getGridsPerEdge(); - - U32 j, k; - F32 *west_surface, *east_surface; - - if (!getNeighborPatch(EAST)) - { - west_surface = mDataZ + grids_per_patch_edge; - east_surface = mDataZ + grids_per_patch_edge - 1; - } - else if (mConnectedEdge & EAST_EDGE) - { - west_surface = mDataZ + grids_per_patch_edge; - east_surface = getNeighborPatch(EAST)->mDataZ; - } - else - { - return; - } - - // If patchp is on the east edge of its surface, then we update the east - // side buffer - for (j=0; j < grids_per_patch_edge; j++) - { - k = j * grids_per_edge; - *(west_surface + k) = *(east_surface + k); // update buffer Z - } + U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); + U32 grids_per_edge = mSurfacep->getGridsPerEdge(); + + U32 j, k; + F32 *west_surface, *east_surface; + + if (!getNeighborPatch(EAST)) + { + west_surface = mDataZ + grids_per_patch_edge; + east_surface = mDataZ + grids_per_patch_edge - 1; + } + else if (mConnectedEdge & EAST_EDGE) + { + west_surface = mDataZ + grids_per_patch_edge; + east_surface = getNeighborPatch(EAST)->mDataZ; + } + else + { + return; + } + + // If patchp is on the east edge of its surface, then we update the east + // side buffer + for (j=0; j < grids_per_patch_edge; j++) + { + k = j * grids_per_edge; + *(west_surface + k) = *(east_surface + k); // update buffer Z + } } void LLSurfacePatch::updateNorthEdge() { - U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - U32 grids_per_edge = mSurfacep->getGridsPerEdge(); - - U32 i; - F32 *south_surface, *north_surface; - - if (!getNeighborPatch(NORTH)) - { - south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; - north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge; - } - else if (mConnectedEdge & NORTH_EDGE) - { - south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; - north_surface = getNeighborPatch(NORTH)->mDataZ; - } - else - { - return; - } - - // Update patchp's north edge ... - for (i=0; igetGridsPerPatchEdge(); + U32 grids_per_edge = mSurfacep->getGridsPerEdge(); + + U32 i; + F32 *south_surface, *north_surface; + + if (!getNeighborPatch(NORTH)) + { + south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; + north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge; + } + else if (mConnectedEdge & NORTH_EDGE) + { + south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; + north_surface = getNeighborPatch(NORTH)->mDataZ; + } + else + { + return; + } + + // Update patchp's north edge ... + for (i=0; igetMetersPerGrid(); - F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); - - if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData()) - && (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData()) - && (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData()) - && (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData())) - { - LLViewerRegion *regionp = getSurface()->getRegion(); - LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); - - // Have to figure out a better way to deal with these edge conditions... - LLVLComposition* comp = regionp->getComposition(); - if (!mHeightsGenerated) - { - F32 patch_size = meters_per_grid*(grids_per_patch_edge+1); - if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY], - patch_size, patch_size)) - { - mHeightsGenerated = TRUE; - } - else - { - return FALSE; - } - } - - if (comp->generateComposition()) - { - if (mVObjp) - { - mVObjp->dirtyGeom(); - gPipeline.markGLRebuild(mVObjp); - return !mSTexUpdate; - } - } - } - return FALSE; - } - else - { - return TRUE; - } + if (mSTexUpdate) // Update texture as needed + { + F32 meters_per_grid = getSurface()->getMetersPerGrid(); + F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); + + if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData()) + && (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData()) + && (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData()) + && (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData())) + { + LLViewerRegion *regionp = getSurface()->getRegion(); + LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); + + // Have to figure out a better way to deal with these edge conditions... + LLVLComposition* comp = regionp->getComposition(); + if (!mHeightsGenerated) + { + F32 patch_size = meters_per_grid*(grids_per_patch_edge+1); + if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY], + patch_size, patch_size)) + { + mHeightsGenerated = TRUE; + } + else + { + return FALSE; + } + } + + if (comp->generateComposition()) + { + if (mVObjp) + { + mVObjp->dirtyGeom(); + gPipeline.markGLRebuild(mVObjp); + return !mSTexUpdate; + } + } + } + return FALSE; + } + else + { + return TRUE; + } } void LLSurfacePatch::updateGL() { - LL_PROFILE_ZONE_SCOPED - F32 meters_per_grid = getSurface()->getMetersPerGrid(); - F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); - - LLViewerRegion *regionp = getSurface()->getRegion(); - LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); - - LLVLComposition* comp = regionp->getComposition(); - - updateCompositionStats(); - F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = FALSE; - - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); - } + LL_PROFILE_ZONE_SCOPED + F32 meters_per_grid = getSurface()->getMetersPerGrid(); + F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); + + LLViewerRegion *regionp = getSurface()->getRegion(); + LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); + + LLVLComposition* comp = regionp->getComposition(); + + updateCompositionStats(); + F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; + if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY], + tex_patch_size, tex_patch_size)) + { + mSTexUpdate = FALSE; + + // Also generate the water texture + mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], + tex_patch_size, tex_patch_size); + } } void LLSurfacePatch::dirtyZ() { - mSTexUpdate = TRUE; - - // Invalidate all normals in this patch - U32 i; - for (i = 0; i < 9; i++) - { - mNormalsInvalid[i] = TRUE; - } - - // Invalidate normals in this and neighboring patches - for (i = 0; i < 8; i++) - { - if (getNeighborPatch(i)) - { - getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE; - getNeighborPatch(i)->dirty(); - if (i < 4) - { - getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE; - getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE; - } - } - } - - dirty(); - mLastUpdateTime = gFrameTime; + mSTexUpdate = TRUE; + + // Invalidate all normals in this patch + U32 i; + for (i = 0; i < 9; i++) + { + mNormalsInvalid[i] = TRUE; + } + + // Invalidate normals in this and neighboring patches + for (i = 0; i < 8; i++) + { + if (getNeighborPatch(i)) + { + getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE; + getNeighborPatch(i)->dirty(); + if (i < 4) + { + getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE; + getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE; + } + } + } + + dirty(); + mLastUpdateTime = gFrameTime; } const U64 &LLSurfacePatch::getLastUpdateTime() const { - return mLastUpdateTime; + return mLastUpdateTime; } F32 LLSurfacePatch::getMaxZ() const { - return mMaxZ; + return mMaxZ; } F32 LLSurfacePatch::getMinZ() const { - return mMinZ; + return mMinZ; } void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global) { - mOriginGlobal = origin_global; + mOriginGlobal = origin_global; + + LLVector3 origin_region; + origin_region.setVec(mOriginGlobal - mSurfacep->getOriginGlobal()); - LLVector3 origin_region; - origin_region.setVec(mOriginGlobal - mSurfacep->getOriginGlobal()); + mOriginRegion = origin_region; + mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid(); + mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid(); - mOriginRegion = origin_region; - mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid(); - mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid(); + mVisInfo.mbIsVisible = FALSE; + mVisInfo.mDistance = 512.0f; + mVisInfo.mRenderLevel = 0; + mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge(); - mVisInfo.mbIsVisible = FALSE; - mVisInfo.mDistance = 512.0f; - mVisInfo.mRenderLevel = 0; - mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge(); - } void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction) { - llassert(neighbor_patchp); - mNormalsInvalid[direction] = TRUE; - neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE; - - setNeighborPatch(direction, neighbor_patchp); - neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this); - - if (EAST == direction) - { - mConnectedEdge |= EAST_EDGE; - neighbor_patchp->mConnectedEdge |= WEST_EDGE; - } - else if (NORTH == direction) - { - mConnectedEdge |= NORTH_EDGE; - neighbor_patchp->mConnectedEdge |= SOUTH_EDGE; - } - else if (WEST == direction) - { - mConnectedEdge |= WEST_EDGE; - neighbor_patchp->mConnectedEdge |= EAST_EDGE; - } - else if (SOUTH == direction) - { - mConnectedEdge |= SOUTH_EDGE; - neighbor_patchp->mConnectedEdge |= NORTH_EDGE; - } + llassert(neighbor_patchp); + mNormalsInvalid[direction] = TRUE; + neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE; + + setNeighborPatch(direction, neighbor_patchp); + neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this); + + if (EAST == direction) + { + mConnectedEdge |= EAST_EDGE; + neighbor_patchp->mConnectedEdge |= WEST_EDGE; + } + else if (NORTH == direction) + { + mConnectedEdge |= NORTH_EDGE; + neighbor_patchp->mConnectedEdge |= SOUTH_EDGE; + } + else if (WEST == direction) + { + mConnectedEdge |= WEST_EDGE; + neighbor_patchp->mConnectedEdge |= EAST_EDGE; + } + else if (SOUTH == direction) + { + mConnectedEdge |= SOUTH_EDGE; + neighbor_patchp->mConnectedEdge |= NORTH_EDGE; + } } void LLSurfacePatch::updateVisibility() { - if (mVObjp.isNull()) - { - return; - } - - const F32 DEFAULT_DELTA_ANGLE = (0.15f); - U32 old_render_stride, max_render_stride; - U32 new_render_level; - F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid(); - U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - - LLVector4a center; - center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV); - LLVector4a radius; - radius.splat(mRadius); - - // sphere in frustum on global coordinates - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius)) - { - // We now need to calculate the render stride based on patchp's distance - // from LLCamera render_stride is governed by a relation something like this... - // - // delta_angle * patch.distance - // render_stride <= ---------------------------------------- - // mMetersPerGrid - // - // where 'delta_angle' is the desired solid angle of the average polgon on a patch. - // - // Any render_stride smaller than the RHS would be 'satisfactory'. Smaller - // strides give more resolution, but efficiency suggests that we use the largest - // of the render_strides that obey the relation. Flexibility is achieved by - // modulating 'delta_angle' until we have an acceptable number of triangles. - - old_render_stride = mVisInfo.mRenderStride; - - // Calculate the render_stride using information in agent - max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance); - max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge); - - // We only use render_strides that are powers of two, so we use look-up tables to figure out - // the render_level and corresponding render_stride - new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride); - mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level); - - if ((mVisInfo.mRenderStride != old_render_stride)) - // The reason we check !mbIsVisible is because non-visible patches normals - // are not updated when their data is changed. When this changes we can get - // rid of mbIsVisible altogether. - { - if (mVObjp) - { - mVObjp->dirtyGeom(); - if (getNeighborPatch(WEST)) - { - getNeighborPatch(WEST)->mVObjp->dirtyGeom(); - } - if (getNeighborPatch(SOUTH)) - { - getNeighborPatch(SOUTH)->mVObjp->dirtyGeom(); - } - } - } - mVisInfo.mbIsVisible = TRUE; - } - else - { - mVisInfo.mbIsVisible = FALSE; - } + if (mVObjp.isNull()) + { + return; + } + + const F32 DEFAULT_DELTA_ANGLE = (0.15f); + U32 old_render_stride, max_render_stride; + U32 new_render_level; + F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid(); + U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); + + LLVector4a center; + center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV); + LLVector4a radius; + radius.splat(mRadius); + + // sphere in frustum on global coordinates + if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius)) + { + // We now need to calculate the render stride based on patchp's distance + // from LLCamera render_stride is governed by a relation something like this... + // + // delta_angle * patch.distance + // render_stride <= ---------------------------------------- + // mMetersPerGrid + // + // where 'delta_angle' is the desired solid angle of the average polgon on a patch. + // + // Any render_stride smaller than the RHS would be 'satisfactory'. Smaller + // strides give more resolution, but efficiency suggests that we use the largest + // of the render_strides that obey the relation. Flexibility is achieved by + // modulating 'delta_angle' until we have an acceptable number of triangles. + + old_render_stride = mVisInfo.mRenderStride; + + // Calculate the render_stride using information in agent + max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance); + max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge); + + // We only use render_strides that are powers of two, so we use look-up tables to figure out + // the render_level and corresponding render_stride + new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride); + mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level); + + if ((mVisInfo.mRenderStride != old_render_stride)) + // The reason we check !mbIsVisible is because non-visible patches normals + // are not updated when their data is changed. When this changes we can get + // rid of mbIsVisible altogether. + { + if (mVObjp) + { + mVObjp->dirtyGeom(); + if (getNeighborPatch(WEST)) + { + getNeighborPatch(WEST)->mVObjp->dirtyGeom(); + } + if (getNeighborPatch(SOUTH)) + { + getNeighborPatch(SOUTH)->mVObjp->dirtyGeom(); + } + } + } + mVisInfo.mbIsVisible = TRUE; + } + else + { + mVisInfo.mbIsVisible = FALSE; + } } const LLVector3d &LLSurfacePatch::getOriginGlobal() const { - return mOriginGlobal; + return mOriginGlobal; } LLVector3 LLSurfacePatch::getOriginAgent() const { - return gAgent.getPosAgentFromGlobal(mOriginGlobal); + return gAgent.getPosAgentFromGlobal(mOriginGlobal); } BOOL LLSurfacePatch::getVisible() const { - return mVisInfo.mbIsVisible; + return mVisInfo.mbIsVisible; } U32 LLSurfacePatch::getRenderStride() const { - return mVisInfo.mRenderStride; + return mVisInfo.mRenderStride; } S32 LLSurfacePatch::getRenderLevel() const { - return mVisInfo.mRenderLevel; + return mVisInfo.mRenderLevel; } void LLSurfacePatch::setHasReceivedData() { - mHasReceivedData = TRUE; + mHasReceivedData = TRUE; } BOOL LLSurfacePatch::getHasReceivedData() const { - return mHasReceivedData; + return mHasReceivedData; } const LLVector3 &LLSurfacePatch::getCenterRegion() const { - return mCenterRegion; + return mCenterRegion; } void LLSurfacePatch::updateCompositionStats() { - LLViewerLayer *vlp = mSurfacep->getRegion()->getComposition(); - - F32 x, y, width, height, mpg, min, mean, max; - - LLVector3 origin = getOriginAgent() - mSurfacep->getOriginAgent(); - mpg = mSurfacep->getMetersPerGrid(); - x = origin.mV[VX]; - y = origin.mV[VY]; - width = mpg*(mSurfacep->getGridsPerPatchEdge()+1); - height = mpg*(mSurfacep->getGridsPerPatchEdge()+1); - - mean = 0.f; - min = vlp->getValueScaled(x, y); - max= min; - U32 count = 0; - F32 i, j; - for (j = 0; j < height; j += mpg) - { - for (i = 0; i < width; i += mpg) - { - F32 comp = vlp->getValueScaled(x + i, y + j); - mean += comp; - min = llmin(min, comp); - max = llmax(max, comp); - count++; - } - } - mean /= count; - - mMinComposition = min; - mMeanComposition = mean; - mMaxComposition = max; + LLViewerLayer *vlp = mSurfacep->getRegion()->getComposition(); + + F32 x, y, width, height, mpg, min, mean, max; + + LLVector3 origin = getOriginAgent() - mSurfacep->getOriginAgent(); + mpg = mSurfacep->getMetersPerGrid(); + x = origin.mV[VX]; + y = origin.mV[VY]; + width = mpg*(mSurfacep->getGridsPerPatchEdge()+1); + height = mpg*(mSurfacep->getGridsPerPatchEdge()+1); + + mean = 0.f; + min = vlp->getValueScaled(x, y); + max= min; + U32 count = 0; + F32 i, j; + for (j = 0; j < height; j += mpg) + { + for (i = 0; i < width; i += mpg) + { + F32 comp = vlp->getValueScaled(x + i, y + j); + mean += comp; + min = llmin(min, comp); + max = llmax(max, comp); + count++; + } + } + mean /= count; + + mMinComposition = min; + mMeanComposition = mean; + mMaxComposition = max; } F32 LLSurfacePatch::getMeanComposition() const { - return mMeanComposition; + return mMeanComposition; } F32 LLSurfacePatch::getMinComposition() const { - return mMinComposition; + return mMinComposition; } F32 LLSurfacePatch::getMaxComposition() const { - return mMaxComposition; + return mMaxComposition; } void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp) { - mNeighborPatches[direction] = neighborp; - mNormalsInvalid[direction] = TRUE; - if (direction < 4) - { - mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE; - mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE; - } + mNeighborPatches[direction] = neighborp; + mNormalsInvalid[direction] = TRUE; + if (direction < 4) + { + mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE; + mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE; + } } LLSurfacePatch *LLSurfacePatch::getNeighborPatch(const U32 direction) const { - return mNeighborPatches[direction]; + return mNeighborPatches[direction]; } void LLSurfacePatch::clearVObj() { - mVObjp = NULL; + mVObjp = NULL; } diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index ec3864ce44..94d471b43d 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -1,25 +1,25 @@ -/** +/** * @file llsurfacepatch.h * @brief LLSurfacePatch class definition * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,71 +37,71 @@ class LLVector2; class LLColor4U; class LLAgent; -// A patch shouldn't know about its visibility since that really depends on the +// A patch shouldn't know about its visibility since that really depends on the // camera that is looking (or not looking) at it. So, anything about a patch // that is specific to a camera should be in the class below. class LLPatchVisibilityInfo { public: - LLPatchVisibilityInfo() : - mbIsVisible(FALSE), - mDistance(0.f), - mRenderLevel(0), - mRenderStride(0) { }; - ~LLPatchVisibilityInfo() { }; - - BOOL mbIsVisible; - F32 mDistance; // Distance from camera - S32 mRenderLevel; - U32 mRenderStride; + LLPatchVisibilityInfo() : + mbIsVisible(FALSE), + mDistance(0.f), + mRenderLevel(0), + mRenderStride(0) { }; + ~LLPatchVisibilityInfo() { }; + + BOOL mbIsVisible; + F32 mDistance; // Distance from camera + S32 mRenderLevel; + U32 mRenderStride; }; -class LLSurfacePatch +class LLSurfacePatch { public: - LLSurfacePatch(); - ~LLSurfacePatch(); + LLSurfacePatch(); + ~LLSurfacePatch(); - void reset(const U32 id); - void connectNeighbor(LLSurfacePatch *neighborp, const U32 direction); - void disconnectNeighbor(LLSurface *surfacep); + void reset(const U32 id); + void connectNeighbor(LLSurfacePatch *neighborp, const U32 direction); + void disconnectNeighbor(LLSurface *surfacep); - void setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp); - LLSurfacePatch *getNeighborPatch(const U32 direction) const; + void setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp); + LLSurfacePatch *getNeighborPatch(const U32 direction) const; - void colorPatch(const U8 r, const U8 g, const U8 b); + void colorPatch(const U8 r, const U8 g, const U8 b); - BOOL updateTexture(); + BOOL updateTexture(); - void updateVerticalStats(); - void updateCompositionStats(); + void updateVerticalStats(); + void updateCompositionStats(); template - void updateNormals(); - - void updateEastEdge(); - void updateNorthEdge(); - - void updateCameraDistanceRegion( const LLVector3 &pos_region); - void updateVisibility(); - void updateGL(); - - void dirtyZ(); // Dirty the z values of this patch - void setHasReceivedData(); - BOOL getHasReceivedData() const; - - F32 getDistance() const; - F32 getMaxZ() const; - F32 getMinZ() const; - F32 getMeanComposition() const; - F32 getMinComposition() const; - F32 getMaxComposition() const; - const LLVector3 &getCenterRegion() const; - const U64 &getLastUpdateTime() const; - LLSurface *getSurface() const { return mSurfacep; } - LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset. - LLVector2 getTexCoords(const U32 x, const U32 y) const; + void updateNormals(); + + void updateEastEdge(); + void updateNorthEdge(); + + void updateCameraDistanceRegion( const LLVector3 &pos_region); + void updateVisibility(); + void updateGL(); + + void dirtyZ(); // Dirty the z values of this patch + void setHasReceivedData(); + BOOL getHasReceivedData() const; + + F32 getDistance() const; + F32 getMaxZ() const; + F32 getMinZ() const; + F32 getMeanComposition() const; + F32 getMinComposition() const; + F32 getMaxComposition() const; + const LLVector3 &getCenterRegion() const; + const U64 &getLastUpdateTime() const; + LLSurface *getSurface() const { return mSurfacep; } + LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset. + LLVector2 getTexCoords(const U32 x, const U32 y) const; // Per-vertex normals // *TODO: PBR=true is a test implementation solely for proof-of-concept. @@ -109,86 +109,86 @@ public: // this function. If we decide to keep calcNormalFlat, remove index as it // is a debug parameter for testing. template - void calcNormal(const U32 x, const U32 y, const U32 stride); - const LLVector3 &getNormal(const U32 x, const U32 y) const; + void calcNormal(const U32 x, const U32 y, const U32 stride); + const LLVector3 &getNormal(const U32 x, const U32 y) const; // Per-triangle normals for flat edges - void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */); + void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */); + + void eval(const U32 x, const U32 y, const U32 stride, + LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); + + - void eval(const U32 x, const U32 y, const U32 stride, - LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); - - + LLVector3 getOriginAgent() const; + const LLVector3d &getOriginGlobal() const; + void setOriginGlobal(const LLVector3d &origin_global); - LLVector3 getOriginAgent() const; - const LLVector3d &getOriginGlobal() const; - void setOriginGlobal(const LLVector3d &origin_global); - - // connectivity -- each LLPatch points at 5 neighbors (or NULL) - // +---+---+---+ - // | | 2 | 5 | - // +---+---+---+ - // | 3 | 0 | 1 | - // +---+---+---+ - // | 6 | 4 | | - // +---+---+---+ + // connectivity -- each LLPatch points at 5 neighbors (or NULL) + // +---+---+---+ + // | | 2 | 5 | + // +---+---+---+ + // | 3 | 0 | 1 | + // +---+---+---+ + // | 6 | 4 | | + // +---+---+---+ - BOOL getVisible() const; - U32 getRenderStride() const; - S32 getRenderLevel() const; + BOOL getVisible() const; + U32 getRenderStride() const; + S32 getRenderLevel() const; - void setSurface(LLSurface *surfacep); - void setDataZ(F32 *data_z) { mDataZ = data_z; } - void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; } - F32 *getDataZ() const { return mDataZ; } + void setSurface(LLSurface *surfacep); + void setDataZ(F32 *data_z) { mDataZ = data_z; } + void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; } + F32 *getDataZ() const { return mDataZ; } - void dirty(); // Mark this surface patch as dirty... - void clearDirty() { mDirty = FALSE; } + void dirty(); // Mark this surface patch as dirty... + void clearDirty() { mDirty = FALSE; } - void clearVObj(); + void clearVObj(); public: - BOOL mHasReceivedData; // has the patch EVER received height data? - BOOL mSTexUpdate; // Does the surface texture need to be updated? + BOOL mHasReceivedData; // has the patch EVER received height data? + BOOL mSTexUpdate; // Does the surface texture need to be updated? protected: - LLSurfacePatch *mNeighborPatches[8]; // Adjacent patches - BOOL mNormalsInvalid[9]; // Which normals are invalid + LLSurfacePatch *mNeighborPatches[8]; // Adjacent patches + BOOL mNormalsInvalid[9]; // Which normals are invalid - BOOL mDirty; - BOOL mDirtyZStats; - BOOL mHeightsGenerated; + BOOL mDirty; + BOOL mDirtyZStats; + BOOL mHeightsGenerated; - U32 mDataOffset; - F32 *mDataZ; - LLVector3 *mDataNorm; + U32 mDataOffset; + F32 *mDataZ; + LLVector3 *mDataNorm; - // Pointer to the LLVOSurfacePatch object which is used in the new renderer. - LLPointer mVObjp; + // Pointer to the LLVOSurfacePatch object which is used in the new renderer. + LLPointer mVObjp; - // All of the camera-dependent stuff should be in its own class... - LLPatchVisibilityInfo mVisInfo; + // All of the camera-dependent stuff should be in its own class... + LLPatchVisibilityInfo mVisInfo; - // pointers to beginnings of patch data fields - LLVector3d mOriginGlobal; - LLVector3 mOriginRegion; + // pointers to beginnings of patch data fields + LLVector3d mOriginGlobal; + LLVector3 mOriginRegion; - // height field stats - LLVector3 mCenterRegion; // Center in region-local coords - F32 mMinZ, mMaxZ, mMeanZ; - F32 mRadius; + // height field stats + LLVector3 mCenterRegion; // Center in region-local coords + F32 mMinZ, mMaxZ, mMeanZ; + F32 mRadius; - F32 mMinComposition; - F32 mMaxComposition; - F32 mMeanComposition; + F32 mMinComposition; + F32 mMaxComposition; + F32 mMeanComposition; - U8 mConnectedEdge; // This flag is non-zero iff patch is on at least one edge - // of LLSurface that is "connected" to another LLSurface - U64 mLastUpdateTime; // Time patch was last updated + U8 mConnectedEdge; // This flag is non-zero iff patch is on at least one edge + // of LLSurface that is "connected" to another LLSurface + U64 mLastUpdateTime; // Time patch was last updated - LLSurface *mSurfacep; // Pointer to "parent" surface + LLSurface *mSurfacep; // Pointer to "parent" surface }; extern template void LLSurfacePatch::updateNormals(); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 91c2755ea5..4744edd5a3 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lltexturectrl.cpp * @author Richard Nelson, James Cook * @brief LLTextureCtrl class implementation including related functions @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,7 +49,7 @@ #include "llmaterialeditor.h" #include "llui.h" #include "llviewerinventory.h" -#include "llviewermenufile.h" // LLFilePickerReplyThread +#include "llviewermenufile.h" // LLFilePickerReplyThread #include "llpermissions.h" #include "llpreviewtexture.h" #include "llsaleinfo.h" @@ -105,7 +105,7 @@ LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm) items, LLInventoryModel::INCLUDE_TRASH, asset_id_matches); - + LLUUID res; if (items.size()) { @@ -143,53 +143,53 @@ bool get_can_copy_texture(LLUUID asset_id) S32 LLFloaterTexturePicker::sLastPickerMode = 0; -LLFloaterTexturePicker::LLFloaterTexturePicker( - LLView* owner, - LLUUID image_asset_id, - LLUUID default_image_asset_id, - LLUUID blank_image_asset_id, - BOOL tentative, - BOOL allow_no_texture, - const std::string& label, - PermissionMask immediate_filter_perm_mask, - PermissionMask dnd_filter_perm_mask, - BOOL can_apply_immediately, - LLUIImagePtr fallback_image, +LLFloaterTexturePicker::LLFloaterTexturePicker( + LLView* owner, + LLUUID image_asset_id, + LLUUID default_image_asset_id, + LLUUID blank_image_asset_id, + BOOL tentative, + BOOL allow_no_texture, + const std::string& label, + PermissionMask immediate_filter_perm_mask, + PermissionMask dnd_filter_perm_mask, + BOOL can_apply_immediately, + LLUIImagePtr fallback_image, EPickInventoryType pick_type) -: LLFloater(LLSD()), - mOwner( owner ), - mImageAssetID( image_asset_id ), - mOriginalImageAssetID(image_asset_id), - mFallbackImage(fallback_image), - mDefaultImageAssetID(default_image_asset_id), - mBlankImageAssetID(blank_image_asset_id), - mTentative(tentative), - mAllowNoTexture(allow_no_texture), - mLabel(label), - mTentativeLabel(NULL), - mResolutionLabel(NULL), - mActive( TRUE ), - mFilterEdit(NULL), - mImmediateFilterPermMask(immediate_filter_perm_mask), - mDnDFilterPermMask(dnd_filter_perm_mask), - mContextConeOpacity(0.f), - mSelectedItemPinned( FALSE ), - mCanApply(true), - mCanPreview(true), +: LLFloater(LLSD()), + mOwner( owner ), + mImageAssetID( image_asset_id ), + mOriginalImageAssetID(image_asset_id), + mFallbackImage(fallback_image), + mDefaultImageAssetID(default_image_asset_id), + mBlankImageAssetID(blank_image_asset_id), + mTentative(tentative), + mAllowNoTexture(allow_no_texture), + mLabel(label), + mTentativeLabel(NULL), + mResolutionLabel(NULL), + mActive( TRUE ), + mFilterEdit(NULL), + mImmediateFilterPermMask(immediate_filter_perm_mask), + mDnDFilterPermMask(dnd_filter_perm_mask), + mContextConeOpacity(0.f), + mSelectedItemPinned( FALSE ), + mCanApply(true), + mCanPreview(true), mLimitsSet(false), mMaxDim(S32_MAX), mMinDim(0), - mPreviewSettingChanged(false), - mOnFloaterCommitCallback(NULL), - mOnFloaterCloseCallback(NULL), - mSetImageAssetIDCallback(NULL), - mOnUpdateImageStatsCallback(NULL), - mBakeTextureEnabled(FALSE), + mPreviewSettingChanged(false), + mOnFloaterCommitCallback(NULL), + mOnFloaterCloseCallback(NULL), + mSetImageAssetIDCallback(NULL), + mOnUpdateImageStatsCallback(NULL), + mBakeTextureEnabled(FALSE), mInventoryPickType(pick_type) { - mCanApplyImmediately = can_apply_immediately; - buildFromFile("floater_texture_ctrl.xml"); - setCanMinimize(FALSE); + mCanApplyImmediately = can_apply_immediately; + buildFromFile("floater_texture_ctrl.xml"); + setCanMinimize(FALSE); } LLFloaterTexturePicker::~LLFloaterTexturePicker() @@ -198,27 +198,27 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker() void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/) { - if( ((mImageAssetID != image_id) || mTentative) && mActive) - { - mNoCopyTextureSelected = FALSE; - mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - mImageAssetID = image_id; - - if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) - { - if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2) - { - mModeSelector->selectByValue(2); - onModeSelect(0,this); - } - } - else - { - if (mModeSelector->getValue().asInteger() == 2) - { - mModeSelector->selectByValue(0); - onModeSelect(0,this); - } + if( ((mImageAssetID != image_id) || mTentative) && mActive) + { + mNoCopyTextureSelected = FALSE; + mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + mImageAssetID = image_id; + + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2) + { + mModeSelector->selectByValue(2); + onModeSelect(0,this); + } + } + else + { + if (mModeSelector->getValue().asInteger() == 2) + { + mModeSelector->selectByValue(0); + onModeSelect(0,this); + } LLUUID item_id; LLFolderView* root_folder = mInventoryPanel->getRootFolder(); @@ -244,27 +244,27 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti { item_id = findItemID(mImageAssetID, FALSE); } - if (item_id.isNull()) - { - mInventoryPanel->getRootFolder()->clearSelection(); - } - else - { - LLInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) - { - // no copy texture - getChild("apply_immediate_check")->setValue(FALSE); - mNoCopyTextureSelected = TRUE; - } - } - - if (set_selection) - { - mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); - } - } - } + if (item_id.isNull()) + { + mInventoryPanel->getRootFolder()->clearSelection(); + } + else + { + LLInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + // no copy texture + getChild("apply_immediate_check")->setValue(FALSE); + mNoCopyTextureSelected = TRUE; + } + } + + if (set_selection) + { + mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); + } + } + } } void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection) @@ -278,18 +278,18 @@ void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bo setImageID(asset_id, set_selection); } -void LLFloaterTexturePicker::setActive( BOOL active ) +void LLFloaterTexturePicker::setActive( BOOL active ) { - if (!active && getChild("Pipette")->getValue().asBoolean()) - { - stopUsingPipette(); - } - mActive = active; + if (!active && getChild("Pipette")->getValue().asBoolean()) + { + stopUsingPipette(); + } + mActive = active; } void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b) { - mCanApplyImmediately = b; + mCanApplyImmediately = b; LLUICtrl *apply_checkbox = getChild("apply_immediate_check"); apply_checkbox->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")); @@ -298,10 +298,10 @@ void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b) void LLFloaterTexturePicker::stopUsingPipette() { - if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()) - { - LLToolMgr::getInstance()->clearTransientTool(); - } + if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()) + { + LLToolMgr::getInstance()->clearTransientTool(); + } } bool LLFloaterTexturePicker::updateImageStats() @@ -359,13 +359,13 @@ bool LLFloaterTexturePicker::updateImageStats() mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("")); } } - else if (mTexturep.notNull()) - { - //RN: have we received header data for this image? + else if (mTexturep.notNull()) + { + //RN: have we received header data for this image? S32 width = mTexturep->getFullWidth(); S32 height = mTexturep->getFullHeight(); - if (width > 0 && height > 0) - { + if (width > 0 && height > 0) + { if ((mLimitsSet && (width != height)) || width < mMinDim || width > mMaxDim @@ -387,16 +387,16 @@ bool LLFloaterTexturePicker::updateImageStats() { mOnUpdateImageStatsCallback(mTexturep); } - } - else - { - mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]")); - } - } - else - { - mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("")); - } + } + else + { + mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]")); + } + } + else + { + mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("")); + } mResolutionLabel->setVisible(result); mResolutionWarning->setVisible(!result); @@ -415,16 +415,16 @@ bool LLFloaterTexturePicker::updateImageStats() } // virtual -BOOL LLFloaterTexturePicker::handleDragAndDrop( - S32 x, S32 y, MASK mask, - BOOL drop, - EDragAndDropType cargo_type, void *cargo_data, - EAcceptance *accept, - std::string& tooltip_msg) +BOOL LLFloaterTexturePicker::handleDragAndDrop( + S32 x, S32 y, MASK mask, + BOOL drop, + EDragAndDropType cargo_type, void *cargo_data, + EAcceptance *accept, + std::string& tooltip_msg) { - BOOL handled = FALSE; + BOOL handled = FALSE; - bool is_mesh = cargo_type == DAD_MESH; + bool is_mesh = cargo_type == DAD_MESH; bool is_texture = cargo_type == DAD_TEXTURE; bool is_material = cargo_type == DAD_MATERIAL; @@ -442,83 +442,83 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( allow_dnd = is_texture || is_mesh || is_material; } - if (allow_dnd) - { - LLInventoryItem *item = (LLInventoryItem *)cargo_data; - - BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); - BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); - BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID()); - - PermissionMask item_perm_mask = 0; - if (copy) item_perm_mask |= PERM_COPY; - if (mod) item_perm_mask |= PERM_MODIFY; - if (xfer) item_perm_mask |= PERM_TRANSFER; - - PermissionMask filter_perm_mask = mDnDFilterPermMask; - if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) - { - if (drop) - { + if (allow_dnd) + { + LLInventoryItem *item = (LLInventoryItem *)cargo_data; + + BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); + BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); + BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID()); + + PermissionMask item_perm_mask = 0; + if (copy) item_perm_mask |= PERM_COPY; + if (mod) item_perm_mask |= PERM_MODIFY; + if (xfer) item_perm_mask |= PERM_TRANSFER; + + PermissionMask filter_perm_mask = mDnDFilterPermMask; + if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) + { + if (drop) + { setImageIDFromItem(item); - commitIfImmediateSet(); - } + commitIfImmediateSet(); + } - *accept = ACCEPT_YES_SINGLE; - } - else - { - *accept = ACCEPT_NO; - } - } - else - { - *accept = ACCEPT_NO; - } + *accept = ACCEPT_YES_SINGLE; + } + else + { + *accept = ACCEPT_NO; + } + } + else + { + *accept = ACCEPT_NO; + } - handled = TRUE; - LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << LL_ENDL; + handled = TRUE; + LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << LL_ENDL; - return handled; + return handled; } BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) { - LLFolderView* root_folder = mInventoryPanel->getRootFolder(); - - if (root_folder && mFilterEdit) - { - if (mFilterEdit->hasFocus() - && (key == KEY_RETURN || key == KEY_DOWN) - && mask == MASK_NONE) - { - if (!root_folder->getCurSelectedItem()) - { - LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID()); - if (itemp) - { - root_folder->setSelection(itemp, FALSE, FALSE); - } - } - root_folder->scrollToShowSelection(); - - // move focus to inventory proper - mInventoryPanel->setFocus(TRUE); - - // treat this as a user selection of the first filtered result - commitIfImmediateSet(); - - return TRUE; - } - - if (mInventoryPanel->hasFocus() && key == KEY_UP) - { - mFilterEdit->focusFirstItem(TRUE); - } - } - - return LLFloater::handleKeyHere(key, mask); + LLFolderView* root_folder = mInventoryPanel->getRootFolder(); + + if (root_folder && mFilterEdit) + { + if (mFilterEdit->hasFocus() + && (key == KEY_RETURN || key == KEY_DOWN) + && mask == MASK_NONE) + { + if (!root_folder->getCurSelectedItem()) + { + LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID()); + if (itemp) + { + root_folder->setSelection(itemp, FALSE, FALSE); + } + } + root_folder->scrollToShowSelection(); + + // move focus to inventory proper + mInventoryPanel->setFocus(TRUE); + + // treat this as a user selection of the first filtered result + commitIfImmediateSet(); + + return TRUE; + } + + if (mInventoryPanel->hasFocus() && key == KEY_UP) + { + mFilterEdit->focusFirstItem(TRUE); + } + } + + return LLFloater::handleKeyHere(key, mask); } void LLFloaterTexturePicker::onOpen(const LLSD& key) @@ -532,11 +532,11 @@ void LLFloaterTexturePicker::onOpen(const LLSD& key) void LLFloaterTexturePicker::onClose(bool app_quitting) { - if (mOwner && mOnFloaterCloseCallback) - { - mOnFloaterCloseCallback(); - } - stopUsingPipette(); + if (mOwner && mOnFloaterCloseCallback) + { + mOnFloaterCloseCallback(); + } + stopUsingPipette(); sLastPickerMode = mModeSelector->getValue().asInteger(); // *NOTE: Vertex buffer for sphere preview is still cached mGLTFPreview = nullptr; @@ -545,17 +545,17 @@ void LLFloaterTexturePicker::onClose(bool app_quitting) // virtual BOOL LLFloaterTexturePicker::postBuild() { - LLFloater::postBuild(); + LLFloater::postBuild(); - if (!mLabel.empty()) - { - std::string pick = getString("pick title"); - - setTitle(pick + mLabel); - } - mTentativeLabel = getChild("Multiple"); + if (!mLabel.empty()) + { + std::string pick = getString("pick title"); - mResolutionLabel = getChild("size_lbl"); + setTitle(pick + mLabel); + } + mTentativeLabel = getChild("Multiple"); + + mResolutionLabel = getChild("size_lbl"); mResolutionWarning = getChild("over_limit_lbl"); @@ -576,70 +576,70 @@ BOOL LLFloaterTexturePicker::postBuild() mFilterEdit = getChild("inventory search editor"); mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2)); - mInventoryPanel = getChild("inventory panel"); + mInventoryPanel = getChild("inventory panel"); - mModeSelector = getChild("mode_selection"); - mModeSelector->setCommitCallback(onModeSelect, this); - mModeSelector->selectByValue(0); + mModeSelector = getChild("mode_selection"); + mModeSelector->setCommitCallback(onModeSelect, this); + mModeSelector->selectByValue(0); - if(mInventoryPanel) - { + if(mInventoryPanel) + { // to avoid having to make an assumption about which option is // selected at startup, we call the same function that is triggered // when a texture/materials/both choice is made and let it take care // of setting the filters refreshInventoryFilter(); - mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); - mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); - mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); + mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); + mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - // Disable auto selecting first filtered item because it takes away - // selection from the item set by LLTextureCtrl owning this floater. - mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE); + // Disable auto selecting first filtered item because it takes away + // selection from the item set by LLTextureCtrl owning this floater. + mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE); - // Commented out to scroll to currently selected texture. See EXT-5403. - // // store this filter as the default one - // mInventoryPanel->getRootFolder()->getFilter().markDefault(); + // Commented out to scroll to currently selected texture. See EXT-5403. + // // store this filter as the default one + // mInventoryPanel->getRootFolder()->getFilter().markDefault(); - // Commented out to stop opening all folders with textures - // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE); + // Commented out to stop opening all folders with textures + // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE); - // don't put keyboard focus on selected item, because the selection callback - // will assume that this was user input + // don't put keyboard focus on selected item, because the selection callback + // will assume that this was user input - if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL) - { - mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); - } - } + if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL) + { + mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); + } + } - childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); - childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this); - childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this); + childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this); - mLocalScrollCtrl = getChild("l_name_list"); - mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this); + mLocalScrollCtrl = getChild("l_name_list"); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this); refreshLocalList(); - mNoCopyTextureSelected = FALSE; + mNoCopyTextureSelected = FALSE; - getChild("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")); - childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); + getChild("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")); + childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately); - getChild("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); - childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); - childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); + getChild("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); + childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); + childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); + + mSavedFolderState.setApply(FALSE); - mSavedFolderState.setApply(FALSE); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); - LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); - - getChild("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); + getChild("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); - setBakeTextureEnabled(TRUE); - return TRUE; + setBakeTextureEnabled(TRUE); + return TRUE; } // virtual @@ -650,18 +650,18 @@ void LLFloaterTexturePicker::draw() // This is going to spam mOnUpdateImageStatsCallback, // either move elsewhere or fix to cause update once per image - bool valid_dims = updateImageStats(); + bool valid_dims = updateImageStats(); - // if we're inactive, gray out "apply immediate" checkbox - getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); - mSelectBtn->setEnabled(mActive && mCanApply && valid_dims); - mPipetteBtn->setEnabled(mActive); + // if we're inactive, gray out "apply immediate" checkbox + getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); + mSelectBtn->setEnabled(mActive && mCanApply && valid_dims); + mPipetteBtn->setEnabled(mActive); mPipetteBtn->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); - //BOOL allow_copy = FALSE; - if( mOwner ) - { - mTexturep = NULL; + //BOOL allow_copy = FALSE; + if( mOwner ) + { + mTexturep = NULL; LLPointer old_material = mGLTFMaterial; mGLTFMaterial = NULL; if (mImageAssetID.notNull()) @@ -700,7 +700,7 @@ void LLFloaterTexturePicker::draw() if (obj) { LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); - texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; } } @@ -714,33 +714,33 @@ void LLFloaterTexturePicker::draw() } } - if (mTentativeLabel) - { - mTentativeLabel->setVisible( FALSE ); - } + if (mTentativeLabel) + { + mTentativeLabel->setVisible( FALSE ); + } - mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); - mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative); - mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); + mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); + mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative); + mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); - LLFloater::draw(); + LLFloater::draw(); - if( isMinimized() ) - { - return; - } + if( isMinimized() ) + { + return; + } - // Border - LLRect border = getChildView("preview_widget")->getRect(); - gl_rect_2d( border, LLColor4::black, FALSE ); + // Border + LLRect border = getChildView("preview_widget")->getRect(); + gl_rect_2d( border, LLColor4::black, FALSE ); - // Interior - LLRect interior = border; - interior.stretch( -1 ); + // Interior + LLRect interior = border; + interior.stretch( -1 ); - // If the floater is focused, don't apply its alpha to the texture (STORM-677). - const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + // If the floater is focused, don't apply its alpha to the texture (STORM-677). + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); LLViewerTexture* preview; if (mGLTFMaterial) { @@ -751,66 +751,66 @@ void LLFloaterTexturePicker::draw() preview = mTexturep.get(); } - if( preview ) - { + if( preview ) + { preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); - if( preview->getComponents() == 4 ) - { - gl_rect_2d_checkerboard( interior, alpha ); - } - - gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha ); - } - else if (!mFallbackImage.isNull()) - { - mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha); - } - else - { - gl_rect_2d( interior, LLColor4::grey % alpha, TRUE ); - - // Draw X - gl_draw_x(interior, LLColor4::black ); - } - - // Draw Tentative Label over the image - if( mTentative && !mViewModel->isDirty() ) - { - mTentativeLabel->setVisible( TRUE ); - drawChild(mTentativeLabel); - } - - if (mSelectedItemPinned) return; - - LLFolderView* folder_view = mInventoryPanel->getRootFolder(); - if (!folder_view) return; - - LLFolderViewFilter& filter = static_cast(folder_view->getFolderViewModel())->getFilter(); - - bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() && - filter.isNotDefault(); - - // After inventory panel filter is applied we have to update - // constraint rect for the selected item because of folder view - // AutoSelectOverride set to TRUE. We force PinningSelectedItem - // flag to FALSE state and setting filter "dirty" to update - // scroll container to show selected item (see LLFolderView::doIdle()). - if (!is_filter_active && !mSelectedItemPinned) - { - folder_view->setPinningSelectedItem(mSelectedItemPinned); - folder_view->getViewModelItem()->dirtyFilter(); - mSelectedItemPinned = TRUE; - } - } + if( preview->getComponents() == 4 ) + { + gl_rect_2d_checkerboard( interior, alpha ); + } + + gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha ); + } + else if (!mFallbackImage.isNull()) + { + mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha); + } + else + { + gl_rect_2d( interior, LLColor4::grey % alpha, TRUE ); + + // Draw X + gl_draw_x(interior, LLColor4::black ); + } + + // Draw Tentative Label over the image + if( mTentative && !mViewModel->isDirty() ) + { + mTentativeLabel->setVisible( TRUE ); + drawChild(mTentativeLabel); + } + + if (mSelectedItemPinned) return; + + LLFolderView* folder_view = mInventoryPanel->getRootFolder(); + if (!folder_view) return; + + LLFolderViewFilter& filter = static_cast(folder_view->getFolderViewModel())->getFilter(); + + bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() && + filter.isNotDefault(); + + // After inventory panel filter is applied we have to update + // constraint rect for the selected item because of folder view + // AutoSelectOverride set to TRUE. We force PinningSelectedItem + // flag to FALSE state and setting filter "dirty" to update + // scroll container to show selected item (see LLFolderView::doIdle()). + if (!is_filter_active && !mSelectedItemPinned) + { + folder_view->setPinningSelectedItem(mSelectedItemPinned); + folder_view->getViewModelItem()->dirtyFilter(); + mSelectedItemPinned = TRUE; + } + } } const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library) { - if (asset_id.isNull()) - { + if (asset_id.isNull()) + { // null asset id means, no material or texture assigned return LLUUID::null; - } + } LLUUID loockup_id = asset_id; if (mInventoryPickType == PICK_MATERIAL && loockup_id == BLANK_MATERIAL_ASSET_ID) @@ -819,8 +819,8 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co loockup_id = LLUUID::null; } - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; if (loockup_id.isNull()) { @@ -844,44 +844,44 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co } - if (items.size()) - { - // search for copyable version first - for (S32 i = 0; i < items.size(); i++) - { - LLInventoryItem* itemp = items[i]; - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) - { - if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID())) - { - return itemp->getUUID(); - } - } - } - // otherwise just return first instance, unless copyable requested - if (copyable_only) - { - return LLUUID::null; - } - else - { - if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID())) - { - return items[0]->getUUID(); - } - } - } - - return LLUUID::null; + if (items.size()) + { + // search for copyable version first + for (S32 i = 0; i < items.size(); i++) + { + LLInventoryItem* itemp = items[i]; + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) + { + if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID())) + { + return itemp->getUUID(); + } + } + } + // otherwise just return first instance, unless copyable requested + if (copyable_only) + { + return LLUUID::null; + } + else + { + if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID())) + { + return items[0]->getUUID(); + } + } + } + + return LLUUID::null; } void LLFloaterTexturePicker::commitIfImmediateSet() { - if (!mNoCopyTextureSelected && mCanApply) - { + if (!mNoCopyTextureSelected && mCanApply) + { commitCallback(LLTextureCtrl::TEXTURE_CHANGE); - } + } } void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) @@ -963,40 +963,40 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) } void LLFloaterTexturePicker::commitCancel() { - if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply) - { - mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null); - } + if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply) + { + mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null); + } } // static void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - self->setCanApply(true, true); - if (self->mOwner) - { - self->setImageID( self->getDefaultImageAssetID() ); - } - self->commitIfImmediateSet(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); + if (self->mOwner) + { + self->setImageID( self->getDefaultImageAssetID() ); + } + self->commitIfImmediateSet(); } // static void LLFloaterTexturePicker::onBtnBlank(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - self->setCanApply(true, true); - self->setImageID( self->getBlankImageAssetID() ); - self->commitIfImmediateSet(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); + self->setImageID( self->getBlankImageAssetID() ); + self->commitIfImmediateSet(); } // static void LLFloaterTexturePicker::onBtnNone(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setCanApply(true, true); - self->setImageID( LLUUID::null ); + self->setImageID( LLUUID::null ); self->commitIfImmediateSet(); } @@ -1004,88 +1004,88 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata) // static void LLFloaterTexturePicker::onBtnRevert(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - self->setImageID( self->mOriginalImageAssetID ); - // TODO: Change this to tell the owner to cancel. It needs to be - // smart enough to restore multi-texture selections. - self->mOwner->onFloaterCommit(); - self->mViewModel->resetDirty(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setImageID( self->mOriginalImageAssetID ); + // TODO: Change this to tell the owner to cancel. It needs to be + // smart enough to restore multi-texture selections. + self->mOwner->onFloaterCommit(); + self->mViewModel->resetDirty(); }*/ // static void LLFloaterTexturePicker::onBtnCancel(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - self->setImageID( self->mOriginalImageAssetID ); - if (self->mOnFloaterCommitCallback) - { - self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null); - } - self->mViewModel->resetDirty(); - self->closeFloater(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setImageID( self->mOriginalImageAssetID ); + if (self->mOnFloaterCommitCallback) + { + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null); + } + self->mViewModel->resetDirty(); + self->closeFloater(); } // static void LLFloaterTexturePicker::onBtnSelect(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - if (self->mOnFloaterCommitCallback) - { - self->commitCallback(LLTextureCtrl::TEXTURE_SELECT); - } - self->closeFloater(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + if (self->mOnFloaterCommitCallback) + { + self->commitCallback(LLTextureCtrl::TEXTURE_SELECT); + } + self->closeFloater(); } void LLFloaterTexturePicker::onBtnPipette() { - BOOL pipette_active = getChild("Pipette")->getValue().asBoolean(); - pipette_active = !pipette_active; - if (pipette_active) - { - LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); - } - else - { - LLToolMgr::getInstance()->clearTransientTool(); - } + BOOL pipette_active = getChild("Pipette")->getValue().asBoolean(); + pipette_active = !pipette_active; + if (pipette_active) + { + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); + } + else + { + LLToolMgr::getInstance()->clearTransientTool(); + } } void LLFloaterTexturePicker::onSelectionChange(const std::deque &items, BOOL user_action) { - if (items.size()) - { - LLFolderViewItem* first_item = items.front(); - LLInventoryItem* itemp = gInventory.getItem(static_cast(first_item->getViewModelItem())->getUUID()); - mNoCopyTextureSelected = FALSE; - if (itemp) - { - if (!mTextureSelectedCallback.empty()) - { - mTextureSelectedCallback(itemp); - } - if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) - { - mNoCopyTextureSelected = TRUE; - } + if (items.size()) + { + LLFolderViewItem* first_item = items.front(); + LLInventoryItem* itemp = gInventory.getItem(static_cast(first_item->getViewModelItem())->getUUID()); + mNoCopyTextureSelected = FALSE; + if (itemp) + { + if (!mTextureSelectedCallback.empty()) + { + mTextureSelectedCallback(itemp); + } + if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + mNoCopyTextureSelected = TRUE; + } setImageIDFromItem(itemp, false); - mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - - if(!mPreviewSettingChanged) - { - mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"); - } - else - { - mPreviewSettingChanged = false; - } - - if (user_action && mCanPreview) - { - // only commit intentional selections, not implicit ones - commitIfImmediateSet(); - } - } - } + mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + if(!mPreviewSettingChanged) + { + mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"); + } + else + { + mPreviewSettingChanged = false; + } + + if (user_action && mCanPreview) + { + // only commit intentional selections, not implicit ones + commitIfImmediateSet(); + } + } + } } // static @@ -1117,18 +1117,18 @@ void LLFloaterTexturePicker::onBtnAdd(void* userdata) // static void LLFloaterTexturePicker::onBtnRemove(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); - if (!selected_items.empty()) - { + if (!selected_items.empty()) + { - for(std::vector::iterator iter = selected_items.begin(); - iter != selected_items.end(); iter++) - { - LLScrollListItem* list_item = *iter; - if (list_item) - { + for(std::vector::iterator iter = selected_items.begin(); + iter != selected_items.end(); iter++) + { + LLScrollListItem* list_item = *iter; + if (list_item) + { LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue(); LLUUID tracking_id = data["id"]; S32 asset_type = data["type"].asInteger(); @@ -1141,28 +1141,28 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata) { LLLocalBitmapMgr::getInstance()->delUnit(tracking_id); } - } - } + } + } - self->getChild("l_rem_btn")->setEnabled(false); - self->getChild("l_upl_btn")->setEnabled(false); + self->getChild("l_rem_btn")->setEnabled(false); + self->getChild("l_upl_btn")->setEnabled(false); self->refreshLocalList(); - } + } } // static void LLFloaterTexturePicker::onBtnUpload(void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); - if (selected_items.empty()) - { - return; - } + if (selected_items.empty()) + { + return; + } - /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!) - in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */ + /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!) + in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue(); LLUUID tracking_id = data["id"]; @@ -1191,16 +1191,16 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata) //static void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); - bool has_selection = !selected_items.empty(); + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + std::vector selected_items = self->mLocalScrollCtrl->getAllSelected(); + bool has_selection = !selected_items.empty(); - self->getChild("l_rem_btn")->setEnabled(has_selection); - self->getChild("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2)); - /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */ + self->getChild("l_rem_btn")->setEnabled(has_selection); + self->getChild("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2)); + /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */ - if (has_selection) - { + if (has_selection) + { LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue(); LLUUID tracking_id = data["id"]; S32 asset_type = data["type"].asInteger(); @@ -1215,114 +1215,114 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); } - if (self->mSetImageAssetIDCallback) - { - self->mSetImageAssetIDCallback(inworld_id); - } + if (self->mSetImageAssetIDCallback) + { + self->mSetImageAssetIDCallback(inworld_id); + } - if (self->childGetValue("apply_immediate_check").asBoolean()) - { - if (self->mOnFloaterCommitCallback) - { - self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id); - } - } - } + if (self->childGetValue("apply_immediate_check").asBoolean()) + { + if (self->mOnFloaterCommitCallback) + { + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id); + } + } + } } // static void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data) { - LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data; + LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data; - LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; - gSavedSettings.setBOOL("TextureLivePreview", check_box->get()); + LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; + gSavedSettings.setBOOL("TextureLivePreview", check_box->get()); - picker->commitIfImmediateSet(); + picker->commitIfImmediateSet(); } //static void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data; - LLComboBox* combo_box = (LLComboBox*)ctrl; - - S8 type = combo_box->getValue().asInteger(); - - LLUUID imageID = self->mDefaultImageAssetID; - if (type == 0) - { - imageID = IMG_USE_BAKED_HEAD; - } - else if (type == 1) - { - imageID = IMG_USE_BAKED_UPPER; - } - else if (type == 2) - { - imageID = IMG_USE_BAKED_LOWER; - } - else if (type == 3) - { - imageID = IMG_USE_BAKED_EYES; - } - else if (type == 4) - { - imageID = IMG_USE_BAKED_SKIRT; - } - else if (type == 5) - { - imageID = IMG_USE_BAKED_HAIR; - } - else if (type == 6) - { - imageID = IMG_USE_BAKED_LEFTARM; - } - else if (type == 7) - { - imageID = IMG_USE_BAKED_LEFTLEG; - } - else if (type == 8) - { - imageID = IMG_USE_BAKED_AUX1; - } - else if (type == 9) - { - imageID = IMG_USE_BAKED_AUX2; - } - else if (type == 10) - { - imageID = IMG_USE_BAKED_AUX3; - } - - self->setImageID(imageID); - self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - - if (!self->mPreviewSettingChanged) - { - self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"); - } - else - { - self->mPreviewSettingChanged = false; - } - - if (self->mCanPreview) - { - // only commit intentional selections, not implicit ones - self->commitIfImmediateSet(); - } + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data; + LLComboBox* combo_box = (LLComboBox*)ctrl; + + S8 type = combo_box->getValue().asInteger(); + + LLUUID imageID = self->mDefaultImageAssetID; + if (type == 0) + { + imageID = IMG_USE_BAKED_HEAD; + } + else if (type == 1) + { + imageID = IMG_USE_BAKED_UPPER; + } + else if (type == 2) + { + imageID = IMG_USE_BAKED_LOWER; + } + else if (type == 3) + { + imageID = IMG_USE_BAKED_EYES; + } + else if (type == 4) + { + imageID = IMG_USE_BAKED_SKIRT; + } + else if (type == 5) + { + imageID = IMG_USE_BAKED_HAIR; + } + else if (type == 6) + { + imageID = IMG_USE_BAKED_LEFTARM; + } + else if (type == 7) + { + imageID = IMG_USE_BAKED_LEFTLEG; + } + else if (type == 8) + { + imageID = IMG_USE_BAKED_AUX1; + } + else if (type == 9) + { + imageID = IMG_USE_BAKED_AUX2; + } + else if (type == 10) + { + imageID = IMG_USE_BAKED_AUX3; + } + + self->setImageID(imageID); + self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + if (!self->mPreviewSettingChanged) + { + self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"); + } + else + { + self->mPreviewSettingChanged = false; + } + + if (self->mCanPreview) + { + // only commit intentional selections, not implicit ones + self->commitIfImmediateSet(); + } } void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool inworld_image) { - mSelectBtn->setEnabled(can_apply); - getChildRef("preview_disabled").setVisible(!can_preview && inworld_image); - getChildRef("apply_immediate_check").setVisible(can_preview); + mSelectBtn->setEnabled(can_apply); + getChildRef("preview_disabled").setVisible(!can_preview && inworld_image); + getChildRef("apply_immediate_check").setVisible(can_preview); - mCanApply = can_apply; - mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false; - mPreviewSettingChanged = true; + mCanApply = can_apply; + mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false; + mPreviewSettingChanged = true; } void LLFloaterTexturePicker::setMinDimentionsLimits(S32 min_dim) @@ -1336,36 +1336,36 @@ void LLFloaterTexturePicker::setMinDimentionsLimits(S32 min_dim) void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) { - std::string upper_case_search_string = search_string; - LLStringUtil::toUpper(upper_case_search_string); - - if (upper_case_search_string.empty()) - { - if (mInventoryPanel->getFilterSubString().empty()) - { - // current filter and new filter empty, do nothing - return; - } - - mSavedFolderState.setApply(TRUE); - mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); - // add folder with current item to list of previously opened folders - LLOpenFoldersWithSelection opener; - mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener); - mInventoryPanel->getRootFolder()->scrollToShowSelection(); - - } - else if (mInventoryPanel->getFilterSubString().empty()) - { - // first letter in search term, save existing folder open state - if (!mInventoryPanel->getFilter().isNotDefault()) - { - mSavedFolderState.setApply(FALSE); - mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); - } - } - - mInventoryPanel->setFilterSubString(search_string); + std::string upper_case_search_string = search_string; + LLStringUtil::toUpper(upper_case_search_string); + + if (upper_case_search_string.empty()) + { + if (mInventoryPanel->getFilterSubString().empty()) + { + // current filter and new filter empty, do nothing + return; + } + + mSavedFolderState.setApply(TRUE); + mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + // add folder with current item to list of previously opened folders + LLOpenFoldersWithSelection opener; + mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener); + mInventoryPanel->getRootFolder()->scrollToShowSelection(); + + } + else if (mInventoryPanel->getFilterSubString().empty()) + { + // first letter in search term, save existing folder open state + if (!mInventoryPanel->getFilter().isNotDefault()) + { + mSavedFolderState.setApply(FALSE); + mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + } + } + + mInventoryPanel->setFilterSubString(search_string); } void LLFloaterTexturePicker::changeMode() @@ -1495,24 +1495,24 @@ void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) { - BOOL changed = (enabled != mBakeTextureEnabled); + BOOL changed = (enabled != mBakeTextureEnabled); + + mBakeTextureEnabled = enabled; + mModeSelector->setEnabledByValue(2, enabled); - mBakeTextureEnabled = enabled; - mModeSelector->setEnabledByValue(2, enabled); + if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2)) + { + mModeSelector->selectByValue(0); + } - if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2)) - { - mModeSelector->selectByValue(0); - } - - if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) - { - if (mModeSelector->getValue().asInteger() != 2) - { - mModeSelector->selectByValue(2); - } - } - onModeSelect(0, this); + if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + if (mModeSelector->getValue().asInteger() != 2) + { + mModeSelector->selectByValue(2); + } + } + onModeSelect(0, this); } void LLFloaterTexturePicker::setInventoryPickType(EPickInventoryType type) @@ -1603,10 +1603,10 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector& fi void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { - LLUUID inventory_item_id = findItemID(te.getID(), TRUE); - if (inventory_item_id.notNull()) - { - LLToolPipette::getInstance()->setResult(TRUE, ""); + LLUUID inventory_item_id = findItemID(te.getID(), TRUE); + if (inventory_item_id.notNull()) + { + LLToolPipette::getInstance()->setResult(TRUE, ""); if (mInventoryPickType == PICK_MATERIAL) { // tes have no data about material ids @@ -1619,21 +1619,21 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) setImageID(te.getID()); } - mNoCopyTextureSelected = FALSE; - LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); + mNoCopyTextureSelected = FALSE; + LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); - if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) - { - // no copy texture - mNoCopyTextureSelected = TRUE; - } - - commitIfImmediateSet(); - } - else - { - LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture")); - } + if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + // no copy texture + mNoCopyTextureSelected = TRUE; + } + + commitIfImmediateSet(); + } + else + { + LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture")); + } } /////////////////////////////////////////////////////////////////////// @@ -1642,107 +1642,107 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) static LLDefaultChildRegistry::Register r("texture_picker"); LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) -: LLUICtrl(p), - mDragCallback(NULL), - mDropCallback(NULL), - mOnCancelCallback(NULL), - mOnCloseCallback(NULL), - mOnSelectCallback(NULL), - mBorderColor( p.border_color() ), - mAllowNoTexture( p.allow_no_texture ), - mAllowLocalTexture( TRUE ), - mImmediateFilterPermMask( PERM_NONE ), - mCanApplyImmediately( FALSE ), - mNeedsRawImageData( FALSE ), - mValid( TRUE ), - mShowLoadingPlaceholder( TRUE ), - mOpenTexPreview(false), +: LLUICtrl(p), + mDragCallback(NULL), + mDropCallback(NULL), + mOnCancelCallback(NULL), + mOnCloseCallback(NULL), + mOnSelectCallback(NULL), + mBorderColor( p.border_color() ), + mAllowNoTexture( p.allow_no_texture ), + mAllowLocalTexture( TRUE ), + mImmediateFilterPermMask( PERM_NONE ), + mCanApplyImmediately( FALSE ), + mNeedsRawImageData( FALSE ), + mValid( TRUE ), + mShowLoadingPlaceholder( TRUE ), + mOpenTexPreview(false), mBakeTextureEnabled(true), mInventoryPickType(p.pick_type), - mImageAssetID(p.image_id), - mDefaultImageAssetID(p.default_image_id), - mDefaultImageName(p.default_image_name), - mFallbackImage(p.fallback_image) -{ - - // Default of defaults is white image for diff tex - // - setBlankImageAssetID(IMG_WHITE); - - setAllowNoTexture(p.allow_no_texture); - setCanApplyImmediately(p.can_apply_immediately); - mCommitOnSelection = !p.no_commit_on_selection; - - LLTextBox::Params params(p.caption_text); - params.name(p.label); - params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 )); - params.initial_value(p.label()); - params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); - mCaption = LLUICtrlFactory::create (params); - addChild( mCaption ); - - S32 image_top = getRect().getHeight(); - S32 image_bottom = BTN_HEIGHT_SMALL; - S32 image_middle = (image_top + image_bottom) / 2; - S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight(); - - LLTextBox::Params tentative_label_p(p.multiselect_text); - tentative_label_p.name("Multiple"); - tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 )); - tentative_label_p.follows.flags(FOLLOWS_ALL); - mTentativeLabel = LLUICtrlFactory::create (tentative_label_p); - - // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion - LLStyle::Params style_params; - style_params.color = LLColor4::white; - - mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params); - mTentativeLabel->setHAlign(LLFontGL::HCENTER); - addChild( mTentativeLabel ); - - LLRect border_rect = getLocalRect(); - border_rect.mBottom += BTN_HEIGHT_SMALL; - LLViewBorder::Params vbparams(p.border); - vbparams.name("border"); - vbparams.rect(border_rect); - mBorder = LLUICtrlFactory::create (vbparams); - addChild(mBorder); - - mLoadingPlaceholderString = LLTrans::getString("texture_loading"); + mImageAssetID(p.image_id), + mDefaultImageAssetID(p.default_image_id), + mDefaultImageName(p.default_image_name), + mFallbackImage(p.fallback_image) +{ + + // Default of defaults is white image for diff tex + // + setBlankImageAssetID(IMG_WHITE); + + setAllowNoTexture(p.allow_no_texture); + setCanApplyImmediately(p.can_apply_immediately); + mCommitOnSelection = !p.no_commit_on_selection; + + LLTextBox::Params params(p.caption_text); + params.name(p.label); + params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 )); + params.initial_value(p.label()); + params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); + mCaption = LLUICtrlFactory::create (params); + addChild( mCaption ); + + S32 image_top = getRect().getHeight(); + S32 image_bottom = BTN_HEIGHT_SMALL; + S32 image_middle = (image_top + image_bottom) / 2; + S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight(); + + LLTextBox::Params tentative_label_p(p.multiselect_text); + tentative_label_p.name("Multiple"); + tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 )); + tentative_label_p.follows.flags(FOLLOWS_ALL); + mTentativeLabel = LLUICtrlFactory::create (tentative_label_p); + + // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion + LLStyle::Params style_params; + style_params.color = LLColor4::white; + + mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params); + mTentativeLabel->setHAlign(LLFontGL::HCENTER); + addChild( mTentativeLabel ); + + LLRect border_rect = getLocalRect(); + border_rect.mBottom += BTN_HEIGHT_SMALL; + LLViewBorder::Params vbparams(p.border); + vbparams.name("border"); + vbparams.rect(border_rect); + mBorder = LLUICtrlFactory::create (vbparams); + addChild(mBorder); + + mLoadingPlaceholderString = LLTrans::getString("texture_loading"); } LLTextureCtrl::~LLTextureCtrl() { - closeDependentFloater(); + closeDependentFloater(); } void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder) { - mShowLoadingPlaceholder = showLoadingPlaceholder; + mShowLoadingPlaceholder = showLoadingPlaceholder; } void LLTextureCtrl::setCaption(const std::string& caption) { - mCaption->setText( caption ); + mCaption->setText( caption ); } void LLTextureCtrl::setCanApplyImmediately(BOOL b) { - mCanApplyImmediately = b; - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if( floaterp ) - { - floaterp->setCanApplyImmediately(b); - } + mCanApplyImmediately = b; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if( floaterp ) + { + floaterp->setCanApplyImmediately(b); + } } void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply) { - LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); - if( floaterp ) - { - floaterp->setCanApply(can_preview, can_apply); - } + LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); + if( floaterp ) + { + floaterp->setCanApply(can_preview, can_apply); + } } void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask) @@ -1756,7 +1756,7 @@ void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask) } } -void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask) +void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask) { setImmediateFilterPermMask(mask); setDnDFilterPermMask(mask); @@ -1775,176 +1775,176 @@ void LLTextureCtrl::onVisibilityChange(BOOL new_visibility) } } -void LLTextureCtrl::setVisible( BOOL visible ) +void LLTextureCtrl::setVisible( BOOL visible ) { - if( !visible ) - { - closeDependentFloater(); - } - LLUICtrl::setVisible( visible ); + if( !visible ) + { + closeDependentFloater(); + } + LLUICtrl::setVisible( visible ); } void LLTextureCtrl::setEnabled( BOOL enabled ) { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if( floaterp ) - { - floaterp->setActive(enabled); - } - if( enabled ) - { - std::string tooltip; - if (floaterp) tooltip = floaterp->getString("choose_picture"); - setToolTip( tooltip ); - } - else - { - setToolTip( std::string() ); - // *TODO: would be better to keep floater open and show - // disabled state. - closeDependentFloater(); - } - - mCaption->setEnabled( enabled ); - - LLView::setEnabled( enabled ); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if( floaterp ) + { + floaterp->setActive(enabled); + } + if( enabled ) + { + std::string tooltip; + if (floaterp) tooltip = floaterp->getString("choose_picture"); + setToolTip( tooltip ); + } + else + { + setToolTip( std::string() ); + // *TODO: would be better to keep floater open and show + // disabled state. + closeDependentFloater(); + } + + mCaption->setEnabled( enabled ); + + LLView::setEnabled( enabled ); } void LLTextureCtrl::setValid(BOOL valid ) { - mValid = valid; - if (!valid) - { - LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if (pickerp) - { - pickerp->setActive(FALSE); - } - } + mValid = valid; + if (!valid) + { + LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if (pickerp) + { + pickerp->setActive(FALSE); + } + } } // virtual void LLTextureCtrl::clear() { - setImageAssetID(LLUUID::null); + setImageAssetID(LLUUID::null); } void LLTextureCtrl::setLabel(const std::string& label) { - mLabel = label; - mCaption->setText(label); + mLabel = label; + mCaption->setText(label); } void LLTextureCtrl::showPicker(BOOL take_focus) { - // show hourglass cursor when loading inventory window - // because inventory construction is slooow - getWindow()->setCursor(UI_CURSOR_WAIT); - LLFloater* floaterp = mFloaterHandle.get(); - - // Show the dialog - if( floaterp ) - { - floaterp->openFloater(); - } - else - { - floaterp = new LLFloaterTexturePicker( - this, - getImageAssetID(), - getDefaultImageAssetID(), - getBlankImageAssetID(), - getTentative(), - getAllowNoTexture(), - mLabel, - mImmediateFilterPermMask, - mDnDFilterPermMask, - mCanApplyImmediately, - mFallbackImage, - mInventoryPickType); - mFloaterHandle = floaterp->getHandle(); - - LLFloaterTexturePicker* texture_floaterp = dynamic_cast(floaterp); - if (texture_floaterp && mOnTextureSelectedCallback) - { - texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback); - } - if (texture_floaterp && mOnCloseCallback) - { - texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this)); - } - if (texture_floaterp) - { - texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5)); - } - if (texture_floaterp) - { - texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); - - texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); - } - - LLFloater* root_floater = gFloaterView->getParentFloater(this); - if (root_floater) - root_floater->addDependentFloater(floaterp); - floaterp->openFloater(); - } - - LLFloaterTexturePicker* picker_floater = dynamic_cast(floaterp); - if (picker_floater) - { - picker_floater->setLocalTextureEnabled(mAllowLocalTexture); - } - - if (take_focus) - { - floaterp->setFocus(TRUE); - } + // show hourglass cursor when loading inventory window + // because inventory construction is slooow + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloater* floaterp = mFloaterHandle.get(); + + // Show the dialog + if( floaterp ) + { + floaterp->openFloater(); + } + else + { + floaterp = new LLFloaterTexturePicker( + this, + getImageAssetID(), + getDefaultImageAssetID(), + getBlankImageAssetID(), + getTentative(), + getAllowNoTexture(), + mLabel, + mImmediateFilterPermMask, + mDnDFilterPermMask, + mCanApplyImmediately, + mFallbackImage, + mInventoryPickType); + mFloaterHandle = floaterp->getHandle(); + + LLFloaterTexturePicker* texture_floaterp = dynamic_cast(floaterp); + if (texture_floaterp && mOnTextureSelectedCallback) + { + texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback); + } + if (texture_floaterp && mOnCloseCallback) + { + texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this)); + } + if (texture_floaterp) + { + texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5)); + } + if (texture_floaterp) + { + texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); + + texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); + } + + LLFloater* root_floater = gFloaterView->getParentFloater(this); + if (root_floater) + root_floater->addDependentFloater(floaterp); + floaterp->openFloater(); + } + + LLFloaterTexturePicker* picker_floater = dynamic_cast(floaterp); + if (picker_floater) + { + picker_floater->setLocalTextureEnabled(mAllowLocalTexture); + } + + if (take_focus) + { + floaterp->setFocus(TRUE); + } } void LLTextureCtrl::closeDependentFloater() { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if( floaterp && floaterp->isInVisibleChain()) - { - floaterp->setOwner(NULL); - floaterp->setVisible(FALSE); - floaterp->closeFloater(); - } + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if( floaterp && floaterp->isInVisibleChain()) + { + floaterp->setOwner(NULL); + floaterp->setVisible(FALSE); + floaterp->closeFloater(); + } } // Allow us to download textures quickly when floater is shown class LLTextureFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver { public: - virtual void done() - { - // We need to find textures in all folders, so get the main - // background download going. - LLInventoryModelBackgroundFetch::instance().start(); - gInventory.removeObserver(this); - delete this; - } + virtual void done() + { + // We need to find textures in all folders, so get the main + // background download going. + LLInventoryModelBackgroundFetch::instance().start(); + gInventory.removeObserver(this); + delete this; + } }; BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask) { - getWindow()->setCursor(mBorder->parentPointInView(x,y) ? UI_CURSOR_HAND : UI_CURSOR_ARROW); - return TRUE; + getWindow()->setCursor(mBorder->parentPointInView(x,y) ? UI_CURSOR_HAND : UI_CURSOR_ARROW); + return TRUE; } BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) { - BOOL handled = LLUICtrl::handleMouseDown( x, y , mask ); + BOOL handled = LLUICtrl::handleMouseDown( x, y , mask ); - if (!handled && mBorder->parentPointInView(x, y)) - { - if (!mOpenTexPreview) - { - showPicker(FALSE); + if (!handled && mBorder->parentPointInView(x, y)) + { + if (!mOpenTexPreview) + { + showPicker(FALSE); if (mInventoryPickType == PICK_MATERIAL) { //grab materials first... @@ -1955,48 +1955,48 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) //grab textures first... LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE)); } - //...then start full inventory fetch. + //...then start full inventory fetch. if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted()) { LLInventoryModelBackgroundFetch::instance().start(); } - handled = TRUE; - } - else - { - if (getImageAssetID().notNull()) - { - LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance("preview_texture", getValue()); - if (preview_texture && !preview_texture->isDependent()) - { - LLFloater* root_floater = gFloaterView->getParentFloater(this); - if (root_floater) - { - root_floater->addDependentFloater(preview_texture); - preview_texture->hideCtrlButtons(); - } - } - } - } - } - - return handled; + handled = TRUE; + } + else + { + if (getImageAssetID().notNull()) + { + LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance("preview_texture", getValue()); + if (preview_texture && !preview_texture->isDependent()) + { + LLFloater* root_floater = gFloaterView->getParentFloater(this); + if (root_floater) + { + root_floater->addDependentFloater(preview_texture); + preview_texture->hideCtrlButtons(); + } + } + } + } + } + + return handled; } void LLTextureCtrl::onFloaterClose() { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if (floaterp) - { - if (mOnCloseCallback) - { - mOnCloseCallback(this,LLSD()); - } - floaterp->setOwner(NULL); - } + if (floaterp) + { + if (mOnCloseCallback) + { + mOnCloseCallback(this,LLSD()); + } + floaterp->setOwner(NULL); + } - mFloaterHandle.markDead(); + mFloaterHandle.markDead(); } void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id) @@ -2004,18 +2004,18 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( floaterp && getEnabled()) - { - if (op == TEXTURE_CANCEL) - mViewModel->resetDirty(); - // If the "no_commit_on_selection" parameter is set - // we get dirty only when user presses OK in the picker - // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. - else if (mCommitOnSelection || op == TEXTURE_SELECT) - mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - - if(floaterp->isDirty() || asset_id.notNull()) // mModelView->setDirty does not work. - { - setTentative( FALSE ); + { + if (op == TEXTURE_CANCEL) + mViewModel->resetDirty(); + // If the "no_commit_on_selection" parameter is set + // we get dirty only when user presses OK in the picker + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. + else if (mCommitOnSelection || op == TEXTURE_SELECT) + mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + if(floaterp->isDirty() || asset_id.notNull()) // mModelView->setDirty does not work. + { + setTentative( FALSE ); switch(source) { @@ -2044,76 +2044,76 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << ", mImageItemID: " << mImageItemID << LL_ENDL; - if (op == TEXTURE_SELECT && mOnSelectCallback) - { + if (op == TEXTURE_SELECT && mOnSelectCallback) + { mOnSelectCallback(this, LLSD()); - } - else if (op == TEXTURE_CANCEL && mOnCancelCallback) - { - mOnCancelCallback( this, LLSD() ); - } - else - { - // If the "no_commit_on_selection" parameter is set - // we commit only when user presses OK in the picker - // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. + } + else if (op == TEXTURE_CANCEL && mOnCancelCallback) + { + mOnCancelCallback( this, LLSD() ); + } + else + { + // If the "no_commit_on_selection" parameter is set + // we commit only when user presses OK in the picker + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. if (mCommitOnSelection || op == TEXTURE_SELECT) { onCommit(); } - } - } - } + } + } + } } void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) { - mOnTextureSelectedCallback = cb; - LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); - if (floaterp) - { - floaterp->setTextureSelectedCallback(cb); - } + mOnTextureSelectedCallback = cb; + LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); + if (floaterp) + { + floaterp->setTextureSelectedCallback(cb); + } } -void LLTextureCtrl::setImageAssetName(const std::string& name) +void LLTextureCtrl::setImageAssetName(const std::string& name) { - LLPointer imagep = LLUI::getUIImage(name); - if(imagep) - { - LLViewerFetchedTexture* pTexture = dynamic_cast(imagep->getImage().get()); - if(pTexture) - { - LLUUID id = pTexture->getID(); - setImageAssetID(id); - } - } + LLPointer imagep = LLUI::getUIImage(name); + if(imagep) + { + LLViewerFetchedTexture* pTexture = dynamic_cast(imagep->getImage().get()); + if(pTexture) + { + LLUUID id = pTexture->getID(); + setImageAssetID(id); + } + } } void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { - if( mImageAssetID != asset_id ) - { - mImageItemID.setNull(); - mImageAssetID = asset_id; + if( mImageAssetID != asset_id ) + { + mImageItemID.setNull(); + mImageAssetID = asset_id; mLocalTrackingID.setNull(); - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if( floaterp && getEnabled() ) - { - floaterp->setImageID( asset_id ); - floaterp->resetDirty(); - } - } + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if( floaterp && getEnabled() ) + { + floaterp->setImageID( asset_id ); + floaterp->resetDirty(); + } + } } void LLTextureCtrl::setBakeTextureEnabled(bool enabled) { mBakeTextureEnabled = enabled; - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if (floaterp) - { - floaterp->setBakeTextureEnabled(enabled); - } + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if (floaterp) + { + floaterp->setBakeTextureEnabled(enabled); + } } void LLTextureCtrl::setInventoryPickType(EPickInventoryType type) @@ -2127,16 +2127,16 @@ void LLTextureCtrl::setInventoryPickType(EPickInventoryType type) } BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, void *cargo_data, - EAcceptance *accept, - std::string& tooltip_msg) + BOOL drop, EDragAndDropType cargo_type, void *cargo_data, + EAcceptance *accept, + std::string& tooltip_msg) { - BOOL handled = FALSE; + BOOL handled = FALSE; - // this downcast may be invalid - but if the second test below - // returns true, then the cast was valid, and we can perform - // the third test without problems. - LLInventoryItem* item = (LLInventoryItem*)cargo_data; + // this downcast may be invalid - but if the second test below + // returns true, then the cast was valid, and we can perform + // the third test without problems. + LLInventoryItem* item = (LLInventoryItem*)cargo_data; bool is_mesh = cargo_type == DAD_MESH; bool is_texture = cargo_type == DAD_TEXTURE; @@ -2156,66 +2156,66 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, allow_dnd = is_texture || is_mesh || is_material; } - if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg)) - { - if (drop) - { - if(doDrop(item)) - { - if (!mCommitOnSelection) - mViewModel->setDirty(); + if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg)) + { + if (drop) + { + if(doDrop(item)) + { + if (!mCommitOnSelection) + mViewModel->setDirty(); - // This removes the 'Multiple' overlay, since - // there is now only one texture selected. - setTentative( FALSE ); - onCommit(); - } - } + // This removes the 'Multiple' overlay, since + // there is now only one texture selected. + setTentative( FALSE ); + onCommit(); + } + } - *accept = ACCEPT_YES_SINGLE; - } - else - { - *accept = ACCEPT_NO; - } + *accept = ACCEPT_YES_SINGLE; + } + else + { + *accept = ACCEPT_NO; + } - handled = TRUE; - LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl " << getName() << LL_ENDL; + handled = TRUE; + LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl " << getName() << LL_ENDL; - return handled; + return handled; } void LLTextureCtrl::draw() { - mBorder->setKeyboardFocusHighlight(hasFocus()); + mBorder->setKeyboardFocusHighlight(hasFocus()); LLPointer preview = NULL; - if (!mValid) - { - mTexturep = NULL; + if (!mValid) + { + mTexturep = NULL; mGLTFMaterial = NULL; mGLTFPreview = NULL; - } - else if (!mImageAssetID.isNull()) - { - if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) - { - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (obj) - { - LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); - mTexturep = viewerTexture ? dynamic_cast(viewerTexture) : NULL; - mGLTFMaterial = NULL; - mGLTFPreview = NULL; + } + else if (!mImageAssetID.isNull()) + { + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + mTexturep = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + mGLTFMaterial = NULL; + mGLTFPreview = NULL; preview = mTexturep; - } - - } + } + + } - if (preview.isNull()) - { + if (preview.isNull()) + { LLPointer old_material = mGLTFMaterial; mGLTFMaterial = NULL; mTexturep = NULL; @@ -2243,151 +2243,151 @@ void LLTextureCtrl::draw() } else { - mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); - mTexturep->forceToSaveRawImage(0); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + mTexturep->forceToSaveRawImage(0); - preview = mTexturep; + preview = mTexturep; } - } - } - else//mImageAssetID == LLUUID::null - { - mTexturep = NULL; + } + } + else//mImageAssetID == LLUUID::null + { + mTexturep = NULL; mGLTFMaterial = NULL; mGLTFPreview = NULL; - } - - // Border - LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); - gl_rect_2d( border, mBorderColor.get(), FALSE ); - - // Interior - LLRect interior = border; - interior.stretch( -1 ); - - // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677). - const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - if( preview ) - { - if( preview->getComponents() == 4 ) - { - gl_rect_2d_checkerboard( interior, alpha ); - } - - gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha); + } + + // Border + LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); + gl_rect_2d( border, mBorderColor.get(), FALSE ); + + // Interior + LLRect interior = border; + interior.stretch( -1 ); + + // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677). + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + if( preview ) + { + if( preview->getComponents() == 4 ) + { + gl_rect_2d_checkerboard( interior, alpha ); + } + + gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha); preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); - } - else if (!mFallbackImage.isNull()) - { - mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha); - } - else - { - gl_rect_2d( interior, LLColor4::grey % alpha, TRUE ); - - // Draw X - gl_draw_x( interior, LLColor4::black ); - } - - mTentativeLabel->setVisible( getTentative() ); - - // Show "Loading..." string on the top left corner while this texture is loading. - // Using the discard level, do not show the string if the texture is almost but not - // fully loaded. - if (mTexturep.notNull() && - (!mTexturep->isFullyLoaded()) && - (mShowLoadingPlaceholder == TRUE)) - { - U32 v_offset = 25; - LLFontGL* font = LLFontGL::getFontSansSerif(); - - // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god - if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike()) - { - font->renderUTF8( - mLoadingPlaceholderString, - 0, - llfloor(interior.mLeft+3), - llfloor(interior.mTop-v_offset), - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::DROP_SHADOW); - } - - // Optionally show more detailed information. - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - LLFontGL* font = LLFontGL::getFontSansSerif(); - std::string tdesc; - // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best). - - v_offset += 12; - tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0)); - font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), - LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); - - v_offset += 12; - tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel()); - font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), - LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); - - v_offset += 12; - tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str()); - font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), - LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); - } - } - - LLUICtrl::draw(); + } + else if (!mFallbackImage.isNull()) + { + mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha); + } + else + { + gl_rect_2d( interior, LLColor4::grey % alpha, TRUE ); + + // Draw X + gl_draw_x( interior, LLColor4::black ); + } + + mTentativeLabel->setVisible( getTentative() ); + + // Show "Loading..." string on the top left corner while this texture is loading. + // Using the discard level, do not show the string if the texture is almost but not + // fully loaded. + if (mTexturep.notNull() && + (!mTexturep->isFullyLoaded()) && + (mShowLoadingPlaceholder == TRUE)) + { + U32 v_offset = 25; + LLFontGL* font = LLFontGL::getFontSansSerif(); + + // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god + if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike()) + { + font->renderUTF8( + mLoadingPlaceholderString, + 0, + llfloor(interior.mLeft+3), + llfloor(interior.mTop-v_offset), + LLColor4::white, + LLFontGL::LEFT, + LLFontGL::BASELINE, + LLFontGL::DROP_SHADOW); + } + + // Optionally show more detailed information. + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + LLFontGL* font = LLFontGL::getFontSansSerif(); + std::string tdesc; + // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best). + + v_offset += 12; + tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0)); + font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), + LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); + + v_offset += 12; + tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel()); + font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), + LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); + + v_offset += 12; + tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str()); + font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset), + LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); + } + } + + LLUICtrl::draw(); } BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg) { - BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); - BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); - BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID()); - - PermissionMask item_perm_mask = 0; - if (copy) item_perm_mask |= PERM_COPY; - if (mod) item_perm_mask |= PERM_MODIFY; - if (xfer) item_perm_mask |= PERM_TRANSFER; - - PermissionMask filter_perm_mask = mImmediateFilterPermMask; - if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) - { - if(mDragCallback) - { - return mDragCallback(this, item); - } - else - { - return TRUE; - } - } - else - { + BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); + BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); + BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID()); + + PermissionMask item_perm_mask = 0; + if (copy) item_perm_mask |= PERM_COPY; + if (mod) item_perm_mask |= PERM_MODIFY; + if (xfer) item_perm_mask |= PERM_TRANSFER; + + PermissionMask filter_perm_mask = mImmediateFilterPermMask; + if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) + { + if(mDragCallback) + { + return mDragCallback(this, item); + } + else + { + return TRUE; + } + } + else + { PermissionMask mask = PERM_COPY | PERM_TRANSFER; if ((filter_perm_mask & mask) == mask && cargo_type == DAD_TEXTURE) { tooltip_msg.assign(LLTrans::getString("TooltipTextureRestrictedDrop")); } - return FALSE; - } + return FALSE; + } } BOOL LLTextureCtrl::doDrop(LLInventoryItem* item) { - // call the callback if it exists. - if(mDropCallback) - { - // if it returns TRUE, we return TRUE, and therefore the - // commit is called above. - return mDropCallback(this, item); - } + // call the callback if it exists. + if(mDropCallback) + { + // if it returns TRUE, we return TRUE, and therefore the + // commit is called above. + return mDropCallback(this, item); + } // no callback installed, so just set the image ids and carry on. LLUUID asset_id = item->getAssetUUID(); @@ -2398,29 +2398,29 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item) asset_id = BLANK_MATERIAL_ASSET_ID; } - setImageAssetID(asset_id); - mImageItemID = item->getUUID(); - return TRUE; + setImageAssetID(asset_id); + mImageItemID = item->getUUID(); + return TRUE; } BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char) { - if( ' ' == uni_char ) - { - showPicker(TRUE); - return TRUE; - } - return LLUICtrl::handleUnicodeCharHere(uni_char); + if( ' ' == uni_char ) + { + showPicker(TRUE); + return TRUE; + } + return LLUICtrl::handleUnicodeCharHere(uni_char); } void LLTextureCtrl::setValue( const LLSD& value ) { - setImageAssetID(value.asUUID()); + setImageAssetID(value.asUUID()); } LLSD LLTextureCtrl::getValue() const { - return LLSD(getImageAssetID()); + return LLSD(getImageAssetID()); } namespace LLInitParam diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index f193b0c083..db36ac9cc2 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -1,4 +1,4 @@ -/** +/** * @file lltexturectrl.h * @author Richard Nelson, James Cook * @brief LLTextureCtrl class header file including related functions @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -75,10 +75,10 @@ typedef enum e_pick_inventory_type namespace LLInitParam { template<> - struct TypeValues : public TypeValuesHelper - { - static void declareValues(); - }; + struct TypeValues : public TypeValuesHelper + { + static void declareValues(); + }; } enum LLPickerSource @@ -97,56 +97,56 @@ class LLTextureCtrl : public LLUICtrl { public: - typedef enum e_texture_pick_op - { - TEXTURE_CHANGE, - TEXTURE_SELECT, - TEXTURE_CANCEL - } ETexturePickOp; + typedef enum e_texture_pick_op + { + TEXTURE_CHANGE, + TEXTURE_SELECT, + TEXTURE_CANCEL + } ETexturePickOp; public: - struct Params : public LLInitParam::Block - { - Optional image_id; - Optional default_image_id; - Optional default_image_name; + struct Params : public LLInitParam::Block + { + Optional image_id; + Optional default_image_id; + Optional default_image_name; Optional pick_type; - Optional allow_no_texture; - Optional can_apply_immediately; - Optional no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty - // only on DnD or when OK is pressed in the picker - Optional label_width; - Optional border_color; - Optional fallback_image; - - Optional multiselect_text, - caption_text; - - Optional border; - - Params() - : image_id("image"), - default_image_id("default_image_id"), - default_image_name("default_image_name"), + Optional allow_no_texture; + Optional can_apply_immediately; + Optional no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty + // only on DnD or when OK is pressed in the picker + Optional label_width; + Optional border_color; + Optional fallback_image; + + Optional multiselect_text, + caption_text; + + Optional border; + + Params() + : image_id("image"), + default_image_id("default_image_id"), + default_image_name("default_image_name"), pick_type("pick_type", PICK_TEXTURE), - allow_no_texture("allow_no_texture", false), - can_apply_immediately("can_apply_immediately"), - no_commit_on_selection("no_commit_on_selection", false), - label_width("label_width", -1), - border_color("border_color"), - fallback_image("fallback_image"), - multiselect_text("multiselect_text"), - caption_text("caption_text"), - border("border") - {} - }; + allow_no_texture("allow_no_texture", false), + can_apply_immediately("can_apply_immediately"), + no_commit_on_selection("no_commit_on_selection", false), + label_width("label_width", -1), + border_color("border_color"), + fallback_image("fallback_image"), + multiselect_text("multiselect_text"), + caption_text("caption_text"), + border("border") + {} + }; protected: - LLTextureCtrl(const Params&); - friend class LLUICtrlFactory; + LLTextureCtrl(const Params&); + friend class LLUICtrlFactory; public: - virtual ~LLTextureCtrl(); + virtual ~LLTextureCtrl(); - // LLView interface + // LLView interface BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, @@ -171,77 +171,77 @@ public: void setValue(const LLSD& value) override; LLSD getValue() const override; - // LLTextureCtrl interface - void showPicker(BOOL take_focus); - bool isPickerShown() { return !mFloaterHandle.isDead(); } - void setLabel(const std::string& label); - void setLabelWidth(S32 label_width) {mLabelWidth =label_width;} - const std::string& getLabel() const { return mLabel; } + // LLTextureCtrl interface + void showPicker(BOOL take_focus); + bool isPickerShown() { return !mFloaterHandle.isDead(); } + void setLabel(const std::string& label); + void setLabelWidth(S32 label_width) {mLabelWidth =label_width;} + const std::string& getLabel() const { return mLabel; } - void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; } - bool getAllowNoTexture() const { return mAllowNoTexture; } + void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; } + bool getAllowNoTexture() const { return mAllowNoTexture; } - void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; } - BOOL getAllowLocalTexture() const { return mAllowLocalTexture; } + void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; } + BOOL getAllowLocalTexture() const { return mAllowLocalTexture; } - const LLUUID& getImageItemID() { return mImageItemID; } + const LLUUID& getImageItemID() { return mImageItemID; } - virtual void setImageAssetName(const std::string& name); - - void setImageAssetID(const LLUUID &image_asset_id); - const LLUUID& getImageAssetID() const { return mImageAssetID; } + virtual void setImageAssetName(const std::string& name); - void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; } - const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; } + void setImageAssetID(const LLUUID &image_asset_id); + const LLUUID& getImageAssetID() const { return mImageAssetID; } - const std::string& getDefaultImageName() const { return mDefaultImageName; } + void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; } + const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; } - void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; } - const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; } + const std::string& getDefaultImageName() const { return mDefaultImageName; } - void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; } + void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; } + const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; } - void setCaption(const std::string& caption); - void setCanApplyImmediately(BOOL b); + void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; } - void setCanApply(bool can_preview, bool can_apply); + void setCaption(const std::string& caption); + void setCanApplyImmediately(BOOL b); - void setImmediateFilterPermMask(PermissionMask mask); - void setDnDFilterPermMask(PermissionMask mask) - { mDnDFilterPermMask = mask; } - PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; } + void setCanApply(bool can_preview, bool can_apply); + + void setImmediateFilterPermMask(PermissionMask mask); + void setDnDFilterPermMask(PermissionMask mask) + { mDnDFilterPermMask = mask; } + PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; } void setFilterPermissionMasks(PermissionMask mask); - void closeDependentFloater(); + void closeDependentFloater(); - void onFloaterClose(); - void onFloaterCommit(ETexturePickOp op, + void onFloaterClose(); + void onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& local_id, const LLUUID& inv_id, const LLUUID& tracking_id); - // This call is returned when a drag is detected. Your callback - // should return TRUE if the drag is acceptable. - void setDragCallback(drag_n_drop_callback cb) { mDragCallback = cb; } + // This call is returned when a drag is detected. Your callback + // should return TRUE if the drag is acceptable. + void setDragCallback(drag_n_drop_callback cb) { mDragCallback = cb; } + + // This callback is called when the drop happens. Return TRUE if + // the drop happened - resulting in an on commit callback, but not + // necessariliy any other change. + void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; } - // This callback is called when the drop happens. Return TRUE if - // the drop happened - resulting in an on commit callback, but not - // necessariliy any other change. - void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; } - - void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; } - void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; } - void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; } + void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; } + void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; } + void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; } - /* - * callback for changing texture selection in inventory list of texture floater - */ - void setOnTextureSelectedCallback(texture_selected_callback cb); + /* + * callback for changing texture selection in inventory list of texture floater + */ + void setOnTextureSelectedCallback(texture_selected_callback cb); - void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder); + void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder); - LLViewerFetchedTexture* getTexture() { return mTexturep; } + LLViewerFetchedTexture* getTexture() { return mTexturep; } void setBakeTextureEnabled(bool enabled); bool getBakeTextureEnabled() const { return mBakeTextureEnabled; } @@ -253,45 +253,45 @@ public: LLUUID getLocalTrackingID() { return mLocalTrackingID; } private: - BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg); - BOOL doDrop(LLInventoryItem* item); + BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg); + BOOL doDrop(LLInventoryItem* item); private: - drag_n_drop_callback mDragCallback; - drag_n_drop_callback mDropCallback; - commit_callback_t mOnCancelCallback; - commit_callback_t mOnSelectCallback; - commit_callback_t mOnCloseCallback; - texture_selected_callback mOnTextureSelectedCallback; - LLPointer mTexturep; - LLPointer mGLTFMaterial; - LLPointer mGLTFPreview; - LLUIColor mBorderColor; - LLUUID mImageItemID; - LLUUID mImageAssetID; - LLUUID mDefaultImageAssetID; - LLUUID mBlankImageAssetID; - LLUUID mLocalTrackingID; - LLUIImagePtr mFallbackImage; - std::string mDefaultImageName; - LLHandle mFloaterHandle; - LLTextBox* mTentativeLabel; - LLTextBox* mCaption; - std::string mLabel; - BOOL mAllowNoTexture; // If true, the user can select "none" as an option - BOOL mAllowLocalTexture; - PermissionMask mImmediateFilterPermMask; - PermissionMask mDnDFilterPermMask; - BOOL mCanApplyImmediately; - BOOL mCommitOnSelection; - BOOL mNeedsRawImageData; - LLViewBorder* mBorder; - BOOL mValid; - BOOL mShowLoadingPlaceholder; - std::string mLoadingPlaceholderString; - S32 mLabelWidth; - bool mOpenTexPreview; - bool mBakeTextureEnabled; + drag_n_drop_callback mDragCallback; + drag_n_drop_callback mDropCallback; + commit_callback_t mOnCancelCallback; + commit_callback_t mOnSelectCallback; + commit_callback_t mOnCloseCallback; + texture_selected_callback mOnTextureSelectedCallback; + LLPointer mTexturep; + LLPointer mGLTFMaterial; + LLPointer mGLTFPreview; + LLUIColor mBorderColor; + LLUUID mImageItemID; + LLUUID mImageAssetID; + LLUUID mDefaultImageAssetID; + LLUUID mBlankImageAssetID; + LLUUID mLocalTrackingID; + LLUIImagePtr mFallbackImage; + std::string mDefaultImageName; + LLHandle mFloaterHandle; + LLTextBox* mTentativeLabel; + LLTextBox* mCaption; + std::string mLabel; + BOOL mAllowNoTexture; // If true, the user can select "none" as an option + BOOL mAllowLocalTexture; + PermissionMask mImmediateFilterPermMask; + PermissionMask mDnDFilterPermMask; + BOOL mCanApplyImmediately; + BOOL mCommitOnSelection; + BOOL mNeedsRawImageData; + LLViewBorder* mBorder; + BOOL mValid; + BOOL mShowLoadingPlaceholder; + std::string mLoadingPlaceholderString; + S32 mLabelWidth; + bool mOpenTexPreview; + bool mBakeTextureEnabled; EPickInventoryType mInventoryPickType; }; @@ -305,90 +305,90 @@ typedef boost::function texture)> set_on_update_ class LLFloaterTexturePicker : public LLFloater { public: - LLFloaterTexturePicker( - LLView* owner, - LLUUID image_asset_id, - LLUUID default_image_asset_id, - LLUUID blank_image_asset_id, - BOOL tentative, - BOOL allow_no_texture, - const std::string& label, - PermissionMask immediate_filter_perm_mask, - PermissionMask dnd_filter_perm_mask, - BOOL can_apply_immediately, - LLUIImagePtr fallback_image_name, - EPickInventoryType pick_type); - - virtual ~LLFloaterTexturePicker(); - - // LLView overrides - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, void *cargo_data, - EAcceptance *accept, - std::string& tooltip_msg); - /*virtual*/ void draw(); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); - - // LLFloater overrides - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_settings); - - // New functions - void setImageID(const LLUUID& image_asset_id, bool set_selection = true); - bool updateImageStats(); // true if within limits - const LLUUID& getAssetID() { return mImageAssetID; } - const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library = FALSE); - void setCanApplyImmediately(BOOL b); - - void setActive(BOOL active); - - LLView* getOwner() const { return mOwner; } - void setOwner(LLView* owner) { mOwner = owner; } - void stopUsingPipette(); - - void commitIfImmediateSet(); + LLFloaterTexturePicker( + LLView* owner, + LLUUID image_asset_id, + LLUUID default_image_asset_id, + LLUUID blank_image_asset_id, + BOOL tentative, + BOOL allow_no_texture, + const std::string& label, + PermissionMask immediate_filter_perm_mask, + PermissionMask dnd_filter_perm_mask, + BOOL can_apply_immediately, + LLUIImagePtr fallback_image_name, + EPickInventoryType pick_type); + + virtual ~LLFloaterTexturePicker(); + + // LLView overrides + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, void *cargo_data, + EAcceptance *accept, + std::string& tooltip_msg); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + + // LLFloater overrides + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_settings); + + // New functions + void setImageID(const LLUUID& image_asset_id, bool set_selection = true); + bool updateImageStats(); // true if within limits + const LLUUID& getAssetID() { return mImageAssetID; } + const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library = FALSE); + void setCanApplyImmediately(BOOL b); + + void setActive(BOOL active); + + LLView* getOwner() const { return mOwner; } + void setOwner(LLView* owner) { mOwner = owner; } + void stopUsingPipette(); + + void commitIfImmediateSet(); void commitCallback(LLTextureCtrl::ETexturePickOp op); - void commitCancel(); + void commitCancel(); - void onFilterEdit(const std::string& search_string); + void onFilterEdit(const std::string& search_string); - void setCanApply(bool can_preview, bool can_apply, bool inworld_image = true); + void setCanApply(bool can_preview, bool can_apply, bool inworld_image = true); void setMinDimentionsLimits(S32 min_dim); - void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; } - void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; } - void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; } - void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; } - void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; } - const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; } - const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; } - - static void onBtnSetToDefault(void* userdata); - static void onBtnSelect(void* userdata); - static void onBtnCancel(void* userdata); - void onBtnPipette(); - //static void onBtnRevert( void* userdata ); - static void onBtnBlank(void* userdata); - static void onBtnNone(void* userdata); - void onSelectionChange(const std::deque &items, BOOL user_action); - static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); - void onTextureSelect(const LLTextureEntry& te); - - static void onModeSelect(LLUICtrl* ctrl, void *userdata); - static void onBtnAdd(void* userdata); - static void onBtnRemove(void* userdata); - static void onBtnUpload(void* userdata); - static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); - - static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata); - - void setLocalTextureEnabled(BOOL enabled); - void setBakeTextureEnabled(BOOL enabled); + void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; } + void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; } + void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; } + void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; } + void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; } + const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; } + const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; } + + static void onBtnSetToDefault(void* userdata); + static void onBtnSelect(void* userdata); + static void onBtnCancel(void* userdata); + void onBtnPipette(); + //static void onBtnRevert( void* userdata ); + static void onBtnBlank(void* userdata); + static void onBtnNone(void* userdata); + void onSelectionChange(const std::deque &items, BOOL user_action); + static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); + void onTextureSelect(const LLTextureEntry& te); + + static void onModeSelect(LLUICtrl* ctrl, void *userdata); + static void onBtnAdd(void* userdata); + static void onBtnRemove(void* userdata); + static void onBtnUpload(void* userdata); + static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); + + static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata); + + void setLocalTextureEnabled(BOOL enabled); + void setBakeTextureEnabled(BOOL enabled); void setInventoryPickType(EPickInventoryType type); void setImmediateFilterPermMask(PermissionMask mask); - static void onPickerCallback(const std::vector& filenames, LLHandle handle); + static void onPickerCallback(const std::vector& filenames, LLHandle handle); protected: void changeMode(); @@ -396,41 +396,41 @@ protected: void refreshInventoryFilter(); void setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection = true); - LLPointer mTexturep; + LLPointer mTexturep; LLPointer mGLTFMaterial; LLPointer mGLTFPreview; - LLView* mOwner; + LLView* mOwner; - LLUUID mImageAssetID; // Currently selected texture - LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null. - LLUUID mDefaultImageAssetID; - LLUUID mBlankImageAssetID; - BOOL mTentative; - BOOL mAllowNoTexture; - LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory. - LLUUID mOriginalImageAssetID; + LLUUID mImageAssetID; // Currently selected texture + LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null. + LLUUID mDefaultImageAssetID; + LLUUID mBlankImageAssetID; + BOOL mTentative; + BOOL mAllowNoTexture; + LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory. + LLUUID mOriginalImageAssetID; - std::string mLabel; + std::string mLabel; - LLTextBox* mTentativeLabel; - LLTextBox* mResolutionLabel; + LLTextBox* mTentativeLabel; + LLTextBox* mResolutionLabel; LLTextBox* mResolutionWarning; - std::string mPendingName; - BOOL mActive; - - LLFilterEditor* mFilterEdit; - LLInventoryPanel* mInventoryPanel; - PermissionMask mImmediateFilterPermMask; - PermissionMask mDnDFilterPermMask; - BOOL mCanApplyImmediately; - BOOL mNoCopyTextureSelected; - F32 mContextConeOpacity; - LLSaveFolderState mSavedFolderState; - BOOL mSelectedItemPinned; - - LLComboBox* mModeSelector; - LLScrollListCtrl* mLocalScrollCtrl; + std::string mPendingName; + BOOL mActive; + + LLFilterEditor* mFilterEdit; + LLInventoryPanel* mInventoryPanel; + PermissionMask mImmediateFilterPermMask; + PermissionMask mDnDFilterPermMask; + BOOL mCanApplyImmediately; + BOOL mNoCopyTextureSelected; + F32 mContextConeOpacity; + LLSaveFolderState mSavedFolderState; + BOOL mSelectedItemPinned; + + LLComboBox* mModeSelector; + LLScrollListCtrl* mLocalScrollCtrl; LLButton* mDefaultBtn; LLButton* mNoneBtn; LLButton* mBlankBtn; @@ -439,22 +439,22 @@ protected: LLButton* mCancelBtn; private: - bool mCanApply; - bool mCanPreview; - bool mPreviewSettingChanged; + bool mCanApply; + bool mCanPreview; + bool mPreviewSettingChanged; bool mLimitsSet; S32 mMaxDim; S32 mMinDim; EPickInventoryType mInventoryPickType; - texture_selected_callback mTextureSelectedCallback; - floater_close_callback mOnFloaterCloseCallback; - floater_commit_callback mOnFloaterCommitCallback; - set_image_asset_id_callback mSetImageAssetIDCallback; - set_on_update_image_stats_callback mOnUpdateImageStatsCallback; + texture_selected_callback mTextureSelectedCallback; + floater_close_callback mOnFloaterCloseCallback; + floater_commit_callback mOnFloaterCommitCallback; + set_image_asset_id_callback mSetImageAssetIDCallback; + set_on_update_image_stats_callback mOnUpdateImageStatsCallback; - BOOL mBakeTextureEnabled; + BOOL mBakeTextureEnabled; static S32 sLastPickerMode; }; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 293c47bf73..8a118232d0 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltooldraganddrop.cpp * @brief LLToolDragAndDrop class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -69,1123 +69,1123 @@ class LLNoPreferredType : public LLInventoryCollectFunctor { public: - LLNoPreferredType() {} - virtual ~LLNoPreferredType() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item) - { - if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE)) - { - return true; - } - return false; - } + LLNoPreferredType() {} + virtual ~LLNoPreferredType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item) + { + if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE)) + { + return true; + } + return false; + } }; class LLNoPreferredTypeOrItem : public LLInventoryCollectFunctor { public: - LLNoPreferredTypeOrItem() {} - virtual ~LLNoPreferredTypeOrItem() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item) - { - if (item) return true; - if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE)) - { - return true; - } - return false; - } + LLNoPreferredTypeOrItem() {} + virtual ~LLNoPreferredTypeOrItem() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item) + { + if (item) return true; + if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE)) + { + return true; + } + return false; + } }; class LLDroppableItem : public LLInventoryCollectFunctor { public: - LLDroppableItem(BOOL is_transfer) : - mCountLosing(0), mIsTransfer(is_transfer) {} - virtual ~LLDroppableItem() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item); - S32 countNoCopy() const { return mCountLosing; } + LLDroppableItem(BOOL is_transfer) : + mCountLosing(0), mIsTransfer(is_transfer) {} + virtual ~LLDroppableItem() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); + S32 countNoCopy() const { return mCountLosing; } protected: - S32 mCountLosing; - BOOL mIsTransfer; + S32 mCountLosing; + BOOL mIsTransfer; }; bool LLDroppableItem::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - bool allowed = false; - if (item) - { - allowed = itemTransferCommonlyAllowed(item); - - if (allowed - && mIsTransfer - && !item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID())) - { - allowed = false; - } - if (allowed && !item->getPermissions().allowCopyBy(gAgent.getID())) - { - ++mCountLosing; - } - } - return allowed; + LLInventoryItem* item) +{ + bool allowed = false; + if (item) + { + allowed = itemTransferCommonlyAllowed(item); + + if (allowed + && mIsTransfer + && !item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID())) + { + allowed = false; + } + if (allowed && !item->getPermissions().allowCopyBy(gAgent.getID())) + { + ++mCountLosing; + } + } + return allowed; } class LLDropCopyableItems : public LLInventoryCollectFunctor { public: - LLDropCopyableItems() {} - virtual ~LLDropCopyableItems() {} - virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); + LLDropCopyableItems() {} + virtual ~LLDropCopyableItems() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); }; bool LLDropCopyableItems::operator()( - LLInventoryCategory* cat, - LLInventoryItem* item) -{ - bool allowed = false; - if (item) - { - allowed = itemTransferCommonlyAllowed(item); - if (allowed && - !item->getPermissions().allowCopyBy(gAgent.getID())) - { - // whoops, can't copy it - don't allow it. - allowed = false; - } - } - return allowed; -} - -// Starts a fetch on folders and items. This is really not used + LLInventoryCategory* cat, + LLInventoryItem* item) +{ + bool allowed = false; + if (item) + { + allowed = itemTransferCommonlyAllowed(item); + if (allowed && + !item->getPermissions().allowCopyBy(gAgent.getID())) + { + // whoops, can't copy it - don't allow it. + allowed = false; + } + } + return allowed; +} + +// Starts a fetch on folders and items. This is really not used // as an observer in the traditional sense; we're just using it to // request a fetch and we don't care about when/if the response arrives. class LLCategoryFireAndForget : public LLInventoryFetchComboObserver { public: - LLCategoryFireAndForget(const uuid_vec_t& folder_ids, - const uuid_vec_t& item_ids) : - LLInventoryFetchComboObserver(folder_ids, item_ids) - {} - ~LLCategoryFireAndForget() {} - virtual void done() - { - /* no-op: it's fire n forget right? */ - LL_DEBUGS() << "LLCategoryFireAndForget::done()" << LL_ENDL; - } + LLCategoryFireAndForget(const uuid_vec_t& folder_ids, + const uuid_vec_t& item_ids) : + LLInventoryFetchComboObserver(folder_ids, item_ids) + {} + ~LLCategoryFireAndForget() {} + virtual void done() + { + /* no-op: it's fire n forget right? */ + LL_DEBUGS() << "LLCategoryFireAndForget::done()" << LL_ENDL; + } }; class LLCategoryDropObserver : public LLInventoryFetchItemsObserver { public: - LLCategoryDropObserver( - const uuid_vec_t& ids, - const LLUUID& obj_id, LLToolDragAndDrop::ESource src) : - LLInventoryFetchItemsObserver(ids), - mObjectID(obj_id), - mSource(src) - {} - ~LLCategoryDropObserver() {} - virtual void done(); + LLCategoryDropObserver( + const uuid_vec_t& ids, + const LLUUID& obj_id, LLToolDragAndDrop::ESource src) : + LLInventoryFetchItemsObserver(ids), + mObjectID(obj_id), + mSource(src) + {} + ~LLCategoryDropObserver() {} + virtual void done(); protected: - LLUUID mObjectID; - LLToolDragAndDrop::ESource mSource; + LLUUID mObjectID; + LLToolDragAndDrop::ESource mSource; }; void LLCategoryDropObserver::done() { - gInventory.removeObserver(this); - LLViewerObject* dst_obj = gObjectList.findObject(mObjectID); - if (dst_obj) - { - // *FIX: coalesce these... - LLInventoryItem* item = NULL; - uuid_vec_t::iterator it = mComplete.begin(); - uuid_vec_t::iterator end = mComplete.end(); - for(; it < end; ++it) - { - item = gInventory.getItem(*it); - if (item) - { - LLToolDragAndDrop::dropInventory( - dst_obj, - item, - mSource, - LLUUID::null); - } - } - } - delete this; + gInventory.removeObserver(this); + LLViewerObject* dst_obj = gObjectList.findObject(mObjectID); + if (dst_obj) + { + // *FIX: coalesce these... + LLInventoryItem* item = NULL; + uuid_vec_t::iterator it = mComplete.begin(); + uuid_vec_t::iterator end = mComplete.end(); + for(; it < end; ++it) + { + item = gInventory.getItem(*it); + if (item) + { + LLToolDragAndDrop::dropInventory( + dst_obj, + item, + mSource, + LLUUID::null); + } + } + } + delete this; } S32 LLToolDragAndDrop::sOperationId = 0; LLToolDragAndDrop::DragAndDropEntry::DragAndDropEntry(dragOrDrop3dImpl f_none, - dragOrDrop3dImpl f_self, - dragOrDrop3dImpl f_avatar, - dragOrDrop3dImpl f_object, - dragOrDrop3dImpl f_land) : - LLDictionaryEntry("") + dragOrDrop3dImpl f_self, + dragOrDrop3dImpl f_avatar, + dragOrDrop3dImpl f_object, + dragOrDrop3dImpl f_land) : + LLDictionaryEntry("") { - mFunctions[DT_NONE] = f_none; - mFunctions[DT_SELF] = f_self; - mFunctions[DT_AVATAR] = f_avatar; - mFunctions[DT_OBJECT] = f_object; - mFunctions[DT_LAND] = f_land; + mFunctions[DT_NONE] = f_none; + mFunctions[DT_SELF] = f_self; + mFunctions[DT_AVATAR] = f_avatar; + mFunctions[DT_OBJECT] = f_object; + mFunctions[DT_LAND] = f_land; } LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::LLDragAndDropDictionary::get(EDragAndDropType dad_type, LLToolDragAndDrop::EDropTarget drop_target) { - const DragAndDropEntry *entry = lookup(dad_type); - if (entry) - { - return (entry->mFunctions[(U8)drop_target]); - } - return &LLToolDragAndDrop::dad3dNULL; + const DragAndDropEntry *entry = lookup(dad_type); + if (entry) + { + return (entry->mFunctions[(U8)drop_target]); + } + return &LLToolDragAndDrop::dad3dNULL; } LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() { - // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND - // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------| - addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); + // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND + // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------| + addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand)); - addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand)); + addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - + // TODO: animation on self could play it? edit it? - // TODO: gesture on self could play it? edit it? + // TODO: gesture on self could play it? edit it? }; LLToolDragAndDrop::LLToolDragAndDrop() -: LLTool(std::string("draganddrop"), NULL), - mCargoCount(0), - mDragStartX(0), - mDragStartY(0), - mSource(SOURCE_AGENT), - mCursor(UI_CURSOR_NO), - mLastAccept(ACCEPT_NO), - mDrop(FALSE), - mCurItemIndex(0) +: LLTool(std::string("draganddrop"), NULL), + mCargoCount(0), + mDragStartX(0), + mDragStartY(0), + mSource(SOURCE_AGENT), + mCursor(UI_CURSOR_NO), + mLastAccept(ACCEPT_NO), + mDrop(FALSE), + mCurItemIndex(0) { } void LLToolDragAndDrop::setDragStart(S32 x, S32 y) { - mDragStartX = x; - mDragStartY = y; + mDragStartX = x; + mDragStartY = y; } BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y) { - static LLCachedControl drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3); - - S32 mouse_delta_x = x - mDragStartX; - S32 mouse_delta_y = y - mDragStartY; - - return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold; + static LLCachedControl drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3); + + S32 mouse_delta_x = x - mDragStartX; + S32 mouse_delta_y = y - mDragStartY; + + return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold; } void LLToolDragAndDrop::beginDrag(EDragAndDropType type, - const LLUUID& cargo_id, - ESource source, - const LLUUID& source_id, - const LLUUID& object_id) -{ - if (type == DAD_NONE) - { - LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL; - return; - } - mCargoTypes.clear(); - mCargoTypes.push_back(type); - mCargoIDs.clear(); - mCargoIDs.push_back(cargo_id); - mSource = source; - mSourceID = source_id; - mObjectID = object_id; - - setMouseCapture( TRUE ); - LLToolMgr::getInstance()->setTransientTool( this ); - mCursor = UI_CURSOR_NO; - if ((mCargoTypes[0] == DAD_CATEGORY) - && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))) - { - LLInventoryCategory* cat = gInventory.getCategory(cargo_id); - // go ahead and fire & forget the descendents if we are not - // dragging a protected folder. - if (cat) - { - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLNoPreferredTypeOrItem is_not_preferred; - uuid_vec_t folder_ids; - uuid_vec_t item_ids; - if (is_not_preferred(cat, NULL)) - { - folder_ids.push_back(cargo_id); - } - gInventory.collectDescendentsIf( - cargo_id, - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_not_preferred); - S32 count = cats.size(); - S32 i; - for(i = 0; i < count; ++i) - { - folder_ids.push_back(cats.at(i)->getUUID()); - } - count = items.size(); - for(i = 0; i < count; ++i) - { - item_ids.push_back(items.at(i)->getUUID()); - } - if (!folder_ids.empty() || !item_ids.empty()) - { - LLCategoryFireAndForget *fetcher = new LLCategoryFireAndForget(folder_ids, item_ids); - fetcher->startFetch(); - delete fetcher; - } - } - } + const LLUUID& cargo_id, + ESource source, + const LLUUID& source_id, + const LLUUID& object_id) +{ + if (type == DAD_NONE) + { + LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL; + return; + } + mCargoTypes.clear(); + mCargoTypes.push_back(type); + mCargoIDs.clear(); + mCargoIDs.push_back(cargo_id); + mSource = source; + mSourceID = source_id; + mObjectID = object_id; + + setMouseCapture( TRUE ); + LLToolMgr::getInstance()->setTransientTool( this ); + mCursor = UI_CURSOR_NO; + if ((mCargoTypes[0] == DAD_CATEGORY) + && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))) + { + LLInventoryCategory* cat = gInventory.getCategory(cargo_id); + // go ahead and fire & forget the descendents if we are not + // dragging a protected folder. + if (cat) + { + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLNoPreferredTypeOrItem is_not_preferred; + uuid_vec_t folder_ids; + uuid_vec_t item_ids; + if (is_not_preferred(cat, NULL)) + { + folder_ids.push_back(cargo_id); + } + gInventory.collectDescendentsIf( + cargo_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_not_preferred); + S32 count = cats.size(); + S32 i; + for(i = 0; i < count; ++i) + { + folder_ids.push_back(cats.at(i)->getUUID()); + } + count = items.size(); + for(i = 0; i < count; ++i) + { + item_ids.push_back(items.at(i)->getUUID()); + } + if (!folder_ids.empty() || !item_ids.empty()) + { + LLCategoryFireAndForget *fetcher = new LLCategoryFireAndForget(folder_ids, item_ids); + fetcher->startFetch(); + delete fetcher; + } + } + } } void LLToolDragAndDrop::beginMultiDrag( - const std::vector types, - const uuid_vec_t& cargo_ids, - ESource source, - const LLUUID& source_id) -{ - // assert on public api is evil - //llassert( type != DAD_NONE ); - - std::vector::const_iterator types_it; - for (types_it = types.begin(); types_it != types.end(); ++types_it) - { - if (DAD_NONE == *types_it) - { - LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL; - return; - } - } - mCargoTypes = types; - mCargoIDs = cargo_ids; - mSource = source; - mSourceID = source_id; - - setMouseCapture( TRUE ); - LLToolMgr::getInstance()->setTransientTool( this ); - mCursor = UI_CURSOR_NO; - if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) - { - // find categories (i.e. inventory folders) in the cargo. - LLInventoryCategory* cat = NULL; - S32 count = llmin(cargo_ids.size(), types.size()); - std::set cat_ids; - for(S32 i = 0; i < count; ++i) - { - cat = gInventory.getCategory(cargo_ids[i]); - if (cat) - { - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLNoPreferredType is_not_preferred; - if (is_not_preferred(cat, NULL)) - { - cat_ids.insert(cat->getUUID()); - } - gInventory.collectDescendentsIf( - cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_not_preferred); - S32 cat_count = cats.size(); - for(S32 i = 0; i < cat_count; ++i) - { - cat_ids.insert(cat->getUUID()); - } - } - } - if (!cat_ids.empty()) - { - uuid_vec_t folder_ids; - uuid_vec_t item_ids; - std::back_insert_iterator copier(folder_ids); - std::copy(cat_ids.begin(), cat_ids.end(), copier); - LLCategoryFireAndForget fetcher(folder_ids, item_ids); - } - } + const std::vector types, + const uuid_vec_t& cargo_ids, + ESource source, + const LLUUID& source_id) +{ + // assert on public api is evil + //llassert( type != DAD_NONE ); + + std::vector::const_iterator types_it; + for (types_it = types.begin(); types_it != types.end(); ++types_it) + { + if (DAD_NONE == *types_it) + { + LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL; + return; + } + } + mCargoTypes = types; + mCargoIDs = cargo_ids; + mSource = source; + mSourceID = source_id; + + setMouseCapture( TRUE ); + LLToolMgr::getInstance()->setTransientTool( this ); + mCursor = UI_CURSOR_NO; + if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) + { + // find categories (i.e. inventory folders) in the cargo. + LLInventoryCategory* cat = NULL; + S32 count = llmin(cargo_ids.size(), types.size()); + std::set cat_ids; + for(S32 i = 0; i < count; ++i) + { + cat = gInventory.getCategory(cargo_ids[i]); + if (cat) + { + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLNoPreferredType is_not_preferred; + if (is_not_preferred(cat, NULL)) + { + cat_ids.insert(cat->getUUID()); + } + gInventory.collectDescendentsIf( + cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_not_preferred); + S32 cat_count = cats.size(); + for(S32 i = 0; i < cat_count; ++i) + { + cat_ids.insert(cat->getUUID()); + } + } + } + if (!cat_ids.empty()) + { + uuid_vec_t folder_ids; + uuid_vec_t item_ids; + std::back_insert_iterator copier(folder_ids); + std::copy(cat_ids.begin(), cat_ids.end(), copier); + LLCategoryFireAndForget fetcher(folder_ids, item_ids); + } + } } void LLToolDragAndDrop::endDrag() { - mEndDragSignal(); - LLSelectMgr::getInstance()->unhighlightAll(); - setMouseCapture(FALSE); + mEndDragSignal(); + LLSelectMgr::getInstance()->unhighlightAll(); + setMouseCapture(FALSE); } void LLToolDragAndDrop::onMouseCaptureLost() { - // Called whenever the drag ends or if mouse capture is simply lost - LLToolMgr::getInstance()->clearTransientTool(); - mCargoTypes.clear(); - mCargoIDs.clear(); - mSource = SOURCE_AGENT; - mSourceID.setNull(); - mObjectID.setNull(); - mCustomMsg.clear(); + // Called whenever the drag ends or if mouse capture is simply lost + LLToolMgr::getInstance()->clearTransientTool(); + mCargoTypes.clear(); + mCargoIDs.clear(); + mSource = SOURCE_AGENT; + mSourceID.setNull(); + mObjectID.setNull(); + mCustomMsg.clear(); } BOOL LLToolDragAndDrop::handleMouseUp( S32 x, S32 y, MASK mask ) { - if (hasMouseCapture()) - { - EAcceptance acceptance = ACCEPT_NO; - dragOrDrop( x, y, mask, TRUE, &acceptance ); - endDrag(); - } - return TRUE; + if (hasMouseCapture()) + { + EAcceptance acceptance = ACCEPT_NO; + dragOrDrop( x, y, mask, TRUE, &acceptance ); + endDrag(); + } + return TRUE; } ECursorType LLToolDragAndDrop::acceptanceToCursor( EAcceptance acceptance ) { - switch (acceptance) - { - case ACCEPT_YES_MULTI: - if (mCargoIDs.size() > 1) - { - mCursor = UI_CURSOR_ARROWDRAGMULTI; - } - else - { - mCursor = UI_CURSOR_ARROWDRAG; - } - break; - case ACCEPT_YES_SINGLE: - if (mCargoIDs.size() > 1) - { - mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop"); - mCursor = UI_CURSOR_NO; - } - else - { - mCursor = UI_CURSOR_ARROWDRAG; - } - break; - - case ACCEPT_NO_LOCKED: - mCursor = UI_CURSOR_NOLOCKED; - break; - - case ACCEPT_NO_CUSTOM: - mToolTipMsg = mCustomMsg; - mCursor = UI_CURSOR_NO; - break; - - - case ACCEPT_NO: - mCursor = UI_CURSOR_NO; - break; - - case ACCEPT_YES_COPY_MULTI: - if (mCargoIDs.size() > 1) - { - mCursor = UI_CURSOR_ARROWCOPYMULTI; - } - else - { - mCursor = UI_CURSOR_ARROWCOPY; - } - break; - case ACCEPT_YES_COPY_SINGLE: - if (mCargoIDs.size() > 1) - { - mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop"); - mCursor = UI_CURSOR_NO; - } - else - { - mCursor = UI_CURSOR_ARROWCOPY; - } - break; - case ACCEPT_POSTPONED: - break; - default: - llassert( FALSE ); - } - - return mCursor; + switch (acceptance) + { + case ACCEPT_YES_MULTI: + if (mCargoIDs.size() > 1) + { + mCursor = UI_CURSOR_ARROWDRAGMULTI; + } + else + { + mCursor = UI_CURSOR_ARROWDRAG; + } + break; + case ACCEPT_YES_SINGLE: + if (mCargoIDs.size() > 1) + { + mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop"); + mCursor = UI_CURSOR_NO; + } + else + { + mCursor = UI_CURSOR_ARROWDRAG; + } + break; + + case ACCEPT_NO_LOCKED: + mCursor = UI_CURSOR_NOLOCKED; + break; + + case ACCEPT_NO_CUSTOM: + mToolTipMsg = mCustomMsg; + mCursor = UI_CURSOR_NO; + break; + + + case ACCEPT_NO: + mCursor = UI_CURSOR_NO; + break; + + case ACCEPT_YES_COPY_MULTI: + if (mCargoIDs.size() > 1) + { + mCursor = UI_CURSOR_ARROWCOPYMULTI; + } + else + { + mCursor = UI_CURSOR_ARROWCOPY; + } + break; + case ACCEPT_YES_COPY_SINGLE: + if (mCargoIDs.size() > 1) + { + mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop"); + mCursor = UI_CURSOR_NO; + } + else + { + mCursor = UI_CURSOR_ARROWCOPY; + } + break; + case ACCEPT_POSTPONED: + break; + default: + llassert( FALSE ); + } + + return mCursor; } BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask ) { - EAcceptance acceptance = ACCEPT_NO; - dragOrDrop( x, y, mask, FALSE, &acceptance ); + EAcceptance acceptance = ACCEPT_NO; + dragOrDrop( x, y, mask, FALSE, &acceptance ); - ECursorType cursor = acceptanceToCursor(acceptance); - gViewerWindow->getWindow()->setCursor( cursor ); + ECursorType cursor = acceptanceToCursor(acceptance); + gViewerWindow->getWindow()->setCursor( cursor ); - LL_DEBUGS("UserInput") << "hover handled by LLToolDragAndDrop" << LL_ENDL; - return TRUE; + LL_DEBUGS("UserInput") << "hover handled by LLToolDragAndDrop" << LL_ENDL; + return TRUE; } BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask) { - if (key == KEY_ESCAPE) - { - // cancel drag and drop operation - endDrag(); - return TRUE; - } + if (key == KEY_ESCAPE) + { + // cancel drag and drop operation + endDrag(); + return TRUE; + } - return FALSE; + return FALSE; } BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) { - if (!mToolTipMsg.empty()) - { - LLToolTipMgr::instance().unblockToolTips(); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(mToolTipMsg) - .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" ))); - return TRUE; - } - return FALSE; + if (!mToolTipMsg.empty()) + { + LLToolTipMgr::instance().unblockToolTips(); + LLToolTipMgr::instance().show(LLToolTip::Params() + .message(mToolTipMsg) + .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" ))); + return TRUE; + } + return FALSE; } void LLToolDragAndDrop::handleDeselect() { - mToolTipMsg.clear(); - mCustomMsg.clear(); + mToolTipMsg.clear(); + mCustomMsg.clear(); - LLToolTipMgr::instance().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); } // protected -void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, - EAcceptance* acceptance) -{ - *acceptance = ACCEPT_YES_MULTI; - - BOOL handled = FALSE; - - LLView* top_view = gFocusMgr.getTopCtrl(); - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - - mToolTipMsg.clear(); - - // Increment the operation id for every drop - if (drop) - { - sOperationId++; - } - - // For people drag and drop we don't need an actual inventory object, - // instead we need the current cargo id, which should be a person id. - bool is_uuid_dragged = (mSource == SOURCE_PEOPLE); - - if (top_view) - { - handled = TRUE; - - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - S32 local_x, local_y; - top_view->screenPointToLocal( x, y, &local_x, &local_y ); - EAcceptance item_acceptance = ACCEPT_NO; - - LLInventoryObject* cargo = locateInventory(item, cat); - if (cargo) - { - handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)cargo, - &item_acceptance, - mToolTipMsg); - } - else if (is_uuid_dragged) - { - handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)&mCargoIDs[mCurItemIndex], - &item_acceptance, - mToolTipMsg); - } - if (handled) - { - // use sort order to determine priority of acceptance - *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); - } - } - - // all objects passed, go ahead and perform drop if necessary - if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE) - { - if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI && - mCargoIDs.size() > 1) - { - // tried to give multi-cargo to a single-acceptor - refuse and return. - *acceptance = ACCEPT_NO; - return; - } - - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - S32 local_x, local_y; - EAcceptance item_acceptance; - top_view->screenPointToLocal( x, y, &local_x, &local_y ); - - LLInventoryObject* cargo = locateInventory(item, cat); - if (cargo) - { - handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE, - mCargoTypes[mCurItemIndex], - (void*)cargo, - &item_acceptance, - mToolTipMsg); - } - else if (is_uuid_dragged) - { - handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)&mCargoIDs[mCurItemIndex], - &item_acceptance, - mToolTipMsg); - } - } - } - if (handled) - { - mLastAccept = (EAcceptance)*acceptance; - } - } - - if (!handled) - { - handled = TRUE; - - LLRootView* root_view = gViewerWindow->getRootView(); - - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - EAcceptance item_acceptance = ACCEPT_NO; - - LLInventoryObject* cargo = locateInventory(item, cat); - - // fix for EXT-3191 - if (cargo) - { - handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)cargo, - &item_acceptance, - mToolTipMsg); - } - else if (is_uuid_dragged) - { - handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, - mCargoTypes[mCurItemIndex], - (void*)&mCargoIDs[mCurItemIndex], - &item_acceptance, - mToolTipMsg); - } - if (handled) - { - // use sort order to determine priority of acceptance - *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); - } - } - // all objects passed, go ahead and perform drop if necessary - if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED) - { - if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI && - mCargoIDs.size() > 1) - { - // tried to give multi-cargo to a single-acceptor - refuse and return. - *acceptance = ACCEPT_NO; - return; - } - - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - EAcceptance item_acceptance; - - LLInventoryObject* cargo = locateInventory(item, cat); - if (cargo) - { - handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, - mCargoTypes[mCurItemIndex], - (void*)cargo, - &item_acceptance, - mToolTipMsg); - } - else if (is_uuid_dragged) - { - handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, - mCargoTypes[mCurItemIndex], - (void*)&mCargoIDs[mCurItemIndex], - &item_acceptance, - mToolTipMsg); - } - } - } - - if (handled) - { - mLastAccept = (EAcceptance)*acceptance; - } - } - - if (!handled) - { - // Disallow drag and drop to 3D from the marketplace - const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); - if (marketplacelistings_id.notNull()) - { - for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++) - { - if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], marketplacelistings_id)) - { - *acceptance = ACCEPT_NO; - mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld"); - return; - } - } - } - - dragOrDrop3D( x, y, mask, drop, acceptance ); - } -} - -void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* acceptance ) +void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, + EAcceptance* acceptance) { - mDrop = drop; - if (mDrop) - { - // don't allow drag and drop onto rigged or transparent objects - pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE)); - } - else - { - // don't allow drag and drop onto transparent objects - gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, FALSE); - } + *acceptance = ACCEPT_YES_MULTI; - *acceptance = mLastAccept; -} + BOOL handled = FALSE; -void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info) -{ - if (getInstance() != NULL) - { - getInstance()->pick(pick_info); - } -} + LLView* top_view = gFocusMgr.getTopCtrl(); + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; -void LLToolDragAndDrop::pick(const LLPickInfo& pick_info) -{ - EDropTarget target = DT_NONE; - S32 hit_face = -1; - - LLViewerObject* hit_obj = pick_info.getObject(); - LLSelectMgr::getInstance()->unhighlightAll(); - bool highlight_object = false; - // Treat attachments as part of the avatar they are attached to. - if (hit_obj != NULL) - { - // don't allow drag and drop on grass, trees, etc. - if (pick_info.mPickType == LLPickInfo::PICK_FLORA) - { - mCursor = UI_CURSOR_NO; - gViewerWindow->getWindow()->setCursor( mCursor ); - return; - } - - if (hit_obj->isAttachment() && !hit_obj->isHUDAttachment()) - { - LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj ); - if (!avatar) - { - mLastAccept = ACCEPT_NO; - mCursor = UI_CURSOR_NO; - gViewerWindow->getWindow()->setCursor( mCursor ); - return; - } - hit_obj = avatar; - } - - if (hit_obj->isAvatar()) - { - if (((LLVOAvatar*) hit_obj)->isSelf()) - { - target = DT_SELF; - hit_face = -1; - } - else - { - target = DT_AVATAR; - hit_face = -1; - } - } - else - { - target = DT_OBJECT; - hit_face = pick_info.mObjectFace; - highlight_object = true; - } - } - else if (pick_info.mPickType == LLPickInfo::PICK_LAND) - { - target = DT_LAND; - hit_face = -1; - } - - mLastAccept = ACCEPT_YES_MULTI; - - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - const S32 item_index = mCurItemIndex; - const EDragAndDropType dad_type = mCargoTypes[item_index]; - // Call the right implementation function - mLastAccept = (EAcceptance)llmin( - (U32)mLastAccept, - (U32)callMemberFunction(*this, - LLDragAndDropDictionary::instance().get(dad_type, target)) - (hit_obj, hit_face, pick_info.mKeyMask, FALSE)); - } - - if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE)) - { - // if target allows multi-drop or there is only one item being dropped, go ahead - if ((mLastAccept >= ACCEPT_YES_COPY_MULTI) || (mCargoIDs.size() == 1)) - { - // Target accepts multi, or cargo is a single-drop - for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) - { - const S32 item_index = mCurItemIndex; - const EDragAndDropType dad_type = mCargoTypes[item_index]; - // Call the right implementation function - callMemberFunction(*this, LLDragAndDropDictionary::instance().get(dad_type, target)) - (hit_obj, hit_face, pick_info.mKeyMask, TRUE); - } - } - else - { - // Target does not accept multi, but cargo is multi - mLastAccept = ACCEPT_NO; - } - } - - if (highlight_object && mLastAccept > ACCEPT_NO_LOCKED) - { - // if any item being dragged will be applied to the object under our cursor - // highlight that object - for (S32 i = 0; i < (S32)mCargoIDs.size(); i++) - { - if (mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL)) - { - LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj); - break; - } - } - } - ECursorType cursor = acceptanceToCursor( mLastAccept ); - gViewerWindow->getWindow()->setCursor( cursor ); - - mLastHitPos = pick_info.mPosGlobal; - mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); -} + mToolTipMsg.clear(); -// static -BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id) -{ - if (!item) return FALSE; - - // Always succeed if.... - // material is from the library - // or already in the contents of the object - if (SOURCE_LIBRARY == source) - { - // dropping a material from the library always just works. - return TRUE; - } - - // In case the inventory has not been loaded (e.g. due to some recent operation - // causing a dirty inventory) and we can do an update, stall the user - // while fetching the inventory. - // - // Fetch if inventory is dirty and listener is present (otherwise we will not receive update) - if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners()) - { - hit_obj->requestInventory(); - LLSD args; - if (LLAssetType::AT_MATERIAL == item->getType()) + // Increment the operation id for every drop + if (drop) + { + sOperationId++; + } + + // For people drag and drop we don't need an actual inventory object, + // instead we need the current cargo id, which should be a person id. + bool is_uuid_dragged = (mSource == SOURCE_PEOPLE); + + if (top_view) + { + handled = TRUE; + + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { - args["ERROR_MESSAGE"] = "Unable to add material.\nPlease wait a few seconds and try again."; + S32 local_x, local_y; + top_view->screenPointToLocal( x, y, &local_x, &local_y ); + EAcceptance item_acceptance = ACCEPT_NO; + + LLInventoryObject* cargo = locateInventory(item, cat); + if (cargo) + { + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)cargo, + &item_acceptance, + mToolTipMsg); + } + else if (is_uuid_dragged) + { + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } + if (handled) + { + // use sort order to determine priority of acceptance + *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); + } } - else + + // all objects passed, go ahead and perform drop if necessary + if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE) { - args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again."; + if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI && + mCargoIDs.size() > 1) + { + // tried to give multi-cargo to a single-acceptor - refuse and return. + *acceptance = ACCEPT_NO; + return; + } + + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) + { + S32 local_x, local_y; + EAcceptance item_acceptance; + top_view->screenPointToLocal( x, y, &local_x, &local_y ); + + LLInventoryObject* cargo = locateInventory(item, cat); + if (cargo) + { + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE, + mCargoTypes[mCurItemIndex], + (void*)cargo, + &item_acceptance, + mToolTipMsg); + } + else if (is_uuid_dragged) + { + handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } + } } - LLNotificationsUtil::add("ErrorMessage", args); - return FALSE; - } - // Make sure to verify both id and type since 'null' - // is a shared default for some asset types. - if (hit_obj->getInventoryItemByAsset(item->getAssetUUID(), item->getType())) - { - // if the asset is already in the object's inventory - // then it can always be added to a side. - // This saves some work if the task's inventory is already loaded - // and ensures that the asset item is only added once. - return TRUE; - } - - LLPointer new_item = new LLViewerInventoryItem(item); - if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) - { - // Check that we can add the material as inventory to the object - if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) - { - return FALSE; - } - // make sure the object has the material in it's inventory. - if (SOURCE_AGENT == source) - { - // Remove the material from local inventory. The server - // will actually remove the item from agent inventory. - gInventory.deleteObject(item->getUUID()); - gInventory.notifyObservers(); - } - else if (SOURCE_WORLD == source) - { - // *FIX: if the objects are in different regions, and the - // source region has crashed, you can bypass these - // permissions. - LLViewerObject* src_obj = gObjectList.findObject(src_id); - if (src_obj) - { - src_obj->removeInventory(item->getUUID()); - } - else - { - LL_WARNS() << "Unable to find source object." << LL_ENDL; - return FALSE; - } - } - // Add the asset item to the target object's inventory. - if (LLAssetType::AT_TEXTURE == new_item->getType() - || LLAssetType::AT_MATERIAL == new_item->getType()) + if (handled) { - hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + mLastAccept = (EAcceptance)*acceptance; } - else - { - hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); - } - // Force the object to update and refetch its inventory so it has this asset. - hit_obj->dirtyInventory(); - hit_obj->requestInventory(); - // TODO: Check to see if adding the item was successful; if not, then - // we should return false here. This will requre a separate listener - // since without listener, we have no way to receive update - } - else if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID())) - { - // Check that we can add the asset as inventory to the object - if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) - { - return FALSE; - } - // *FIX: may want to make sure agent can paint hit_obj. - - // Add the asset item to the target object's inventory. - if (LLAssetType::AT_TEXTURE == new_item->getType() - || LLAssetType::AT_MATERIAL == new_item->getType()) - { - hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); - } - else - { - hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); - } - // Force the object to update and refetch its inventory so it has this asset. - hit_obj->dirtyInventory(); - hit_obj->requestInventory(); - // TODO: Check to see if adding the item was successful; if not, then - // we should return false here. This will requre a separate listener - // since without listener, we have no way to receive update - } - else if (LLAssetType::AT_MATERIAL == new_item->getType() && - !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) - { - // Check that we can add the material as inventory to the object - if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) - { - return FALSE; - } - // *FIX: may want to make sure agent can paint hit_obj. - - // Add the material item to the target object's inventory. - hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); - - // Force the object to update and refetch its inventory so it has this material. - hit_obj->dirtyInventory(); - hit_obj->requestInventory(); - // TODO: Check to see if adding the item was successful; if not, then - // we should return false here. This will requre a separate listener - // since without listener, we have no way to receive update - } - return TRUE; -} - -void set_texture_to_material(LLViewerObject* hit_obj, - S32 hit_face, - const LLUUID& asset_id, - LLGLTFMaterial::TextureInfo drop_channel) -{ - LLTextureEntry* te = hit_obj->getTE(hit_face); - if (!te) - { - return; - } - - const LLUUID base_mat_id = hit_obj->getRenderMaterialID(hit_face); - if (base_mat_id.isNull()) - { - return; } - if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners()) + if (!handled) { - hit_obj->requestInventory(); - return; - } + handled = TRUE; - LLViewerInventoryItem* mat_item = hit_obj->getInventoryItemByAsset(base_mat_id); - if (mat_item && !mat_item->getPermissions().allowModifyBy(gAgentID)) - { - return; - } + LLRootView* root_view = gViewerWindow->getRootView(); - LLPointer material = te->getGLTFMaterialOverride(); + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) + { + EAcceptance item_acceptance = ACCEPT_NO; - // make a copy to not invalidate existing - // material for multiple objects - if (material.isNull()) - { - // Start with a material override which does not make any changes - material = new LLGLTFMaterial(); - } - else - { - material = new LLGLTFMaterial(*material); - } + LLInventoryObject* cargo = locateInventory(item, cat); - switch (drop_channel) - { - case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: - default: + // fix for EXT-3191 + if (cargo) { - material->setBaseColorId(asset_id); + handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)cargo, + &item_acceptance, + mToolTipMsg); } - break; - - case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: + else if (is_uuid_dragged) { - material->setOcclusionRoughnessMetallicId(asset_id); + handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); } - break; - - case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: + if (handled) { - material->setEmissiveId(asset_id); + // use sort order to determine priority of acceptance + *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance); + } + } + // all objects passed, go ahead and perform drop if necessary + if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED) + { + if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI && + mCargoIDs.size() > 1) + { + // tried to give multi-cargo to a single-acceptor - refuse and return. + *acceptance = ACCEPT_NO; + return; } - break; - case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) { - material->setNormalId(asset_id); + EAcceptance item_acceptance; + + LLInventoryObject* cargo = locateInventory(item, cat); + if (cargo) + { + handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, + mCargoTypes[mCurItemIndex], + (void*)cargo, + &item_acceptance, + mToolTipMsg); + } + else if (is_uuid_dragged) + { + handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, + mCargoTypes[mCurItemIndex], + (void*)&mCargoIDs[mCurItemIndex], + &item_acceptance, + mToolTipMsg); + } } - break; - } - LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); -} + } -void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id, - bool remove_pbr) -{ - if (!item) - { - LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << LL_ENDL; - return; - } - S32 num_faces = hit_obj->getNumTEs(); - bool has_non_pbr_faces = false; - for (S32 face = 0; face < num_faces; face++) - { - if (hit_obj->getRenderMaterialID(face).isNull()) + if (handled) { - has_non_pbr_faces = true; - break; + mLastAccept = (EAcceptance)*acceptance; } } - if (has_non_pbr_faces || remove_pbr) + if (!handled) { - BOOL res = handleDropMaterialProtections(hit_obj, item, source, src_id); - if (!res) + // Disallow drag and drop to 3D from the marketplace + const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (marketplacelistings_id.notNull()) { - return; + for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++) + { + if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], marketplacelistings_id)) + { + *acceptance = ACCEPT_NO; + mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld"); + return; + } + } } - } - LLUUID asset_id = item->getAssetUUID(); - // Overrides require textures to be copy and transfer free - LLPermissions item_permissions = item->getPermissions(); - bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()); - allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + dragOrDrop3D( x, y, mask, drop, acceptance ); + } +} - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - add(LLStatViewer::EDIT_TEXTURE, 1); - for( S32 face = 0; face < num_faces; face++ ) - { - if (remove_pbr) +void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* acceptance ) +{ + mDrop = drop; + if (mDrop) + { + // don't allow drag and drop onto rigged or transparent objects + pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE)); + } + else + { + // don't allow drag and drop onto transparent objects + gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, FALSE); + } + + *acceptance = mLastAccept; +} + +void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info) +{ + if (getInstance() != NULL) + { + getInstance()->pick(pick_info); + } +} + +void LLToolDragAndDrop::pick(const LLPickInfo& pick_info) +{ + EDropTarget target = DT_NONE; + S32 hit_face = -1; + + LLViewerObject* hit_obj = pick_info.getObject(); + LLSelectMgr::getInstance()->unhighlightAll(); + bool highlight_object = false; + // Treat attachments as part of the avatar they are attached to. + if (hit_obj != NULL) + { + // don't allow drag and drop on grass, trees, etc. + if (pick_info.mPickType == LLPickInfo::PICK_FLORA) + { + mCursor = UI_CURSOR_NO; + gViewerWindow->getWindow()->setCursor( mCursor ); + return; + } + + if (hit_obj->isAttachment() && !hit_obj->isHUDAttachment()) + { + LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj ); + if (!avatar) + { + mLastAccept = ACCEPT_NO; + mCursor = UI_CURSOR_NO; + gViewerWindow->getWindow()->setCursor( mCursor ); + return; + } + hit_obj = avatar; + } + + if (hit_obj->isAvatar()) + { + if (((LLVOAvatar*) hit_obj)->isSelf()) + { + target = DT_SELF; + hit_face = -1; + } + else + { + target = DT_AVATAR; + hit_face = -1; + } + } + else + { + target = DT_OBJECT; + hit_face = pick_info.mObjectFace; + highlight_object = true; + } + } + else if (pick_info.mPickType == LLPickInfo::PICK_LAND) + { + target = DT_LAND; + hit_face = -1; + } + + mLastAccept = ACCEPT_YES_MULTI; + + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) + { + const S32 item_index = mCurItemIndex; + const EDragAndDropType dad_type = mCargoTypes[item_index]; + // Call the right implementation function + mLastAccept = (EAcceptance)llmin( + (U32)mLastAccept, + (U32)callMemberFunction(*this, + LLDragAndDropDictionary::instance().get(dad_type, target)) + (hit_obj, hit_face, pick_info.mKeyMask, FALSE)); + } + + if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE)) + { + // if target allows multi-drop or there is only one item being dropped, go ahead + if ((mLastAccept >= ACCEPT_YES_COPY_MULTI) || (mCargoIDs.size() == 1)) + { + // Target accepts multi, or cargo is a single-drop + for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) + { + const S32 item_index = mCurItemIndex; + const EDragAndDropType dad_type = mCargoTypes[item_index]; + // Call the right implementation function + callMemberFunction(*this, LLDragAndDropDictionary::instance().get(dad_type, target)) + (hit_obj, hit_face, pick_info.mKeyMask, TRUE); + } + } + else + { + // Target does not accept multi, but cargo is multi + mLastAccept = ACCEPT_NO; + } + } + + if (highlight_object && mLastAccept > ACCEPT_NO_LOCKED) + { + // if any item being dragged will be applied to the object under our cursor + // highlight that object + for (S32 i = 0; i < (S32)mCargoIDs.size(); i++) + { + if (mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL)) + { + LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj); + break; + } + } + } + ECursorType cursor = acceptanceToCursor( mLastAccept ); + gViewerWindow->getWindow()->setCursor( cursor ); + + mLastHitPos = pick_info.mPosGlobal; + mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); +} + +// static +BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (!item) return FALSE; + + // Always succeed if.... + // material is from the library + // or already in the contents of the object + if (SOURCE_LIBRARY == source) + { + // dropping a material from the library always just works. + return TRUE; + } + + // In case the inventory has not been loaded (e.g. due to some recent operation + // causing a dirty inventory) and we can do an update, stall the user + // while fetching the inventory. + // + // Fetch if inventory is dirty and listener is present (otherwise we will not receive update) + if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners()) + { + hit_obj->requestInventory(); + LLSD args; + if (LLAssetType::AT_MATERIAL == item->getType()) + { + args["ERROR_MESSAGE"] = "Unable to add material.\nPlease wait a few seconds and try again."; + } + else + { + args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again."; + } + LLNotificationsUtil::add("ErrorMessage", args); + return FALSE; + } + // Make sure to verify both id and type since 'null' + // is a shared default for some asset types. + if (hit_obj->getInventoryItemByAsset(item->getAssetUUID(), item->getType())) + { + // if the asset is already in the object's inventory + // then it can always be added to a side. + // This saves some work if the task's inventory is already loaded + // and ensures that the asset item is only added once. + return TRUE; + } + + LLPointer new_item = new LLViewerInventoryItem(item); + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + { + // Check that we can add the material as inventory to the object + if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) + { + return FALSE; + } + // make sure the object has the material in it's inventory. + if (SOURCE_AGENT == source) + { + // Remove the material from local inventory. The server + // will actually remove the item from agent inventory. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + else if (SOURCE_WORLD == source) + { + // *FIX: if the objects are in different regions, and the + // source region has crashed, you can bypass these + // permissions. + LLViewerObject* src_obj = gObjectList.findObject(src_id); + if (src_obj) + { + src_obj->removeInventory(item->getUUID()); + } + else + { + LL_WARNS() << "Unable to find source object." << LL_ENDL; + return FALSE; + } + } + // Add the asset item to the target object's inventory. + if (LLAssetType::AT_TEXTURE == new_item->getType() + || LLAssetType::AT_MATERIAL == new_item->getType()) + { + hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + else + { + hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + // Force the object to update and refetch its inventory so it has this asset. + hit_obj->dirtyInventory(); + hit_obj->requestInventory(); + // TODO: Check to see if adding the item was successful; if not, then + // we should return false here. This will requre a separate listener + // since without listener, we have no way to receive update + } + else if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID())) + { + // Check that we can add the asset as inventory to the object + if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) + { + return FALSE; + } + // *FIX: may want to make sure agent can paint hit_obj. + + // Add the asset item to the target object's inventory. + if (LLAssetType::AT_TEXTURE == new_item->getType() + || LLAssetType::AT_MATERIAL == new_item->getType()) + { + hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + else + { + hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + } + // Force the object to update and refetch its inventory so it has this asset. + hit_obj->dirtyInventory(); + hit_obj->requestInventory(); + // TODO: Check to see if adding the item was successful; if not, then + // we should return false here. This will requre a separate listener + // since without listener, we have no way to receive update + } + else if (LLAssetType::AT_MATERIAL == new_item->getType() && + !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + { + // Check that we can add the material as inventory to the object + if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) + { + return FALSE; + } + // *FIX: may want to make sure agent can paint hit_obj. + + // Add the material item to the target object's inventory. + hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + + // Force the object to update and refetch its inventory so it has this material. + hit_obj->dirtyInventory(); + hit_obj->requestInventory(); + // TODO: Check to see if adding the item was successful; if not, then + // we should return false here. This will requre a separate listener + // since without listener, we have no way to receive update + } + return TRUE; +} + +void set_texture_to_material(LLViewerObject* hit_obj, + S32 hit_face, + const LLUUID& asset_id, + LLGLTFMaterial::TextureInfo drop_channel) +{ + LLTextureEntry* te = hit_obj->getTE(hit_face); + if (!te) + { + return; + } + + const LLUUID base_mat_id = hit_obj->getRenderMaterialID(hit_face); + if (base_mat_id.isNull()) + { + return; + } + + if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners()) + { + hit_obj->requestInventory(); + return; + } + + LLViewerInventoryItem* mat_item = hit_obj->getInventoryItemByAsset(base_mat_id); + if (mat_item && !mat_item->getPermissions().allowModifyBy(gAgentID)) + { + return; + } + + LLPointer material = te->getGLTFMaterialOverride(); + + // make a copy to not invalidate existing + // material for multiple objects + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(); + } + else + { + material = new LLGLTFMaterial(*material); + } + + switch (drop_channel) + { + case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: + default: + { + material->setBaseColorId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: + { + material->setOcclusionRoughnessMetallicId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: + { + material->setEmissiveId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: + { + material->setNormalId(asset_id); + } + break; + } + LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); +} + +void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id, + bool remove_pbr) +{ + if (!item) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << LL_ENDL; + return; + } + S32 num_faces = hit_obj->getNumTEs(); + bool has_non_pbr_faces = false; + for (S32 face = 0; face < num_faces; face++) + { + if (hit_obj->getRenderMaterialID(face).isNull()) + { + has_non_pbr_faces = true; + break; + } + } + + if (has_non_pbr_faces || remove_pbr) + { + BOOL res = handleDropMaterialProtections(hit_obj, item, source, src_id); + if (!res) + { + return; + } + } + LLUUID asset_id = item->getAssetUUID(); + + // Overrides require textures to be copy and transfer free + LLPermissions item_permissions = item->getPermissions(); + bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()); + allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + add(LLStatViewer::EDIT_TEXTURE, 1); + for( S32 face = 0; face < num_faces; face++ ) + { + if (remove_pbr) { hit_obj->setRenderMaterialID(face, LLUUID::null); hit_obj->setTEImage(face, image); @@ -1201,11 +1201,11 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, { set_texture_to_material(hit_obj, face, asset_id, LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR); } - } + } - // send the update to the simulator + // send the update to the simulator LLGLTFMaterialList::flushUpdates(nullptr); - hit_obj->sendTEUpdate(); + hit_obj->sendTEUpdate(); } void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj, @@ -1329,35 +1329,35 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id) -{ - if (!item) - { - LL_WARNS() << "no inventory item." << LL_ENDL; - return; - } - LLUUID asset_id = item->getAssetUUID(); - BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); - if(!success) - { - return; - } - - LLSculptParams sculpt_params; - sculpt_params.setSculptTexture(asset_id, LL_SCULPT_TYPE_MESH); - hit_obj->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); - - dialog_refresh_all(); -} - -void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, - S32 hit_face, - LLInventoryItem* item, - ESource source, - const LLUUID& src_id, - bool all_faces, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (!item) + { + LL_WARNS() << "no inventory item." << LL_ENDL; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); + if(!success) + { + return; + } + + LLSculptParams sculpt_params; + sculpt_params.setSculptTexture(asset_id, LL_SCULPT_TYPE_MESH); + hit_obj->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); + + dialog_refresh_all(); +} + +void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, + S32 hit_face, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id, + bool all_faces, bool remove_pbr, S32 tex_channel) { @@ -1454,19 +1454,19 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, } void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, - S32 hit_face, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id, + S32 hit_face, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id, bool remove_pbr, S32 tex_channel) { - if (hit_face == -1) return; - if (!item) - { - LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL; - return; - } + if (hit_face == -1) return; + if (!item) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL; + return; + } LLUUID asset_id = item->getAssetUUID(); @@ -1490,593 +1490,593 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, } return; } - BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); - if (!success) - { - return; - } + BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); + if (!success) + { + return; + } if (remove_pbr) { hit_obj->setRenderMaterialID(hit_face, LLUUID::null); } - // update viewer side image in anticipation of update from simulator - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - add(LLStatViewer::EDIT_TEXTURE, 1); + // update viewer side image in anticipation of update from simulator + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + add(LLStatViewer::EDIT_TEXTURE, 1); - LLTextureEntry* tep = hit_obj->getTE(hit_face); + LLTextureEntry* tep = hit_obj->getTE(hit_face); - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + LLPanelFace* panel_face = gFloaterTools->getPanelFace(); - if (gFloaterTools->getVisible() && panel_face) - { + if (gFloaterTools->getVisible() && panel_face) + { tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel(); switch (tex_channel) - { + { - case 0: - default: - { - hit_obj->setTEImage(hit_face, image); - } - break; + case 0: + default: + { + hit_obj->setTEImage(hit_face, image); + } + break; - case 1: + case 1: if (tep) - { - LLMaterialPtr old_mat = tep->getMaterialParams(); - LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); - new_mat->setNormalID(asset_id); - tep->setMaterialParams(new_mat); - hit_obj->setTENormalMap(hit_face, asset_id); - LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); - } - break; - - case 2: + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setNormalID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTENormalMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + + case 2: if (tep) - { - LLMaterialPtr old_mat = tep->getMaterialParams(); - LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); - new_mat->setSpecularID(asset_id); - tep->setMaterialParams(new_mat); - hit_obj->setTESpecularMap(hit_face, asset_id); - LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); - } - break; - } - } - else - { - hit_obj->setTEImage(hit_face, image); - } - - dialog_refresh_all(); - - // send the update to the simulator - hit_obj->sendTEUpdate(); + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setSpecularID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTESpecularMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + } + } + else + { + hit_obj->setTEImage(hit_face, image); + } + + dialog_refresh_all(); + + // send the update to the simulator + hit_obj->sendTEUpdate(); } void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj, - LLInventoryItem* item, - BOOL active, - ESource source, - const LLUUID& src_id) -{ - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource) - || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource)) - { - LL_WARNS() << "Call to LLToolDragAndDrop::dropScript() from world" - << " or notecard." << LL_ENDL; - return; - } - if (hit_obj && item) - { - LLPointer new_script = new LLViewerInventoryItem(item); - if (!item->getPermissions().allowCopyBy(gAgent.getID())) - { - if (SOURCE_AGENT == source) - { - // Remove the script from local inventory. The server - // will actually remove the item from agent inventory. - gInventory.deleteObject(item->getUUID()); - gInventory.notifyObservers(); - } - else if (SOURCE_WORLD == source) - { - // *FIX: if the objects are in different regions, and - // the source region has crashed, you can bypass - // these permissions. - LLViewerObject* src_obj = gObjectList.findObject(src_id); - if (src_obj) - { - src_obj->removeInventory(item->getUUID()); - } - else - { - LL_WARNS() << "Unable to find source object." << LL_ENDL; - return; - } - } - } - hit_obj->saveScript(new_script, active, true); - gFloaterTools->dirty(); - - // VEFFECT: SetScript - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(hit_obj); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - } + LLInventoryItem* item, + BOOL active, + ESource source, + const LLUUID& src_id) +{ + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource) + || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource)) + { + LL_WARNS() << "Call to LLToolDragAndDrop::dropScript() from world" + << " or notecard." << LL_ENDL; + return; + } + if (hit_obj && item) + { + LLPointer new_script = new LLViewerInventoryItem(item); + if (!item->getPermissions().allowCopyBy(gAgent.getID())) + { + if (SOURCE_AGENT == source) + { + // Remove the script from local inventory. The server + // will actually remove the item from agent inventory. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + else if (SOURCE_WORLD == source) + { + // *FIX: if the objects are in different regions, and + // the source region has crashed, you can bypass + // these permissions. + LLViewerObject* src_obj = gObjectList.findObject(src_id); + if (src_obj) + { + src_obj->removeInventory(item->getUUID()); + } + else + { + LL_WARNS() << "Unable to find source object." << LL_ENDL; + return; + } + } + } + hit_obj->saveScript(new_script, active, true); + gFloaterTools->dirty(); + + // VEFFECT: SetScript + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(hit_obj); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } } void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, - BOOL bypass_sim_raycast, - BOOL from_task_inventory, - BOOL remove_from_inventory) -{ - LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos); - if (!regionp) - { - LL_WARNS() << "Couldn't find region to rez object" << LL_ENDL; - return; - } - - //LL_INFOS() << "Rezzing object" << LL_ENDL; - make_ui_sound("UISndObjectRezIn"); - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return; - - //if (regionp - // && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))) - //{ - // LLFirstUse::useSandbox(); - //} - // check if it cannot be copied, and mark as remove if it is - - // this will remove the object from inventory after rez. Only - // bother with this check if we would not normally remove from - // inventory. - if (!remove_from_inventory - && !item->getPermissions().allowCopyBy(gAgent.getID())) - { - remove_from_inventory = TRUE; - } - - // Limit raycast to a single object. - // Speeds up server raycast + avoid problems with server ray - // hitting objects that were clipped by the near plane or culled - // on the viewer. - LLUUID ray_target_id; - if (raycast_target) - { - ray_target_id = raycast_target->getID(); - } - else - { - ray_target_id.setNull(); - } - - // Check if it's in the trash. - bool is_in_trash = false; - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) - { - is_in_trash = true; - } - - LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null; - - // Select the object only if we're editing. - BOOL rez_selected = LLToolMgr::getInstance()->inEdit(); - - - LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos); - LLVector3 ray_end = regionp->getPosRegionFromGlobal(mLastHitPos); - // currently the ray's end point is an approximation, - // and is sometimes too short (causing failure.) so we - // double the ray's length: - if (bypass_sim_raycast == FALSE) - { - LLVector3 ray_direction = ray_start - ray_end; - ray_end = ray_end - ray_direction; - } - - - // Message packing code should be it's own uninterrupted block - LLMessageSystem* msg = gMessageSystem; - if (mSource == SOURCE_NOTECARD) - { - LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard"); - msg->newMessageFast(_PREHASH_RezObjectFromNotecard); - } - else - { - LLUIUsage::instance().logCommand("Object.RezObject"); - msg->newMessageFast(_PREHASH_RezObject); - } - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - - msg->nextBlock("RezData"); - // if it's being rezzed from task inventory, we need to enable - // saving it back into the task inventory. - // *FIX: We can probably compress this to a single byte, since I - // think folderid == mSourceID. This will be a later - // optimization. - msg->addUUIDFast(_PREHASH_FromTaskID, source_id); - msg->addU8Fast(_PREHASH_BypassRaycast, (U8) bypass_sim_raycast); - msg->addVector3Fast(_PREHASH_RayStart, ray_start); - msg->addVector3Fast(_PREHASH_RayEnd, ray_end); - msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id ); - msg->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE); - msg->addBOOLFast(_PREHASH_RezSelected, rez_selected); - msg->addBOOLFast(_PREHASH_RemoveItem, remove_from_inventory); - - // deal with permissions slam logic - pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); - - LLUUID folder_id = item->getParentUUID(); - if ((SOURCE_LIBRARY == mSource) || (is_in_trash)) - { - // since it's coming from the library or trash, we want to not - // 'take' it back to the same place. - item->setParent(LLUUID::null); - // *TODO this code isn't working - the parent (FolderID) is still - // set when the object is "taken". so code on the "take" side is - // checking for trash and library as well (llviewermenu.cpp) - } - if (mSource == SOURCE_NOTECARD) - { - msg->nextBlockFast(_PREHASH_NotecardData); - msg->addUUIDFast(_PREHASH_NotecardItemID, mSourceID); - msg->addUUIDFast(_PREHASH_ObjectID, mObjectID); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addUUIDFast(_PREHASH_ItemID, item->getUUID()); - } - else - { - msg->nextBlockFast(_PREHASH_InventoryData); - item->packMessage(msg); - } - msg->sendReliable(regionp->getHost()); - // back out the change. no actual internal changes take place. - item->setParent(folder_id); - - // If we're going to select it, get ready for the incoming - // selected object. - if (rez_selected) - { - LLSelectMgr::getInstance()->deselectAll(); - gViewerWindow->getWindow()->incBusyCount(); - } - - if (remove_from_inventory) - { - // Delete it from inventory immediately so that users cannot - // easily bypass copy protection in laggy situations. If the - // rez fails, we will put it back on the server. - gInventory.deleteObject(item->getUUID()); - gInventory.notifyObservers(); - } - - // VEFFECT: DropObject - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setPositionGlobal(mLastHitPos); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - - add(LLStatViewer::OBJECT_REZ, 1); + BOOL bypass_sim_raycast, + BOOL from_task_inventory, + BOOL remove_from_inventory) +{ + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos); + if (!regionp) + { + LL_WARNS() << "Couldn't find region to rez object" << LL_ENDL; + return; + } + + //LL_INFOS() << "Rezzing object" << LL_ENDL; + make_ui_sound("UISndObjectRezIn"); + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return; + + //if (regionp + // && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))) + //{ + // LLFirstUse::useSandbox(); + //} + // check if it cannot be copied, and mark as remove if it is - + // this will remove the object from inventory after rez. Only + // bother with this check if we would not normally remove from + // inventory. + if (!remove_from_inventory + && !item->getPermissions().allowCopyBy(gAgent.getID())) + { + remove_from_inventory = TRUE; + } + + // Limit raycast to a single object. + // Speeds up server raycast + avoid problems with server ray + // hitting objects that were clipped by the near plane or culled + // on the viewer. + LLUUID ray_target_id; + if (raycast_target) + { + ray_target_id = raycast_target->getID(); + } + else + { + ray_target_id.setNull(); + } + + // Check if it's in the trash. + bool is_in_trash = false; + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + { + is_in_trash = true; + } + + LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null; + + // Select the object only if we're editing. + BOOL rez_selected = LLToolMgr::getInstance()->inEdit(); + + + LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos); + LLVector3 ray_end = regionp->getPosRegionFromGlobal(mLastHitPos); + // currently the ray's end point is an approximation, + // and is sometimes too short (causing failure.) so we + // double the ray's length: + if (bypass_sim_raycast == FALSE) + { + LLVector3 ray_direction = ray_start - ray_end; + ray_end = ray_end - ray_direction; + } + + + // Message packing code should be it's own uninterrupted block + LLMessageSystem* msg = gMessageSystem; + if (mSource == SOURCE_NOTECARD) + { + LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard"); + msg->newMessageFast(_PREHASH_RezObjectFromNotecard); + } + else + { + LLUIUsage::instance().logCommand("Object.RezObject"); + msg->newMessageFast(_PREHASH_RezObject); + } + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + + msg->nextBlock("RezData"); + // if it's being rezzed from task inventory, we need to enable + // saving it back into the task inventory. + // *FIX: We can probably compress this to a single byte, since I + // think folderid == mSourceID. This will be a later + // optimization. + msg->addUUIDFast(_PREHASH_FromTaskID, source_id); + msg->addU8Fast(_PREHASH_BypassRaycast, (U8) bypass_sim_raycast); + msg->addVector3Fast(_PREHASH_RayStart, ray_start); + msg->addVector3Fast(_PREHASH_RayEnd, ray_end); + msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id ); + msg->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE); + msg->addBOOLFast(_PREHASH_RezSelected, rez_selected); + msg->addBOOLFast(_PREHASH_RemoveItem, remove_from_inventory); + + // deal with permissions slam logic + pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); + + LLUUID folder_id = item->getParentUUID(); + if ((SOURCE_LIBRARY == mSource) || (is_in_trash)) + { + // since it's coming from the library or trash, we want to not + // 'take' it back to the same place. + item->setParent(LLUUID::null); + // *TODO this code isn't working - the parent (FolderID) is still + // set when the object is "taken". so code on the "take" side is + // checking for trash and library as well (llviewermenu.cpp) + } + if (mSource == SOURCE_NOTECARD) + { + msg->nextBlockFast(_PREHASH_NotecardData); + msg->addUUIDFast(_PREHASH_NotecardItemID, mSourceID); + msg->addUUIDFast(_PREHASH_ObjectID, mObjectID); + msg->nextBlockFast(_PREHASH_InventoryData); + msg->addUUIDFast(_PREHASH_ItemID, item->getUUID()); + } + else + { + msg->nextBlockFast(_PREHASH_InventoryData); + item->packMessage(msg); + } + msg->sendReliable(regionp->getHost()); + // back out the change. no actual internal changes take place. + item->setParent(folder_id); + + // If we're going to select it, get ready for the incoming + // selected object. + if (rez_selected) + { + LLSelectMgr::getInstance()->deselectAll(); + gViewerWindow->getWindow()->incBusyCount(); + } + + if (remove_from_inventory) + { + // Delete it from inventory immediately so that users cannot + // easily bypass copy protection in laggy situations. If the + // rez fails, we will put it back on the server. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + + // VEFFECT: DropObject + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setPositionGlobal(mLastHitPos); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + + add(LLStatViewer::OBJECT_REZ, 1); } void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, - LLInventoryItem* item, - LLToolDragAndDrop::ESource source, - const LLUUID& src_id) -{ - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource) - || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource)) - { - LL_WARNS() << "Call to LLToolDragAndDrop::dropInventory() from world" - << " or notecard." << LL_ENDL; - return; - } - - LLPointer new_item = new LLViewerInventoryItem(item); - time_t creation_date = time_corrected(); - new_item->setCreationDate(creation_date); - - if (!item->getPermissions().allowCopyBy(gAgent.getID())) - { - if (SOURCE_AGENT == source) - { - // Remove the inventory item from local inventory. The - // server will actually remove the item from agent - // inventory. - gInventory.deleteObject(item->getUUID()); - gInventory.notifyObservers(); - } - else if (SOURCE_WORLD == source) - { - // *FIX: if the objects are in different regions, and the - // source region has crashed, you can bypass these - // permissions. - LLViewerObject* src_obj = gObjectList.findObject(src_id); - if (src_obj) - { - src_obj->removeInventory(item->getUUID()); - } - else - { - LL_WARNS() << "Unable to find source object." << LL_ENDL; - return; - } - } - } - hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); - if (LLFloaterReg::instanceVisible("build")) - { - // *FIX: only show this if panel not expanded? - LLFloaterReg::showInstance("build", "Content"); - } - - // VEFFECT: AddToInventory - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(hit_obj); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource) + || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource)) + { + LL_WARNS() << "Call to LLToolDragAndDrop::dropInventory() from world" + << " or notecard." << LL_ENDL; + return; + } + + LLPointer new_item = new LLViewerInventoryItem(item); + time_t creation_date = time_corrected(); + new_item->setCreationDate(creation_date); + + if (!item->getPermissions().allowCopyBy(gAgent.getID())) + { + if (SOURCE_AGENT == source) + { + // Remove the inventory item from local inventory. The + // server will actually remove the item from agent + // inventory. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + else if (SOURCE_WORLD == source) + { + // *FIX: if the objects are in different regions, and the + // source region has crashed, you can bypass these + // permissions. + LLViewerObject* src_obj = gObjectList.findObject(src_id); + if (src_obj) + { + src_obj->removeInventory(item->getUUID()); + } + else + { + LL_WARNS() << "Unable to find source object." << LL_ENDL; + return; + } + } + } + hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + if (LLFloaterReg::instanceVisible("build")) + { + // *FIX: only show this if panel not expanded? + LLFloaterReg::showInstance("build", "Content"); + } + + // VEFFECT: AddToInventory + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(hit_obj); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + gFloaterTools->dirty(); } // accessor that looks at permissions, copyability, and names of // inventory items to determine if a drop would be ok. EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item, EDragAndDropType type) { - // check the basics - if (!item || !obj) return ACCEPT_NO; - // HACK: downcast - LLViewerInventoryItem* vitem = (LLViewerInventoryItem*)item; - if (!vitem->isFinished() && (type != DAD_CATEGORY)) - { - // Note: for DAD_CATEGORY we assume that folder version check passed and folder - // is complete, meaning that items inside are up to date. - // (isFinished() == false) at the moment shows that item was loaded from cache. - // Library or agent inventory only. - return ACCEPT_NO; - } - if (vitem->getIsLinkType()) return ACCEPT_NO; // No giving away links - - // deny attempts to drop from an object onto itself. This is to - // help make sure that drops that are from an object to an object - // don't have to worry about order of evaluation. Think of this - // like check for self in assignment. - if(obj->getID() == item->getParentUUID()) - { - return ACCEPT_NO; - } - - //BOOL copy = (perm.allowCopyBy(gAgent.getID(), - // gAgent.getGroupID()) - // && (obj->mPermModify || obj->mFlagAllowInventoryAdd)); - BOOL worn = FALSE; - LLVOAvatarSelf* my_avatar = NULL; - switch(item->getType()) - { - case LLAssetType::AT_OBJECT: - my_avatar = gAgentAvatarp; - if(my_avatar && my_avatar->isWearingAttachment(item->getUUID())) - { - worn = TRUE; - } - break; - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if(gAgentWearables.isWearingItem(item->getUUID())) - { - worn = TRUE; - } - break; - case LLAssetType::AT_CALLINGCARD: - // Calling Cards in object are disabled for now - // because of incomplete LSL support. See STORM-1117. - return ACCEPT_NO; - default: - break; - } - const LLPermissions& perm = item->getPermissions(); - BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd()); - BOOL transfer = FALSE; - if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID())) - || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID())) - { - transfer = TRUE; - } - BOOL volume = (LL_PCODE_VOLUME == obj->getPCode()); - BOOL attached = obj->isAttachment(); - BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; - if(attached && !unrestricted) - { + // check the basics + if (!item || !obj) return ACCEPT_NO; + // HACK: downcast + LLViewerInventoryItem* vitem = (LLViewerInventoryItem*)item; + if (!vitem->isFinished() && (type != DAD_CATEGORY)) + { + // Note: for DAD_CATEGORY we assume that folder version check passed and folder + // is complete, meaning that items inside are up to date. + // (isFinished() == false) at the moment shows that item was loaded from cache. + // Library or agent inventory only. + return ACCEPT_NO; + } + if (vitem->getIsLinkType()) return ACCEPT_NO; // No giving away links + + // deny attempts to drop from an object onto itself. This is to + // help make sure that drops that are from an object to an object + // don't have to worry about order of evaluation. Think of this + // like check for self in assignment. + if(obj->getID() == item->getParentUUID()) + { + return ACCEPT_NO; + } + + //BOOL copy = (perm.allowCopyBy(gAgent.getID(), + // gAgent.getGroupID()) + // && (obj->mPermModify || obj->mFlagAllowInventoryAdd)); + BOOL worn = FALSE; + LLVOAvatarSelf* my_avatar = NULL; + switch(item->getType()) + { + case LLAssetType::AT_OBJECT: + my_avatar = gAgentAvatarp; + if(my_avatar && my_avatar->isWearingAttachment(item->getUUID())) + { + worn = TRUE; + } + break; + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + if(gAgentWearables.isWearingItem(item->getUUID())) + { + worn = TRUE; + } + break; + case LLAssetType::AT_CALLINGCARD: + // Calling Cards in object are disabled for now + // because of incomplete LSL support. See STORM-1117. + return ACCEPT_NO; + default: + break; + } + const LLPermissions& perm = item->getPermissions(); + BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd()); + BOOL transfer = FALSE; + if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID())) + || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID())) + { + transfer = TRUE; + } + BOOL volume = (LL_PCODE_VOLUME == obj->getPCode()); + BOOL attached = obj->isAttachment(); + BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; + if(attached && !unrestricted) + { // Attachments are in world and in inventory simultaneously, // at the moment server doesn't support such a situation. - return ACCEPT_NO_LOCKED; - } - else if(modify && transfer && volume && !worn) - { - return ACCEPT_YES_MULTI; - } - else if(!modify) - { - return ACCEPT_NO_LOCKED; - } - return ACCEPT_NO; + return ACCEPT_NO_LOCKED; + } + else if(modify && transfer && volume && !worn) + { + return ACCEPT_YES_MULTI; + } + else if(!modify) + { + return ACCEPT_NO_LOCKED; + } + return ACCEPT_NO; } static void give_inventory_cb(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - // if Cancel pressed - if (option == 1) - { - return; - } - - LLSD payload = notification["payload"]; - const LLUUID& session_id = payload["session_id"]; - const LLUUID& agent_id = payload["agent_id"]; - LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]); - LLViewerInventoryCategory * inv_cat = gInventory.getCategory(payload["item_id"]); - if (NULL == inv_item && NULL == inv_cat) - { - llassert( FALSE ); - return; - } - bool successfully_shared; - if (inv_item) - { - successfully_shared = LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id); - } - else - { - successfully_shared = LLGiveInventory::doGiveInventoryCategory(agent_id, inv_cat, session_id); - } - if (successfully_shared) - { - if ("avatarpicker" == payload["d&d_dest"].asString()) - { - LLFloaterReg::hideInstance("avatar_picker"); - } - LLNotificationsUtil::add("ItemsShared"); - } + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } + + LLSD payload = notification["payload"]; + const LLUUID& session_id = payload["session_id"]; + const LLUUID& agent_id = payload["agent_id"]; + LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]); + LLViewerInventoryCategory * inv_cat = gInventory.getCategory(payload["item_id"]); + if (NULL == inv_item && NULL == inv_cat) + { + llassert( FALSE ); + return; + } + bool successfully_shared; + if (inv_item) + { + successfully_shared = LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id); + } + else + { + successfully_shared = LLGiveInventory::doGiveInventoryCategory(agent_id, inv_cat, session_id); + } + if (successfully_shared) + { + if ("avatarpicker" == payload["d&d_dest"].asString()) + { + LLFloaterReg::hideInstance("avatar_picker"); + } + LLNotificationsUtil::add("ItemsShared"); + } } static void show_object_sharing_confirmation(const std::string name, - LLInventoryObject* inv_item, - const LLSD& dest, - const LLUUID& dest_agent, - const LLUUID& session_id = LLUUID::null) -{ - if (!inv_item) - { - llassert(NULL != inv_item); - return; - } - LLSD substitutions; - substitutions["RESIDENTS"] = name; - substitutions["ITEMS"] = inv_item->getName(); - LLSD payload; - payload["agent_id"] = dest_agent; - payload["item_id"] = inv_item->getUUID(); - payload["session_id"] = session_id; - payload["d&d_dest"] = dest.asString(); - LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); + LLInventoryObject* inv_item, + const LLSD& dest, + const LLUUID& dest_agent, + const LLUUID& session_id = LLUUID::null) +{ + if (!inv_item) + { + llassert(NULL != inv_item); + return; + } + LLSD substitutions; + substitutions["RESIDENTS"] = name; + substitutions["ITEMS"] = inv_item->getName(); + LLSD payload; + payload["agent_id"] = dest_agent; + payload["item_id"] = inv_item->getUUID(); + payload["session_id"] = session_id; + payload["d&d_dest"] = dest.asString(); + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); } static void get_name_cb(const LLUUID& id, - const LLAvatarName& av_name, - LLInventoryObject* inv_obj, - const LLSD& dest, - const LLUUID& dest_agent) + const LLAvatarName& av_name, + LLInventoryObject* inv_obj, + const LLSD& dest, + const LLUUID& dest_agent) { - show_object_sharing_confirmation(av_name.getUserName(), - inv_obj, - dest, - id, - LLUUID::null); + show_object_sharing_confirmation(av_name.getUserName(), + inv_obj, + dest, + id, + LLUUID::null); } // function used as drag-and-drop handler for simple agent give inventory requests //static bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - const LLSD& dest) -{ - // check the type - switch(cargo_type) - { - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_CLOTHING: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: - case DAD_CALLINGCARD: - case DAD_MESH: - case DAD_CATEGORY: + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + const LLSD& dest) +{ + // check the type + switch(cargo_type) + { + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_CLOTHING: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_CALLINGCARD: + case DAD_MESH: + case DAD_CATEGORY: case DAD_SETTINGS: case DAD_MATERIAL: - { - LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data; - if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID()) - && LLGiveInventory::isInventoryGiveAcceptable(dynamic_cast(inv_obj)))) - { - // *TODO: get multiple object transfers working - *accept = ACCEPT_YES_COPY_SINGLE; - if(drop) - { - LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); - - // If no IM session found get the destination agent's name by id. - if (NULL == session) - { - LLAvatarName av_name; - - // If destination agent's name is found in cash proceed to showing the confirmation dialog. - // Otherwise set up a callback to show the dialog when the name arrives. - if (LLAvatarNameCache::get(dest_agent, &av_name)) - { - show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null); - } - else - { - LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent)); - } - - return true; - } - std::string dest_name = session->mName; - LLAvatarName av_name; - if(LLAvatarNameCache::get(dest_agent, &av_name)) - { - dest_name = av_name.getCompleteName(); - } - // If an IM session with destination agent is found item offer will be logged in this session. - show_object_sharing_confirmation(dest_name, inv_obj, dest, dest_agent, session_id); - } - } - else - { - // It's not in the user's inventory (it's probably - // in an object's contents), so disallow dragging - // it here. You can't give something you don't - // yet have. - *accept = ACCEPT_NO; - } - break; - } - default: - *accept = ACCEPT_NO; - break; - } - - return TRUE; + { + LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data; + if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID()) + && LLGiveInventory::isInventoryGiveAcceptable(dynamic_cast(inv_obj)))) + { + // *TODO: get multiple object transfers working + *accept = ACCEPT_YES_COPY_SINGLE; + if(drop) + { + LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); + + // If no IM session found get the destination agent's name by id. + if (NULL == session) + { + LLAvatarName av_name; + + // If destination agent's name is found in cash proceed to showing the confirmation dialog. + // Otherwise set up a callback to show the dialog when the name arrives. + if (LLAvatarNameCache::get(dest_agent, &av_name)) + { + show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null); + } + else + { + LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent)); + } + + return true; + } + std::string dest_name = session->mName; + LLAvatarName av_name; + if(LLAvatarNameCache::get(dest_agent, &av_name)) + { + dest_name = av_name.getCompleteName(); + } + // If an IM session with destination agent is found item offer will be logged in this session. + show_object_sharing_confirmation(dest_name, inv_obj, dest, dest_agent, session_id); + } + } + else + { + // It's not in the user's inventory (it's probably + // in an object's contents), so disallow dragging + // it here. You can't give something you don't + // yet have. + *accept = ACCEPT_NO; + } + break; + } + default: + *accept = ACCEPT_NO; + break; + } + + return TRUE; } @@ -2086,278 +2086,278 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ /// EAcceptance LLToolDragAndDrop::dad3dNULL( - LLViewerObject*, S32, MASK, BOOL) + LLViewerObject*, S32, MASK, BOOL) { - LL_DEBUGS() << "LLToolDragAndDrop::dad3dNULL()" << LL_ENDL; - return ACCEPT_NO; + LL_DEBUGS() << "LLToolDragAndDrop::dad3dNULL()" << LL_ENDL; + return ACCEPT_NO; } EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << LL_ENDL; - // must be in the user's inventory - if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) - { - return ACCEPT_NO; - } - - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - - // must not be in the trash - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) - { - return ACCEPT_NO; - } - - // must not be already wearing it - LLVOAvatarSelf* avatar = gAgentAvatarp; - if( !avatar || avatar->isWearingAttachment(item->getUUID()) ) - { - return ACCEPT_NO; - } - - const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX); - if(outbox_id.notNull() && gInventory.isObjectDescendentOf(item->getUUID(), outbox_id)) - { - // Legacy - return ACCEPT_NO; - } - - - if( drop ) - { - if(mSource == SOURCE_LIBRARY) - { - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0)); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - rez_attachment(item, 0); - } - } - return ACCEPT_YES_SINGLE; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << LL_ENDL; + // must be in the user's inventory + if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) + { + return ACCEPT_NO; + } + + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + + // must not be in the trash + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) + { + return ACCEPT_NO; + } + + // must not be already wearing it + LLVOAvatarSelf* avatar = gAgentAvatarp; + if( !avatar || avatar->isWearingAttachment(item->getUUID()) ) + { + return ACCEPT_NO; + } + + const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX); + if(outbox_id.notNull() && gInventory.isObjectDescendentOf(item->getUUID(), outbox_id)) + { + // Legacy + return ACCEPT_NO; + } + + + if( drop ) + { + if(mSource == SOURCE_LIBRARY) + { + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0)); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + else + { + rez_attachment(item, 0); + } + } + return ACCEPT_YES_SINGLE; +} + + +EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + if (mSource == SOURCE_WORLD) + { + return dad3dRezFromObjectOnLand(obj, face, mask, drop); + } + + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnLand()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + + LLVOAvatarSelf* my_avatar = gAgentAvatarp; + if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) + { + return ACCEPT_NO; + } + + EAcceptance accept; + BOOL remove_inventory; + + // Get initial settings based on shift key + if (mask & MASK_SHIFT) + { + // For now, always make copy + //accept = ACCEPT_YES_SINGLE; + //remove_inventory = TRUE; + accept = ACCEPT_YES_COPY_SINGLE; + remove_inventory = FALSE; + } + else + { + accept = ACCEPT_YES_COPY_SINGLE; + remove_inventory = FALSE; + } + + // check if the item can be copied. If not, send that to the sim + // which will remove the inventory item. + if(!item->getPermissions().allowCopyBy(gAgent.getID())) + { + accept = ACCEPT_YES_SINGLE; + remove_inventory = TRUE; + } + + // Check if it's in the trash. + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + { + accept = ACCEPT_YES_SINGLE; + } + + if(drop) + { + dropObject(obj, TRUE, FALSE, remove_inventory); + } + + return accept; +} + +EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + // handle objects coming from object inventory + if (mSource == SOURCE_WORLD) + { + return dad3dRezFromObjectOnObject(obj, face, mask, drop); + } + + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnObject()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + LLVOAvatarSelf* my_avatar = gAgentAvatarp; + if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) + { + return ACCEPT_NO; + } + + if((mask & MASK_CONTROL)) + { + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if(mSource == SOURCE_NOTECARD) + { + return ACCEPT_NO; + } + + EAcceptance rv = willObjectAcceptInventory(obj, item); + if(drop && (ACCEPT_YES_SINGLE <= rv)) + { + dropInventory(obj, item, mSource, mSourceID); + } + return rv; + } + + EAcceptance accept; + BOOL remove_inventory; + + if (mask & MASK_SHIFT) + { + // For now, always make copy + //accept = ACCEPT_YES_SINGLE; + //remove_inventory = TRUE; + accept = ACCEPT_YES_COPY_SINGLE; + remove_inventory = FALSE; + } + else + { + accept = ACCEPT_YES_COPY_SINGLE; + remove_inventory = FALSE; + } + + // check if the item can be copied. If not, send that to the sim + // which will remove the inventory item. + if(!item->getPermissions().allowCopyBy(gAgent.getID())) + { + accept = ACCEPT_YES_SINGLE; + remove_inventory = TRUE; + } + + // Check if it's in the trash. + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + { + accept = ACCEPT_YES_SINGLE; + remove_inventory = TRUE; + } + + if(drop) + { + dropObject(obj, FALSE, FALSE, remove_inventory); + } + + return accept; } +EAcceptance LLToolDragAndDrop::dad3dRezScript( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezScript()" << LL_ENDL; + + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) + { + return ACCEPT_NO; + } -EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - if (mSource == SOURCE_WORLD) - { - return dad3dRezFromObjectOnLand(obj, face, mask, drop); - } - - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnLand()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - - LLVOAvatarSelf* my_avatar = gAgentAvatarp; - if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) - { - return ACCEPT_NO; - } - - EAcceptance accept; - BOOL remove_inventory; - - // Get initial settings based on shift key - if (mask & MASK_SHIFT) - { - // For now, always make copy - //accept = ACCEPT_YES_SINGLE; - //remove_inventory = TRUE; - accept = ACCEPT_YES_COPY_SINGLE; - remove_inventory = FALSE; - } - else - { - accept = ACCEPT_YES_COPY_SINGLE; - remove_inventory = FALSE; - } - - // check if the item can be copied. If not, send that to the sim - // which will remove the inventory item. - if(!item->getPermissions().allowCopyBy(gAgent.getID())) - { - accept = ACCEPT_YES_SINGLE; - remove_inventory = TRUE; - } - - // Check if it's in the trash. - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) - { - accept = ACCEPT_YES_SINGLE; - } - - if(drop) - { - dropObject(obj, TRUE, FALSE, remove_inventory); - } - - return accept; -} + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + EAcceptance rv = willObjectAcceptInventory(obj, item); + if(drop && (ACCEPT_YES_SINGLE <= rv)) + { + // rez in the script active by default, rez in inactive if the + // control key is being held down. + BOOL active = ((mask & MASK_CONTROL) == 0); -EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - // handle objects coming from object inventory - if (mSource == SOURCE_WORLD) - { - return dad3dRezFromObjectOnObject(obj, face, mask, drop); - } - - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnObject()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - LLVOAvatarSelf* my_avatar = gAgentAvatarp; - if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) - { - return ACCEPT_NO; - } - - if((mask & MASK_CONTROL)) - { - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if(mSource == SOURCE_NOTECARD) - { - return ACCEPT_NO; - } - - EAcceptance rv = willObjectAcceptInventory(obj, item); - if(drop && (ACCEPT_YES_SINGLE <= rv)) - { - dropInventory(obj, item, mSource, mSourceID); - } - return rv; - } - - EAcceptance accept; - BOOL remove_inventory; - - if (mask & MASK_SHIFT) - { - // For now, always make copy - //accept = ACCEPT_YES_SINGLE; - //remove_inventory = TRUE; - accept = ACCEPT_YES_COPY_SINGLE; - remove_inventory = FALSE; - } - else - { - accept = ACCEPT_YES_COPY_SINGLE; - remove_inventory = FALSE; - } - - // check if the item can be copied. If not, send that to the sim - // which will remove the inventory item. - if(!item->getPermissions().allowCopyBy(gAgent.getID())) - { - accept = ACCEPT_YES_SINGLE; - remove_inventory = TRUE; - } - - // Check if it's in the trash. - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) - { - accept = ACCEPT_YES_SINGLE; - remove_inventory = TRUE; - } - - if(drop) - { - dropObject(obj, FALSE, FALSE, remove_inventory); - } - - return accept; -} + LLViewerObject* root_object = obj; + if (obj && obj->getParent()) + { + LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); + if (!parent_obj->isAvatar()) + { + root_object = parent_obj; + } + } -EAcceptance LLToolDragAndDrop::dad3dRezScript( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezScript()" << LL_ENDL; - - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) - { - return ACCEPT_NO; - } - - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - EAcceptance rv = willObjectAcceptInventory(obj, item); - if(drop && (ACCEPT_YES_SINGLE <= rv)) - { - // rez in the script active by default, rez in inactive if the - // control key is being held down. - BOOL active = ((mask & MASK_CONTROL) == 0); - - LLViewerObject* root_object = obj; - if (obj && obj->getParent()) - { - LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); - if (!parent_obj->isAvatar()) - { - root_object = parent_obj; - } - } - - dropScript(root_object, item, active, mSource, mSourceID); - } - return rv; + dropScript(root_object, item, active, mSource, mSourceID); + } + return rv; } EAcceptance LLToolDragAndDrop::dad3dApplyToObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dApplyToObject()" << LL_ENDL; - - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) - { - return ACCEPT_NO; - } - - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dApplyToObject()" << LL_ENDL; + + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) + { + return ACCEPT_NO; + } + + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; LLPermissions item_permissions = item->getPermissions(); - EAcceptance rv = willObjectAcceptInventory(obj, item); - if((mask & MASK_CONTROL)) - { - if((ACCEPT_YES_SINGLE <= rv) && drop) - { - dropInventory(obj, item, mSource, mSourceID); - } - return rv; - } - if(!obj->permModify()) - { - return ACCEPT_NO_LOCKED; - } + EAcceptance rv = willObjectAcceptInventory(obj, item); + if((mask & MASK_CONTROL)) + { + if((ACCEPT_YES_SINGLE <= rv) && drop) + { + dropInventory(obj, item, mSource, mSourceID); + } + return rv; + } + if(!obj->permModify()) + { + return ACCEPT_NO_LOCKED; + } if (cargo_type == DAD_TEXTURE && (mask & MASK_ALT) == 0) { @@ -2389,10 +2389,10 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( } } - if(drop && (ACCEPT_YES_SINGLE <= rv)) - { - if (cargo_type == DAD_TEXTURE) - { + if(drop && (ACCEPT_YES_SINGLE <= rv)) + { + if (cargo_type == DAD_TEXTURE) + { bool all_faces = mask & MASK_SHIFT; bool remove_pbr = mask & MASK_ALT; if (item_permissions.allowOperationBy(PERM_COPY, gAgent.getID())) @@ -2414,7 +2414,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( dropTexture(obj, face, item, source, source_id, all_faces, remove_pbr); }); } - } + } else if (cargo_type == DAD_MATERIAL) { bool all_faces = mask & MASK_SHIFT; @@ -2438,32 +2438,32 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( }); } } - else if (cargo_type == DAD_MESH) - { - dropMesh(obj, item, mSource, mSourceID); - } - else - { - LL_WARNS() << "unsupported asset type" << LL_ENDL; - } - - // VEFFECT: SetTexture - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(obj); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - } + else if (cargo_type == DAD_MESH) + { + dropMesh(obj, item, mSource, mSourceID); + } + else + { + LL_WARNS() << "unsupported asset type" << LL_ENDL; + } + + // VEFFECT: SetTexture + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(obj); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } - // enable multi-drop, although last texture will win - return ACCEPT_YES_MULTI; + // enable multi-drop, although last texture will win + return ACCEPT_YES_MULTI; } EAcceptance LLToolDragAndDrop::dad3dTextureObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { - return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); + return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); } EAcceptance LLToolDragAndDrop::dad3dMaterialObject( @@ -2473,506 +2473,506 @@ EAcceptance LLToolDragAndDrop::dad3dMaterialObject( } EAcceptance LLToolDragAndDrop::dad3dMeshObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { - return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH); + return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH); } EAcceptance LLToolDragAndDrop::dad3dWearItem( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearItem()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - - if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) - { - // it's in the agent inventory - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) - { - return ACCEPT_NO; - } - - if( drop ) - { - // TODO: investigate wearables may not be loaded at this point EXT-8231 - - LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); - } - return ACCEPT_YES_MULTI; - } - else - { - // TODO: copy/move item to avatar's inventory and then wear it. - return ACCEPT_NO; - } + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearItem()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + + if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) + { + // it's in the agent inventory + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) + { + return ACCEPT_NO; + } + + if( drop ) + { + // TODO: investigate wearables may not be loaded at this point EXT-8231 + + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); + } + return ACCEPT_YES_MULTI; + } + else + { + // TODO: copy/move item to avatar's inventory and then wear it. + return ACCEPT_NO; + } } EAcceptance LLToolDragAndDrop::dad3dActivateGesture( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dActivateGesture()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - - if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) - { - // it's in the agent inventory - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) - { - return ACCEPT_NO; - } - - if( drop ) - { - LLUUID item_id; - if(mSource == SOURCE_LIBRARY) - { - // create item based on that one, and put it on if that - // was a success. - LLPointer cb = new LLBoostFuncInventoryCallback(activate_gesture_cb); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - LLGestureMgr::instance().activateGesture(item->getUUID()); - gInventory.updateItem(item); - gInventory.notifyObservers(); - } - } - return ACCEPT_YES_MULTI; - } - else - { - return ACCEPT_NO; - } + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dActivateGesture()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + + if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) + { + // it's in the agent inventory + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) + { + return ACCEPT_NO; + } + + if( drop ) + { + LLUUID item_id; + if(mSource == SOURCE_LIBRARY) + { + // create item based on that one, and put it on if that + // was a success. + LLPointer cb = new LLBoostFuncInventoryCallback(activate_gesture_cb); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + else + { + LLGestureMgr::instance().activateGesture(item->getUUID()); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } + return ACCEPT_YES_MULTI; + } + else + { + return ACCEPT_NO; + } } EAcceptance LLToolDragAndDrop::dad3dWearCategory( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearCategory()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* category; - locateInventory(item, category); - if(!category) return ACCEPT_NO; - - if (drop) - { - // TODO: investigate wearables may not be loaded at this point EXT-8231 - } - - U32 max_items = gSavedSettings.getU32("WearFolderLimit"); - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); - gInventory.collectDescendentsIf(category->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - not_worn); - if (items.size() > max_items) - { - LLStringUtil::format_map_t args; - args["AMOUNT"] = llformat("%d", max_items); - mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args); - return ACCEPT_NO_CUSTOM; - } - - if(mSource == SOURCE_AGENT) - { - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) ) - { - return ACCEPT_NO; - } - - const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX); - if(outbox_id.notNull() && gInventory.isObjectDescendentOf(category->getUUID(), outbox_id)) - { - // Legacy - return ACCEPT_NO; - } - - if(drop) - { - BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); - LLAppearanceMgr::instance().wearInventoryCategory(category, false, append); - } - return ACCEPT_YES_MULTI; - } - else if(mSource == SOURCE_LIBRARY) - { - if(drop) - { - LLAppearanceMgr::instance().wearInventoryCategory(category, true, false); - } - return ACCEPT_YES_MULTI; - } - else - { - // TODO: copy/move category to avatar's inventory and then wear it. - return ACCEPT_NO; - } + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearCategory()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* category; + locateInventory(item, category); + if(!category) return ACCEPT_NO; + + if (drop) + { + // TODO: investigate wearables may not be loaded at this point EXT-8231 + } + + U32 max_items = gSavedSettings.getU32("WearFolderLimit"); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(category->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + not_worn); + if (items.size() > max_items) + { + LLStringUtil::format_map_t args; + args["AMOUNT"] = llformat("%d", max_items); + mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args); + return ACCEPT_NO_CUSTOM; + } + + if(mSource == SOURCE_AGENT) + { + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) ) + { + return ACCEPT_NO; + } + + const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX); + if(outbox_id.notNull() && gInventory.isObjectDescendentOf(category->getUUID(), outbox_id)) + { + // Legacy + return ACCEPT_NO; + } + + if(drop) + { + BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); + LLAppearanceMgr::instance().wearInventoryCategory(category, false, append); + } + return ACCEPT_YES_MULTI; + } + else if(mSource == SOURCE_LIBRARY) + { + if(drop) + { + LLAppearanceMgr::instance().wearInventoryCategory(category, true, false); + } + return ACCEPT_YES_MULTI; + } + else + { + // TODO: copy/move category to avatar's inventory and then wear it. + return ACCEPT_NO; + } } EAcceptance LLToolDragAndDrop::dad3dUpdateInventory( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dadUpdateInventory()" << LL_ENDL; - - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) - { - return ACCEPT_NO; - } - - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - LLViewerObject* root_object = obj; - if (obj && obj->getParent()) - { - LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); - if (!parent_obj->isAvatar()) - { - root_object = parent_obj; - } - } - - EAcceptance rv = willObjectAcceptInventory(root_object, item); - if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv)) - { - dropInventory(root_object, item, mSource, mSourceID); - } - return rv; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dadUpdateInventory()" << LL_ENDL; + + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) + { + return ACCEPT_NO; + } + + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + LLViewerObject* root_object = obj; + if (obj && obj->getParent()) + { + LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); + if (!parent_obj->isAvatar()) + { + root_object = parent_obj; + } + } + + EAcceptance rv = willObjectAcceptInventory(root_object, item); + if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv)) + { + dropInventory(root_object, item, mSource, mSourceID); + } + return rv; } BOOL LLToolDragAndDrop::dadUpdateInventory(LLViewerObject* obj, BOOL drop) { - EAcceptance rv = dad3dUpdateInventory(obj, -1, MASK_NONE, drop); - return (rv >= ACCEPT_YES_COPY_SINGLE); + EAcceptance rv = dad3dUpdateInventory(obj, -1, MASK_NONE, drop); + return (rv >= ACCEPT_YES_COPY_SINGLE); } EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << LL_ENDL; - if (obj == NULL) - { - LL_WARNS() << "obj is NULL; aborting func with ACCEPT_NO" << LL_ENDL; - return ACCEPT_NO; - } - - if ((mSource != SOURCE_AGENT) && (mSource != SOURCE_LIBRARY)) - { - return ACCEPT_NO; - } - if (obj->isAttachment()) - { - return ACCEPT_NO_LOCKED; - } - - LLViewerInventoryItem* item = NULL; - LLViewerInventoryCategory* cat = NULL; - locateInventory(item, cat); - if (!cat) - { - return ACCEPT_NO; - } - - // Find all the items in the category - LLDroppableItem droppable(!obj->permYouOwner()); - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendentsIf(cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - droppable); - cats.push_back(cat); - if (droppable.countNoCopy() > 0) - { - LL_WARNS() << "*** Need to confirm this step" << LL_ENDL; - } - LLViewerObject* root_object = obj; - if (obj->getParent()) - { - LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); - if (!parent_obj->isAvatar()) - { - root_object = parent_obj; - } - } - - EAcceptance rv = ACCEPT_NO; - - // Check for accept - for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); - cat_iter != cats.end(); - ++cat_iter) - { - const LLViewerInventoryCategory *cat = (*cat_iter); - rv = gInventory.isCategoryComplete(cat->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO; - if(rv < ACCEPT_YES_SINGLE) - { - LL_DEBUGS() << "Category " << cat->getUUID() << "is not complete." << LL_ENDL; - break; - } - } - if (ACCEPT_YES_COPY_SINGLE <= rv) - { - for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); - item_iter != items.end(); - ++item_iter) - { - LLViewerInventoryItem *item = (*item_iter); - /* - // Pass the base objects, not the links. - if (item && item->getIsLinkType()) - { - item = item->getLinkedItem(); - (*item_iter) = item; - } - */ - rv = willObjectAcceptInventory(root_object, item, DAD_CATEGORY); - if (rv < ACCEPT_YES_COPY_SINGLE) - { - LL_DEBUGS() << "Object will not accept " << item->getUUID() << LL_ENDL; - break; - } - } - } - - // If every item is accepted, send it on - if (drop && (ACCEPT_YES_COPY_SINGLE <= rv)) - { - uuid_vec_t ids; - for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); - item_iter != items.end(); - ++item_iter) - { - const LLViewerInventoryItem *item = (*item_iter); - ids.push_back(item->getUUID()); - } - LLCategoryDropObserver* dropper = new LLCategoryDropObserver(ids, obj->getID(), mSource); - dropper->startFetch(); - if (dropper->isFinished()) - { - dropper->done(); - } - else - { - gInventory.addObserver(dropper); - } - } - return rv; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << LL_ENDL; + if (obj == NULL) + { + LL_WARNS() << "obj is NULL; aborting func with ACCEPT_NO" << LL_ENDL; + return ACCEPT_NO; + } + + if ((mSource != SOURCE_AGENT) && (mSource != SOURCE_LIBRARY)) + { + return ACCEPT_NO; + } + if (obj->isAttachment()) + { + return ACCEPT_NO_LOCKED; + } + + LLViewerInventoryItem* item = NULL; + LLViewerInventoryCategory* cat = NULL; + locateInventory(item, cat); + if (!cat) + { + return ACCEPT_NO; + } + + // Find all the items in the category + LLDroppableItem droppable(!obj->permYouOwner()); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendentsIf(cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + droppable); + cats.push_back(cat); + if (droppable.countNoCopy() > 0) + { + LL_WARNS() << "*** Need to confirm this step" << LL_ENDL; + } + LLViewerObject* root_object = obj; + if (obj->getParent()) + { + LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); + if (!parent_obj->isAvatar()) + { + root_object = parent_obj; + } + } + + EAcceptance rv = ACCEPT_NO; + + // Check for accept + for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); + cat_iter != cats.end(); + ++cat_iter) + { + const LLViewerInventoryCategory *cat = (*cat_iter); + rv = gInventory.isCategoryComplete(cat->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO; + if(rv < ACCEPT_YES_SINGLE) + { + LL_DEBUGS() << "Category " << cat->getUUID() << "is not complete." << LL_ENDL; + break; + } + } + if (ACCEPT_YES_COPY_SINGLE <= rv) + { + for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + LLViewerInventoryItem *item = (*item_iter); + /* + // Pass the base objects, not the links. + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + (*item_iter) = item; + } + */ + rv = willObjectAcceptInventory(root_object, item, DAD_CATEGORY); + if (rv < ACCEPT_YES_COPY_SINGLE) + { + LL_DEBUGS() << "Object will not accept " << item->getUUID() << LL_ENDL; + break; + } + } + } + + // If every item is accepted, send it on + if (drop && (ACCEPT_YES_COPY_SINGLE <= rv)) + { + uuid_vec_t ids; + for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLViewerInventoryItem *item = (*item_iter); + ids.push_back(item->getUUID()); + } + LLCategoryDropObserver* dropper = new LLCategoryDropObserver(ids, obj->getID(), mSource); + dropper->startFetch(); + if (dropper->isFinished()) + { + dropper->done(); + } + else + { + gInventory.addObserver(dropper); + } + } + return rv; } EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { - if ((mask & MASK_CONTROL)) - { - return dad3dUpdateInventoryCategory(obj, face, mask, drop); - } - else - { - return ACCEPT_NO; - } + if ((mask & MASK_CONTROL)) + { + return dad3dUpdateInventoryCategory(obj, face, mask, drop); + } + else + { + return ACCEPT_NO; + } } BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj, - BOOL drop) + BOOL drop) { - EAcceptance rv = dad3dUpdateInventoryCategory(obj, -1, MASK_NONE, drop); - return (rv >= ACCEPT_YES_COPY_SINGLE); + EAcceptance rv = dad3dUpdateInventoryCategory(obj, -1, MASK_NONE, drop); + return (rv >= ACCEPT_YES_COPY_SINGLE); } EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << LL_ENDL; - - // item has to be in agent inventory. - if(mSource != SOURCE_AGENT) return ACCEPT_NO; - - // find the item now. - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - { - // cannot give away no-transfer objects - return ACCEPT_NO; - } - LLVOAvatarSelf* avatar = gAgentAvatarp; - if(avatar && avatar->isWearingAttachment( item->getUUID() ) ) - { - // You can't give objects that are attached to you - return ACCEPT_NO; - } - if( obj && avatar ) - { - if(drop) - { - LLGiveInventory::doGiveInventoryItem(obj->getID(), item ); - } - // *TODO: deal with all the issues surrounding multi-object - // inventory transfers. - return ACCEPT_YES_SINGLE; - } - return ACCEPT_NO; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << LL_ENDL; + + // item has to be in agent inventory. + if(mSource != SOURCE_AGENT) return ACCEPT_NO; + + // find the item now. + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + { + // cannot give away no-transfer objects + return ACCEPT_NO; + } + LLVOAvatarSelf* avatar = gAgentAvatarp; + if(avatar && avatar->isWearingAttachment( item->getUUID() ) ) + { + // You can't give objects that are attached to you + return ACCEPT_NO; + } + if( obj && avatar ) + { + if(drop) + { + LLGiveInventory::doGiveInventoryItem(obj->getID(), item ); + } + // *TODO: deal with all the issues surrounding multi-object + // inventory transfers. + return ACCEPT_YES_SINGLE; + } + return ACCEPT_NO; } EAcceptance LLToolDragAndDrop::dad3dGiveInventory( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventory()" << LL_ENDL; - // item has to be in agent inventory. - if(mSource != SOURCE_AGENT) return ACCEPT_NO; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - if (!LLGiveInventory::isInventoryGiveAcceptable(item)) - { - return ACCEPT_NO; - } - if (drop && obj) - { - LLGiveInventory::doGiveInventoryItem(obj->getID(), item); - } - // *TODO: deal with all the issues surrounding multi-object - // inventory transfers. - return ACCEPT_YES_SINGLE; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventory()" << LL_ENDL; + // item has to be in agent inventory. + if(mSource != SOURCE_AGENT) return ACCEPT_NO; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + if (!LLGiveInventory::isInventoryGiveAcceptable(item)) + { + return ACCEPT_NO; + } + if (drop && obj) + { + LLGiveInventory::doGiveInventoryItem(obj->getID(), item); + } + // *TODO: deal with all the issues surrounding multi-object + // inventory transfers. + return ACCEPT_YES_SINGLE; } EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { - LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL; - if(drop && obj) - { - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if(!cat) return ACCEPT_NO; - LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat); - } - // *TODO: deal with all the issues surrounding multi-object - // inventory transfers. - return ACCEPT_YES_SINGLE; + LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL; + if(drop && obj) + { + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if(!cat) return ACCEPT_NO; + LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat); + } + // *TODO: deal with all the issues surrounding multi-object + // inventory transfers. + return ACCEPT_YES_SINGLE; } EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << LL_ENDL; - LLViewerInventoryItem* item = NULL; - LLViewerInventoryCategory* cat = NULL; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - - if(!gAgent.allowOperation(PERM_COPY, item->getPermissions()) - || !item->getPermissions().allowTransferTo(LLUUID::null)) - { - return ACCEPT_NO_LOCKED; - } - if(drop) - { - dropObject(obj, TRUE, TRUE, FALSE); - } - return ACCEPT_YES_SINGLE; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << LL_ENDL; + LLViewerInventoryItem* item = NULL; + LLViewerInventoryCategory* cat = NULL; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + + if(!gAgent.allowOperation(PERM_COPY, item->getPermissions()) + || !item->getPermissions().allowTransferTo(LLUUID::null)) + { + return ACCEPT_NO_LOCKED; + } + if(drop) + { + dropObject(obj, TRUE, TRUE, FALSE); + } + return ACCEPT_YES_SINGLE; } EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << LL_ENDL; - LLViewerInventoryItem* item; - LLViewerInventoryCategory* cat; - locateInventory(item, cat); - if (!item || !item->isFinished()) return ACCEPT_NO; - if((mask & MASK_CONTROL)) - { - // *HACK: In order to resolve SL-22177, we need to block drags - // from notecards and objects onto other objects. - return ACCEPT_NO; - - // *HACK: uncomment this when appropriate - //EAcceptance rv = willObjectAcceptInventory(obj, item); - //if(drop && (ACCEPT_YES_SINGLE <= rv)) - //{ - // dropInventory(obj, item, mSource, mSourceID); - //} - //return rv; - } - if(!item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID()) - || !item->getPermissions().allowTransferTo(LLUUID::null)) - { - return ACCEPT_NO_LOCKED; - } - if(drop) - { - dropObject(obj, FALSE, TRUE, FALSE); - } - return ACCEPT_YES_SINGLE; + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << LL_ENDL; + LLViewerInventoryItem* item; + LLViewerInventoryCategory* cat; + locateInventory(item, cat); + if (!item || !item->isFinished()) return ACCEPT_NO; + if((mask & MASK_CONTROL)) + { + // *HACK: In order to resolve SL-22177, we need to block drags + // from notecards and objects onto other objects. + return ACCEPT_NO; + + // *HACK: uncomment this when appropriate + //EAcceptance rv = willObjectAcceptInventory(obj, item); + //if(drop && (ACCEPT_YES_SINGLE <= rv)) + //{ + // dropInventory(obj, item, mSource, mSourceID); + //} + //return rv; + } + if(!item->getPermissions().allowCopyBy(gAgent.getID(), + gAgent.getGroupID()) + || !item->getPermissions().allowTransferTo(LLUUID::null)) + { + return ACCEPT_NO_LOCKED; + } + if(drop) + { + dropObject(obj, FALSE, TRUE, FALSE); + } + return ACCEPT_YES_SINGLE; } EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand( - LLViewerObject *obj, S32 face, MASK mask, BOOL drop) -{ - return ACCEPT_NO; - /* - LL_DEBUGS() << "LLToolDragAndDrop::dad3dCategoryOnLand()" << LL_ENDL; - LLInventoryItem* item; - LLInventoryCategory* cat; - locateInventory(item, cat); - if(!cat) return ACCEPT_NO; - EAcceptance rv = ACCEPT_NO; - - // find all the items in the category - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLDropCopyableItems droppable; - gInventory.collectDescendentsIf(cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - droppable); - if(items.size() > 0) - { - rv = ACCEPT_YES_SINGLE; - } - if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) - { - createContainer(items, cat->getName()); - return ACCEPT_NO; - } - return rv; - */ + LLViewerObject *obj, S32 face, MASK mask, BOOL drop) +{ + return ACCEPT_NO; + /* + LL_DEBUGS() << "LLToolDragAndDrop::dad3dCategoryOnLand()" << LL_ENDL; + LLInventoryItem* item; + LLInventoryCategory* cat; + locateInventory(item, cat); + if(!cat) return ACCEPT_NO; + EAcceptance rv = ACCEPT_NO; + + // find all the items in the category + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLDropCopyableItems droppable; + gInventory.collectDescendentsIf(cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + droppable); + if(items.size() > 0) + { + rv = ACCEPT_YES_SINGLE; + } + if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) + { + createContainer(items, cat->getName()); + return ACCEPT_NO; + } + return rv; + */ } @@ -2980,163 +2980,163 @@ EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand( // This shortcuts alot of steps to make a basic object // w/ an inventory and a special permissions set EAcceptance LLToolDragAndDrop::dad3dAssetOnLand( - LLViewerObject *obj, S32 face, MASK mask, BOOL drop) -{ - return ACCEPT_NO; - /* - LL_DEBUGS() << "LLToolDragAndDrop::dad3dAssetOnLand()" << LL_ENDL; - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLViewerInventoryItem::item_array_t copyable_items; - locateMultipleInventory(items, cats); - if(!items.size()) return ACCEPT_NO; - EAcceptance rv = ACCEPT_NO; - for (S32 i = 0; i < items.size(); i++) - { - LLInventoryItem* item = items[i]; - if(item->getPermissions().allowCopyBy(gAgent.getID())) - { - copyable_items.push_back(item); - rv = ACCEPT_YES_SINGLE; - } - } - - if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) - { - createContainer(copyable_items, NULL); - } - - return rv; - */ + LLViewerObject *obj, S32 face, MASK mask, BOOL drop) +{ + return ACCEPT_NO; + /* + LL_DEBUGS() << "LLToolDragAndDrop::dad3dAssetOnLand()" << LL_ENDL; + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLViewerInventoryItem::item_array_t copyable_items; + locateMultipleInventory(items, cats); + if(!items.size()) return ACCEPT_NO; + EAcceptance rv = ACCEPT_NO; + for (S32 i = 0; i < items.size(); i++) + { + LLInventoryItem* item = items[i]; + if(item->getPermissions().allowCopyBy(gAgent.getID())) + { + copyable_items.push_back(item); + rv = ACCEPT_YES_SINGLE; + } + } + + if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) + { + createContainer(copyable_items, NULL); + } + + return rv; + */ } LLInventoryObject* LLToolDragAndDrop::locateInventory( - LLViewerInventoryItem*& item, - LLViewerInventoryCategory*& cat) -{ - item = NULL; - cat = NULL; - - if (mCargoIDs.empty() - || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop. - { - return NULL; - } - - if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) - { - // The object should be in user inventory. - item = (LLViewerInventoryItem*)gInventory.getItem(mCargoIDs[mCurItemIndex]); - cat = (LLViewerInventoryCategory*)gInventory.getCategory(mCargoIDs[mCurItemIndex]); - } - else if(mSource == SOURCE_WORLD) - { - // This object is in some task inventory somewhere. - LLViewerObject* obj = gObjectList.findObject(mSourceID); - if(obj) - { - if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY) - || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY)) - { - cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]); - } - else - { - item = (LLViewerInventoryItem*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]); - } - } - } - else if(mSource == SOURCE_NOTECARD) - { - LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", mSourceID); - if(preview) - { - item = (LLViewerInventoryItem*)preview->getDragItem(); - } - } - else if(mSource == SOURCE_VIEWER) - { - item = (LLViewerInventoryItem*)gToolBarView->getDragItem(); - } - - if(item) return item; - if(cat) return cat; - return NULL; + LLViewerInventoryItem*& item, + LLViewerInventoryCategory*& cat) +{ + item = NULL; + cat = NULL; + + if (mCargoIDs.empty() + || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop. + { + return NULL; + } + + if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) + { + // The object should be in user inventory. + item = (LLViewerInventoryItem*)gInventory.getItem(mCargoIDs[mCurItemIndex]); + cat = (LLViewerInventoryCategory*)gInventory.getCategory(mCargoIDs[mCurItemIndex]); + } + else if(mSource == SOURCE_WORLD) + { + // This object is in some task inventory somewhere. + LLViewerObject* obj = gObjectList.findObject(mSourceID); + if(obj) + { + if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY) + || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY)) + { + cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]); + } + else + { + item = (LLViewerInventoryItem*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]); + } + } + } + else if(mSource == SOURCE_NOTECARD) + { + LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", mSourceID); + if(preview) + { + item = (LLViewerInventoryItem*)preview->getDragItem(); + } + } + else if(mSource == SOURCE_VIEWER) + { + item = (LLViewerInventoryItem*)gToolBarView->getDragItem(); + } + + if(item) return item; + if(cat) return cat; + return NULL; } /* LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryCategory::cat_array_t& cats, - LLViewerInventoryItem::item_array_t& items) -{ - if(mCargoIDs.size() == 0) return NULL; - if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) - { - // The object should be in user inventory. - for (S32 i = 0; i < mCargoIDs.size(); i++) - { - LLInventoryItem* item = gInventory.getItem(mCargoIDs[i]); - if (item) - { - items.push_back(item); - } - LLInventoryCategory* category = gInventory.getCategory(mCargoIDs[i]); - if (category) - { - cats.push_back(category); - } - } - } - else if(mSource == SOURCE_WORLD) - { - // This object is in some task inventory somewhere. - LLViewerObject* obj = gObjectList.findObject(mSourceID); - if(obj) - { - if((mCargoType == DAD_CATEGORY) - || (mCargoType == DAD_ROOT_CATEGORY)) - { - // The object should be in user inventory. - for (S32 i = 0; i < mCargoIDs.size(); i++) - { - LLInventoryCategory* category = (LLInventoryCategory*)obj->getInventoryObject(mCargoIDs[i]); - if (category) - { - cats.push_back(category); - } - } - } - else - { - for (S32 i = 0; i < mCargoIDs.size(); i++) - { - LLInventoryItem* item = (LLInventoryItem*)obj->getInventoryObject(mCargoIDs[i]); - if (item) - { - items.push_back(item); - } - } - } - } - } - else if(mSource == SOURCE_NOTECARD) - { - LLPreviewNotecard* card; - card = (LLPreviewNotecard*)LLPreview::find(mSourceID); - if(card) - { - items.push_back((LLInventoryItem*)card->getDragItem()); - } - } - if(items.size()) return items[0]; - if(cats.size()) return cats[0]; - return NULL; + LLViewerInventoryItem::item_array_t& items) +{ + if(mCargoIDs.size() == 0) return NULL; + if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) + { + // The object should be in user inventory. + for (S32 i = 0; i < mCargoIDs.size(); i++) + { + LLInventoryItem* item = gInventory.getItem(mCargoIDs[i]); + if (item) + { + items.push_back(item); + } + LLInventoryCategory* category = gInventory.getCategory(mCargoIDs[i]); + if (category) + { + cats.push_back(category); + } + } + } + else if(mSource == SOURCE_WORLD) + { + // This object is in some task inventory somewhere. + LLViewerObject* obj = gObjectList.findObject(mSourceID); + if(obj) + { + if((mCargoType == DAD_CATEGORY) + || (mCargoType == DAD_ROOT_CATEGORY)) + { + // The object should be in user inventory. + for (S32 i = 0; i < mCargoIDs.size(); i++) + { + LLInventoryCategory* category = (LLInventoryCategory*)obj->getInventoryObject(mCargoIDs[i]); + if (category) + { + cats.push_back(category); + } + } + } + else + { + for (S32 i = 0; i < mCargoIDs.size(); i++) + { + LLInventoryItem* item = (LLInventoryItem*)obj->getInventoryObject(mCargoIDs[i]); + if (item) + { + items.push_back(item); + } + } + } + } + } + else if(mSource == SOURCE_NOTECARD) + { + LLPreviewNotecard* card; + card = (LLPreviewNotecard*)LLPreview::find(mSourceID); + if(card) + { + items.push_back((LLInventoryItem*)card->getDragItem()); + } + } + if(items.size()) return items[0]; + if(cats.size()) return cats[0]; + return NULL; } */ // void LLToolDragAndDrop::createContainer(LLViewerInventoryItem::item_array_t &items, const char* preferred_name ) // { -// LL_WARNS() << "LLToolDragAndDrop::createContainer()" << LL_ENDL; -// return; +// LL_WARNS() << "LLToolDragAndDrop::createContainer()" << LL_ENDL; +// return; // } @@ -3144,13 +3144,13 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC void pack_permissions_slam(LLMessageSystem* msg, U32 flags, const LLPermissions& perms) { - // CRUFT -- the server no longer pays attention to this data - U32 group_mask = perms.getMaskGroup(); - U32 everyone_mask = perms.getMaskEveryone(); - U32 next_owner_mask = perms.getMaskNextOwner(); - - msg->addU32Fast(_PREHASH_ItemFlags, flags); - msg->addU32Fast(_PREHASH_GroupMask, group_mask); - msg->addU32Fast(_PREHASH_EveryoneMask, everyone_mask); - msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_mask); + // CRUFT -- the server no longer pays attention to this data + U32 group_mask = perms.getMaskGroup(); + U32 everyone_mask = perms.getMaskEveryone(); + U32 next_owner_mask = perms.getMaskNextOwner(); + + msg->addU32Fast(_PREHASH_ItemFlags, flags); + msg->addU32Fast(_PREHASH_GroupMask, group_mask); + msg->addU32Fast(_PREHASH_EveryoneMask, everyone_mask); + msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_mask); } diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 907cec4d17..5960989166 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltoolselect.cpp * @brief LLToolSelect class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,8 +42,8 @@ #include "llviewercamera.h" #include "llviewermenu.h" #include "llviewerobject.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llworld.h" @@ -55,235 +55,235 @@ const F32 SELECTION_ROTATION_TRESHOLD = 0.1f; const F32 SELECTION_SITTING_ROTATION_TRESHOLD = 3.2f; //radian LLToolSelect::LLToolSelect( LLToolComposite* composite ) -: LLTool( std::string("Select"), composite ), - mIgnoreGroup( FALSE ) +: LLTool( std::string("Select"), composite ), + mIgnoreGroup( FALSE ) { } // True if you selected an object. BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask) { - // do immediate pick query + // do immediate pick query BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects"); BOOL pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes"); - mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, FALSE, TRUE, pick_reflection_probe); + mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, FALSE, TRUE, pick_reflection_probe); - // Pass mousedown to agent - LLTool::handleMouseDown(x, y, mask); + // Pass mousedown to agent + LLTool::handleMouseDown(x, y, mask); - return mPick.getObject().notNull(); + return mPick.getObject().notNull(); } // static LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root) { - LLViewerObject* object = pick.getObject(); - if (select_root) - { - object = object->getRootEdit(); - } - BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); - BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); + LLViewerObject* object = pick.getObject(); + if (select_root) + { + object = object->getRootEdit(); + } + BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); + BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); // *NOTE: These settings must be cleaned up at bottom of function. - if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) - { - gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); - gSavedSettings.setBOOL("SelectMovableOnly", FALSE); - LLSelectMgr::getInstance()->setForceSelection(TRUE); - } - - BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); - - // If no object, check for icon, then just deselect - if (!object) - { - LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon; - - if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject()) - { - LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID()); - } - else if (!extend_select) - { - LLSelectMgr::getInstance()->deselectAll(); - } - } - else - { - BOOL already_selected = object->isSelected(); - - if (already_selected && - object->getNumTEs() > 0 && - !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES)) - { - const LLTextureEntry* tep = object->getTE(pick.mObjectFace); - if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull()) - { - // we were interacting with media and clicked on non selected face, drop media focus - LLViewerMediaFocus::getInstance()->clearFocus(); - // selection was removed and zoom preserved by clearFocus(), continue with regular selection - already_selected = false; - extend_select = true; - } - } - - if ( extend_select ) - { - if ( already_selected ) - { - if ( ignore_group ) - { - LLSelectMgr::getInstance()->deselectObjectOnly(object); - } - else - { - LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE); - } - } - else - { - if ( ignore_group ) - { - LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); - } - else - { - LLSelectMgr::getInstance()->selectObjectAndFamily(object); - } - } - } - else - { - // Save the current zoom values because deselect resets them. - F32 target_zoom; - F32 current_zoom; - LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom); - - // JC - Change behavior to make it easier to select children - // of linked sets. 9/3/2002 - if( !already_selected || ignore_group) - { - // ...lose current selection in favor of just this object - LLSelectMgr::getInstance()->deselectAll(); - } - - if ( ignore_group ) - { - LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES, pick.mGLTFNodeIndex, pick.mGLTFPrimitiveIndex); - } - else - { - LLSelectMgr::getInstance()->selectObjectAndFamily(object); - } - - // restore the zoom to the previously stored values. - LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); - } - - if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar - LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments - object != gAgentAvatarp) // and it's not you - { - // have avatar turn to face the selected object(s) - LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal(); - selection_center = selection_center - gAgent.getPositionGlobal(); - LLVector3 selection_dir; - selection_dir.setVec(selection_center); - selection_dir.mV[VZ] = 0.f; - selection_dir.normVec(); - if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f) - { - LLQuaternion target_rot; - target_rot.shortestArc(LLVector3::x_axis, selection_dir); - gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), - "", - &target_rot, - NULL, - NULL, - MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/, - gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD); - } - } - - if (temp_select) - { - if (!already_selected) - { - LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit(); - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - // this is just a temporary selection - LLSelectNode* select_node = selection->findNode(root_object); - if (select_node) - { - select_node->setTransient(TRUE); - } - - LLViewerObject::const_child_list_t& child_list = root_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - select_node = selection->findNode(child); - if (select_node) - { - select_node->setTransient(TRUE); - } - } - - } - } //if(temp_select) - } //if(!object) - - // Cleanup temp select settings above. - if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar) - { - gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); - gSavedSettings.setBOOL("SelectMovableOnly", select_movable); - LLSelectMgr::getInstance()->setForceSelection(FALSE); - } - - return LLSelectMgr::getInstance()->getSelection(); + if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) + { + gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); + gSavedSettings.setBOOL("SelectMovableOnly", FALSE); + LLSelectMgr::getInstance()->setForceSelection(TRUE); + } + + BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); + + // If no object, check for icon, then just deselect + if (!object) + { + LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon; + + if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject()) + { + LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID()); + } + else if (!extend_select) + { + LLSelectMgr::getInstance()->deselectAll(); + } + } + else + { + BOOL already_selected = object->isSelected(); + + if (already_selected && + object->getNumTEs() > 0 && + !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES)) + { + const LLTextureEntry* tep = object->getTE(pick.mObjectFace); + if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull()) + { + // we were interacting with media and clicked on non selected face, drop media focus + LLViewerMediaFocus::getInstance()->clearFocus(); + // selection was removed and zoom preserved by clearFocus(), continue with regular selection + already_selected = false; + extend_select = true; + } + } + + if ( extend_select ) + { + if ( already_selected ) + { + if ( ignore_group ) + { + LLSelectMgr::getInstance()->deselectObjectOnly(object); + } + else + { + LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE); + } + } + else + { + if ( ignore_group ) + { + LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); + } + else + { + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + } + } + } + else + { + // Save the current zoom values because deselect resets them. + F32 target_zoom; + F32 current_zoom; + LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom); + + // JC - Change behavior to make it easier to select children + // of linked sets. 9/3/2002 + if( !already_selected || ignore_group) + { + // ...lose current selection in favor of just this object + LLSelectMgr::getInstance()->deselectAll(); + } + + if ( ignore_group ) + { + LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES, pick.mGLTFNodeIndex, pick.mGLTFPrimitiveIndex); + } + else + { + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + } + + // restore the zoom to the previously stored values. + LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); + } + + if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar + LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments + object != gAgentAvatarp) // and it's not you + { + // have avatar turn to face the selected object(s) + LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal(); + selection_center = selection_center - gAgent.getPositionGlobal(); + LLVector3 selection_dir; + selection_dir.setVec(selection_center); + selection_dir.mV[VZ] = 0.f; + selection_dir.normVec(); + if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f) + { + LLQuaternion target_rot; + target_rot.shortestArc(LLVector3::x_axis, selection_dir); + gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), + "", + &target_rot, + NULL, + NULL, + MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/, + gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD); + } + } + + if (temp_select) + { + if (!already_selected) + { + LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + // this is just a temporary selection + LLSelectNode* select_node = selection->findNode(root_object); + if (select_node) + { + select_node->setTransient(TRUE); + } + + LLViewerObject::const_child_list_t& child_list = root_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + select_node = selection->findNode(child); + if (select_node) + { + select_node->setTransient(TRUE); + } + } + + } + } //if(temp_select) + } //if(!object) + + // Cleanup temp select settings above. + if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar) + { + gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); + gSavedSettings.setBOOL("SelectMovableOnly", select_movable); + LLSelectMgr::getInstance()->setForceSelection(FALSE); + } + + return LLSelectMgr::getInstance()->getSelection(); } BOOL LLToolSelect::handleMouseUp(S32 x, S32 y, MASK mask) { - mIgnoreGroup = gSavedSettings.getBOOL("EditLinkedParts"); + mIgnoreGroup = gSavedSettings.getBOOL("EditLinkedParts"); - handleObjectSelection(mPick, mIgnoreGroup, FALSE); + handleObjectSelection(mPick, mIgnoreGroup, FALSE); - return LLTool::handleMouseUp(x, y, mask); + return LLTool::handleMouseUp(x, y, mask); } void LLToolSelect::handleDeselect() { - if( hasMouseCapture() ) - { - setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly - } + if( hasMouseCapture() ) + { + setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly + } } void LLToolSelect::stopEditing() { - if( hasMouseCapture() ) - { - setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly - } + if( hasMouseCapture() ) + { + setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly + } } void LLToolSelect::onMouseCaptureLost() { - // Finish drag + // Finish drag - LLSelectMgr::getInstance()->enableSilhouette(TRUE); + LLSelectMgr::getInstance()->enableSilhouette(TRUE); - // Clean up drag-specific variables - mIgnoreGroup = FALSE; + // Clean up drag-specific variables + mIgnoreGroup = FALSE; } diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 882e08935c..b2072218ac 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -81,9 +81,9 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, { } -LLResourceUploadInfo::LLResourceUploadInfo(std::string name, - std::string description, S32 compressionInfo, - LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, +LLResourceUploadInfo::LLResourceUploadInfo(std::string name, + std::string description, S32 compressionInfo, + LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) : mName(name), mDescription(description), @@ -100,7 +100,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(std::string name, mFolderId(LLUUID::null), mItemId(LLUUID::null), mAssetId(LLAssetID::null) -{ +{ mTransactionId.generate(); } @@ -311,39 +311,39 @@ std::string LLResourceUploadInfo::getDisplayName() const bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type) { - U32 codec; - return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false); + U32 codec; + return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false); } // static bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload) { - bool succ = false; - std::string exten_lc(exten); - LLStringUtil::toLower(exten_lc); - codec = LLImageBase::getCodecFromExtension(exten_lc); - if (codec != IMG_CODEC_INVALID) - { - asset_type = LLAssetType::AT_TEXTURE; - succ = true; - } - else if (exten_lc == "wav") - { - asset_type = LLAssetType::AT_SOUND; - succ = true; - } - else if (exten_lc == "anim") - { - asset_type = LLAssetType::AT_ANIMATION; - succ = true; - } - else if (!bulk_upload && (exten_lc == "bvh")) - { - asset_type = LLAssetType::AT_ANIMATION; - succ = true; - } - - return succ; + bool succ = false; + std::string exten_lc(exten); + LLStringUtil::toLower(exten_lc); + codec = LLImageBase::getCodecFromExtension(exten_lc); + if (codec != IMG_CODEC_INVALID) + { + asset_type = LLAssetType::AT_TEXTURE; + succ = true; + } + else if (exten_lc == "wav") + { + asset_type = LLAssetType::AT_SOUND; + succ = true; + } + else if (exten_lc == "anim") + { + asset_type = LLAssetType::AT_ANIMATION; + succ = true; + } + else if (!bulk_upload && (exten_lc == "bvh")) + { + asset_type = LLAssetType::AT_ANIMATION; + succ = true; + } + + return succ; } //========================================================================= @@ -385,8 +385,8 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() std::string exten = gDirUtilp->getExtension(getFileName()); LLAssetType::EType assetType = LLAssetType::AT_NONE; - U32 codec = IMG_CODEC_INVALID; - bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec); + U32 codec = IMG_CODEC_INVALID; + bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec); std::string errorMessage; std::string errorLabel; @@ -455,53 +455,53 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() } else if (exten == "anim") { - // Default unless everything succeeds - errorLabel = "ProblemWithFile"; - error = true; + // Default unless everything succeeds + errorLabel = "ProblemWithFile"; + error = true; // read from getFileName() - LLAPRFile infile; - infile.open(getFileName(),LL_APR_RB); - if (!infile.getFileHandle()) - { - LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; - errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); - } - else - { - S32 size = LLAPRFile::size(getFileName()); - U8* buffer = new U8[size]; - S32 size_read = infile.read(buffer,size); - if (size_read != size) - { - errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); - } - else - { - LLDataPackerBinaryBuffer dp(buffer, size); - LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); - motionp->setCharacter(gAgentAvatarp); - if (motionp->deserialize(dp, getAssetId(), false)) - { - // write to temp file - bool succ = motionp->dumpToFile(filename); - if (succ) - { - assetType = LLAssetType::AT_ANIMATION; - errorLabel = ""; - error = false; - } - else - { - errorMessage = "Failed saving temporary animation file"; - } - } - else - { - errorMessage = "Failed reading animation file"; - } - } - } + LLAPRFile infile; + infile.open(getFileName(),LL_APR_RB); + if (!infile.getFileHandle()) + { + LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; + errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); + } + else + { + S32 size = LLAPRFile::size(getFileName()); + U8* buffer = new U8[size]; + S32 size_read = infile.read(buffer,size); + if (size_read != size) + { + errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); + } + else + { + LLDataPackerBinaryBuffer dp(buffer, size); + LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); + motionp->setCharacter(gAgentAvatarp); + if (motionp->deserialize(dp, getAssetId(), false)) + { + // write to temp file + bool succ = motionp->dumpToFile(filename); + if (succ) + { + assetType = LLAssetType::AT_ANIMATION; + errorLabel = ""; + error = false; + } + else + { + errorMessage = "Failed saving temporary animation file"; + } + } + else + { + errorMessage = "Failed reading animation file"; + } + } + } } else { @@ -596,10 +596,10 @@ LLSD LLNewBufferedResourceUploadInfo::exportTempFile() { std::string filename = gDirUtilp->getTempFilename(); - // copy buffer to the cache for upload + // copy buffer to the cache for upload LLFileSystem file(getAssetId(), getAssetType(), LLFileSystem::APPEND); file.write((U8*) mBuffer.c_str(), mBuffer.size()); - + return LLSD(); } @@ -828,8 +828,8 @@ LLSD LLScriptAssetUpload::generatePostBody() LLUUID LLViewerAssetUpload::EnqueueInventoryUpload(const std::string &url, const LLResourceUploadInfo::ptr_t &uploadInfo) { std::string procName("LLViewerAssetUpload::AssetInventoryUploadCoproc("); - - LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("Upload", + + LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("Upload", procName + LLAssetType::lookup(uploadInfo->getAssetType()) + ")", boost::bind(&LLViewerAssetUpload::AssetInventoryUploadCoproc, _1, _2, url, uploadInfo)); @@ -838,7 +838,7 @@ LLUUID LLViewerAssetUpload::EnqueueInventoryUpload(const std::string &url, const //========================================================================= /*static*/ -void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, +void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, const LLUUID &id, std::string url, LLResourceUploadInfo::ptr_t uploadInfo) { LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 9ba42e4f47..437f1239bf 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewercamera.cpp * @brief LLViewerCamera class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,7 +48,7 @@ #include "llgl.h" #include "llglheaders.h" #include "llquaternion.h" -#include "llwindow.h" // getPixelAspectRatio() +#include "llwindow.h" // getPixelAspectRatio() #include "lltracerecording.h" #include "llenvironment.h" @@ -63,38 +63,38 @@ LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_ //glu pick matrix implementation borrowed from Mesa3D glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) { - GLfloat m[16]; - GLfloat sx, sy; - GLfloat tx, ty; - - sx = viewport[2] / width; - sy = viewport[3] / height; - tx = (viewport[2] + 2.f * (viewport[0] - x)) / width; - ty = (viewport[3] + 2.f * (viewport[1] - y)) / height; - - #define M(row,col) m[col*4+row] - M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx; - M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty; - M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f; - M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f; - #undef M - - return glh::matrix4f(m); + GLfloat m[16]; + GLfloat sx, sy; + GLfloat tx, ty; + + sx = viewport[2] / width; + sy = viewport[3] / height; + tx = (viewport[2] + 2.f * (viewport[0] - x)) / width; + ty = (viewport[3] + 2.f * (viewport[1] - y)) / height; + + #define M(row,col) m[col*4+row] + M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx; + M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty; + M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f; + M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f; + #undef M + + return glh::matrix4f(m); } LLViewerCamera::LLViewerCamera() : LLCamera() { - calcProjection(getFar()); - mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; - mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; - mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); - mPixelMeterRatio = 0.f; - mScreenPixelArea = 0; - mZoomFactor = 1.f; - mZoomSubregion = 1; - mAverageSpeed = 0.f; - mAverageAngularSpeed = 0.f; - gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); + calcProjection(getFar()); + mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; + mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; + mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); + mPixelMeterRatio = 0.f; + mScreenPixelArea = 0; + mZoomFactor = 1.f; + mZoomSubregion = 1; + mAverageSpeed = 0.f; + mAverageAngularSpeed = 0.f; + gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); } void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) @@ -133,61 +133,61 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVecto } } - setOriginAndLookAt(origin, up_direction, point_of_interest); + setOriginAndLookAt(origin, up_direction, point_of_interest); + + mVelocityDir = origin - last_position ; + F32 dpos = mVelocityDir.normVec() ; + LLQuaternion rotation; + rotation.shortestArc(last_axis, getAtAxis()); - mVelocityDir = origin - last_position ; - F32 dpos = mVelocityDir.normVec() ; - LLQuaternion rotation; - rotation.shortestArc(last_axis, getAtAxis()); + F32 x, y, z; + F32 drot; + rotation.getAngleAxis(&drot, &x, &y, &z); - F32 x, y, z; - F32 drot; - rotation.getAngleAxis(&drot, &x, &y, &z); + add(sVelocityStat, dpos); + add(sAngularVelocityStat, drot); - add(sVelocityStat, dpos); - add(sAngularVelocityStat, drot); - - mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50); - mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat); - mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); + mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50); + mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat); + mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); - // update pixel meter ratio using default fov, not modified one - mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); - // update screen pixel area - mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); + // update pixel meter ratio using default fov, not modified one + mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); + // update screen pixel area + mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); } const LLMatrix4 &LLViewerCamera::getProjection() const { - calcProjection(getFar()); - return mProjectionMatrix; + calcProjection(getFar()); + return mProjectionMatrix; } const LLMatrix4 &LLViewerCamera::getModelview() const { - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - getMatrixToLocal(mModelviewMatrix); - mModelviewMatrix *= cfr; - return mModelviewMatrix; + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + getMatrixToLocal(mModelviewMatrix); + mModelviewMatrix *= cfr; + return mModelviewMatrix; } void LLViewerCamera::calcProjection(const F32 far_distance) const { - F32 fov_y, z_far, z_near, aspect, f; - fov_y = getView(); - z_far = far_distance; - z_near = getNear(); - aspect = getAspect(); - - f = 1/tan(fov_y*0.5f); - - mProjectionMatrix.setZero(); - mProjectionMatrix.mMatrix[0][0] = f/aspect; - mProjectionMatrix.mMatrix[1][1] = f; - mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[2][3] = -1; + F32 fov_y, z_far, z_near, aspect, f; + fov_y = getView(); + z_far = far_distance; + z_near = getNear(); + aspect = getAspect(); + + f = 1/tan(fov_y*0.5f); + + mProjectionMatrix.setZero(); + mProjectionMatrix.mMatrix[0][0] = f/aspect; + mProjectionMatrix.mMatrix[1][1] = f; + mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); + mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); + mProjectionMatrix.mMatrix[2][3] = -1; } // Sets up opengl state for 3D drawing. If for selection, also @@ -198,222 +198,222 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const //static void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks) { - GLint* viewport = (GLint*) gGLViewport; - F64 model[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - model[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - GLdouble objX,objY,objZ; - - LLVector3 frust[8]; - - if (no_hacks) - { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); - } - else if (zflip) - { - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); - - for (U32 i = 0; i < 4; i++) - { - frust[i+4] = frust[i+4]-frust[i]; - frust[i+4].normVec(); - frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); - } - } - else - { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - if (ortho) - { - LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; - for (U32 i = 0; i < 4; i++) - { - frust[i+4] = frust[i] + far_shift; - } - } - else - { - for (U32 i = 0; i < 4; i++) - { - LLVector3 vec = frust[i] - camera.getOrigin(); - vec.normVec(); - frust[i+4] = camera.getOrigin() + vec*camera.getFar(); - } - } - } - - camera.calcAgentFrustumPlanes(frust); + GLint* viewport = (GLint*) gGLViewport; + F64 model[16]; + F64 proj[16]; + + for (U32 i = 0; i < 16; i++) + { + model[i] = (F64) gGLModelView[i]; + proj[i] = (F64) gGLProjection[i]; + } + + GLdouble objX,objY,objZ; + + LLVector3 frust[8]; + + if (no_hacks) + { + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + } + else if (zflip) + { + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + + for (U32 i = 0; i < 4; i++) + { + frust[i+4] = frust[i+4]-frust[i]; + frust[i+4].normVec(); + frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); + } + } + else + { + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + if (ortho) + { + LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; + for (U32 i = 0; i < 4; i++) + { + frust[i+4] = frust[i] + far_shift; + } + } + else + { + for (U32 i = 0; i < 4; i++) + { + LLVector3 vec = frust[i] - camera.getOrigin(); + vec.normVec(); + frust[i+4] = camera.getOrigin() + vec*camera.getFar(); + } + } + } + + camera.calcAgentFrustumPlanes(frust); } void LLViewerCamera::setPerspective(BOOL for_selection, - S32 x, S32 y_from_bot, S32 width, S32 height, - BOOL limit_select_distance, - F32 z_near, F32 z_far) + S32 x, S32 y_from_bot, S32 width, S32 height, + BOOL limit_select_distance, + F32 z_near, F32 z_far) { - F32 fov_y, aspect; - fov_y = RAD_TO_DEG * getView(); - BOOL z_default_far = FALSE; - if (z_far <= 0) - { - z_default_far = TRUE; - z_far = getFar(); - } - if (z_near <= 0) - { - z_near = getNear(); - } - aspect = getAspect(); - - // Load camera view matrix - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadIdentity(); - - glh::matrix4f proj_mat; - - if (for_selection) - { - // make a tiny little viewport - // anything drawn into this viewport will be "selected" - - GLint viewport[4]; - viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - - proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport); - - if (limit_select_distance) - { - // ...select distance from control - z_far = gSavedSettings.getF32("MaxSelectDistance"); - } - else - { - z_far = gAgentCamera.mDrawDistance; - } - } - else - { - // Only override the far clip if it's not passed in explicitly. - if (z_default_far) - { - z_far = MAX_FAR_CLIP; - } - glViewport(x, y_from_bot, width, height); - gGLViewport[0] = x; - gGLViewport[1] = y_from_bot; - gGLViewport[2] = width; - gGLViewport[3] = height; - } - - if (mZoomFactor > 1.f) - { - float offset = mZoomFactor - 1.f; - int pos_y = mZoomSubregion / llceil(mZoomFactor); - int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor)); - glh::matrix4f translate; - translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f)); - glh::matrix4f scale; - scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f)); - - proj_mat = scale*proj_mat; - proj_mat = translate*proj_mat; - } - - calcProjection(z_far); // Update the projection matrix cache - - proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); - - gGL.loadMatrix(proj_mat.m); - - for (U32 i = 0; i < 16; i++) - { - gGLProjection[i] = proj_mat.m[i]; - } - - gGL.matrixMode(LLRender::MM_MODELVIEW); - - glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION); - - GLfloat ogl_matrix[16]; - - getOpenGLTransform(ogl_matrix); - - modelview *= glh::matrix4f(ogl_matrix); - - gGL.loadMatrix(modelview.m); - - if (for_selection && (width > 1 || height > 1)) - { - // NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window) - // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not - // comfortable hacking on it. - calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, - (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f, - (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, - (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f); - - } - - // if not picking and not doing a snapshot, cache various GL matrices - if (!for_selection && mZoomFactor == 1.f) - { - // Save GL matrices for access elsewhere in code, especially project_world_to_screen - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = modelview.m[i]; - } - } - - updateFrustumPlanes(*this); + F32 fov_y, aspect; + fov_y = RAD_TO_DEG * getView(); + BOOL z_default_far = FALSE; + if (z_far <= 0) + { + z_default_far = TRUE; + z_far = getFar(); + } + if (z_near <= 0) + { + z_near = getNear(); + } + aspect = getAspect(); + + // Load camera view matrix + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadIdentity(); + + glh::matrix4f proj_mat; + + if (for_selection) + { + // make a tiny little viewport + // anything drawn into this viewport will be "selected" + + GLint viewport[4]; + viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + + proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport); + + if (limit_select_distance) + { + // ...select distance from control + z_far = gSavedSettings.getF32("MaxSelectDistance"); + } + else + { + z_far = gAgentCamera.mDrawDistance; + } + } + else + { + // Only override the far clip if it's not passed in explicitly. + if (z_default_far) + { + z_far = MAX_FAR_CLIP; + } + glViewport(x, y_from_bot, width, height); + gGLViewport[0] = x; + gGLViewport[1] = y_from_bot; + gGLViewport[2] = width; + gGLViewport[3] = height; + } + + if (mZoomFactor > 1.f) + { + float offset = mZoomFactor - 1.f; + int pos_y = mZoomSubregion / llceil(mZoomFactor); + int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor)); + glh::matrix4f translate; + translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f)); + glh::matrix4f scale; + scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f)); + + proj_mat = scale*proj_mat; + proj_mat = translate*proj_mat; + } + + calcProjection(z_far); // Update the projection matrix cache + + proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); + + gGL.loadMatrix(proj_mat.m); + + for (U32 i = 0; i < 16; i++) + { + gGLProjection[i] = proj_mat.m[i]; + } + + gGL.matrixMode(LLRender::MM_MODELVIEW); + + glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION); + + GLfloat ogl_matrix[16]; + + getOpenGLTransform(ogl_matrix); + + modelview *= glh::matrix4f(ogl_matrix); + + gGL.loadMatrix(modelview.m); + + if (for_selection && (width > 1 || height > 1)) + { + // NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window) + // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not + // comfortable hacking on it. + calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, + (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f, + (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, + (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f); + + } + + // if not picking and not doing a snapshot, cache various GL matrices + if (!for_selection && mZoomFactor == 1.f) + { + // Save GL matrices for access elsewhere in code, especially project_world_to_screen + for (U32 i = 0; i < 16; i++) + { + gGLModelView[i] = modelview.m[i]; + } + } + + updateFrustumPlanes(*this); } @@ -421,24 +421,24 @@ void LLViewerCamera::setPerspective(BOOL for_selection, // screen coordinates to the agent's region. void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const { - GLdouble x, y, z; - - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - gluUnProject( - GLdouble(screen_x), GLdouble(screen_y), 0.0, - mdlv, proj, (GLint*)gGLViewport, - &x, - &y, - &z ); - pos_agent->setVec( (F32)x, (F32)y, (F32)z ); + GLdouble x, y, z; + + F64 mdlv[16]; + F64 proj[16]; + + for (U32 i = 0; i < 16; i++) + { + mdlv[i] = (F64) gGLModelView[i]; + proj[i] = (F64) gGLProjection[i]; + } + + gluUnProject( + GLdouble(screen_x), GLdouble(screen_y), 0.0, + mdlv, proj, (GLint*)gGLViewport, + &x, + &y, + &z ); + pos_agent->setVec( (F32)x, (F32)y, (F32)z ); } // Uses the last GL matrices set in set_perspective to project a point from @@ -446,318 +446,318 @@ void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 scree // the current window. BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const { - BOOL in_front = TRUE; - GLdouble x, y, z; // object's window coords, GL-style - - LLVector3 dir_to_point = pos_agent - getOrigin(); - dir_to_point /= dir_to_point.magVec(); - - if (dir_to_point * getAtAxis() < 0.f) - { - if (clamp) - { - return FALSE; - } - else - { - in_front = FALSE; - } - } - - LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); - S32 viewport[4]; - viewport[0] = world_view_rect.mLeft; - viewport[1] = world_view_rect.mBottom; - viewport[2] = world_view_rect.getWidth(); - viewport[3] = world_view_rect.getHeight(); - - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], - mdlv, proj, (GLint*)viewport, - &x, &y, &z)) - { - // convert screen coordinates to virtual UI coordinates - x /= gViewerWindow->getDisplayScale().mV[VX]; - y /= gViewerWindow->getDisplayScale().mV[VY]; - - // should now have the x,y coords of grab_point in screen space - LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - - // convert to pixel coordinates - S32 int_x = lltrunc(x); - S32 int_y = lltrunc(y); - - BOOL valid = TRUE; - - if (clamp) - { - if (int_x < world_rect.mLeft) - { - out_point.mX = world_rect.mLeft; - valid = FALSE; - } - else if (int_x > world_rect.mRight) - { - out_point.mX = world_rect.mRight; - valid = FALSE; - } - else - { - out_point.mX = int_x; - } - - if (int_y < world_rect.mBottom) - { - out_point.mY = world_rect.mBottom; - valid = FALSE; - } - else if (int_y > world_rect.mTop) - { - out_point.mY = world_rect.mTop; - valid = FALSE; - } - else - { - out_point.mY = int_y; - } - return valid; - } - else - { - out_point.mX = int_x; - out_point.mY = int_y; - - if (int_x < world_rect.mLeft) - { - valid = FALSE; - } - else if (int_x > world_rect.mRight) - { - valid = FALSE; - } - if (int_y < world_rect.mBottom) - { - valid = FALSE; - } - else if (int_y > world_rect.mTop) - { - valid = FALSE; - } - - return in_front && valid; - } - } - else - { - return FALSE; - } + BOOL in_front = TRUE; + GLdouble x, y, z; // object's window coords, GL-style + + LLVector3 dir_to_point = pos_agent - getOrigin(); + dir_to_point /= dir_to_point.magVec(); + + if (dir_to_point * getAtAxis() < 0.f) + { + if (clamp) + { + return FALSE; + } + else + { + in_front = FALSE; + } + } + + LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); + S32 viewport[4]; + viewport[0] = world_view_rect.mLeft; + viewport[1] = world_view_rect.mBottom; + viewport[2] = world_view_rect.getWidth(); + viewport[3] = world_view_rect.getHeight(); + + F64 mdlv[16]; + F64 proj[16]; + + for (U32 i = 0; i < 16; i++) + { + mdlv[i] = (F64) gGLModelView[i]; + proj[i] = (F64) gGLProjection[i]; + } + + if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], + mdlv, proj, (GLint*)viewport, + &x, &y, &z)) + { + // convert screen coordinates to virtual UI coordinates + x /= gViewerWindow->getDisplayScale().mV[VX]; + y /= gViewerWindow->getDisplayScale().mV[VY]; + + // should now have the x,y coords of grab_point in screen space + LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); + + // convert to pixel coordinates + S32 int_x = lltrunc(x); + S32 int_y = lltrunc(y); + + BOOL valid = TRUE; + + if (clamp) + { + if (int_x < world_rect.mLeft) + { + out_point.mX = world_rect.mLeft; + valid = FALSE; + } + else if (int_x > world_rect.mRight) + { + out_point.mX = world_rect.mRight; + valid = FALSE; + } + else + { + out_point.mX = int_x; + } + + if (int_y < world_rect.mBottom) + { + out_point.mY = world_rect.mBottom; + valid = FALSE; + } + else if (int_y > world_rect.mTop) + { + out_point.mY = world_rect.mTop; + valid = FALSE; + } + else + { + out_point.mY = int_y; + } + return valid; + } + else + { + out_point.mX = int_x; + out_point.mY = int_y; + + if (int_x < world_rect.mLeft) + { + valid = FALSE; + } + else if (int_x > world_rect.mRight) + { + valid = FALSE; + } + if (int_y < world_rect.mBottom) + { + valid = FALSE; + } + else if (int_y > world_rect.mTop) + { + valid = FALSE; + } + + return in_front && valid; + } + } + else + { + return FALSE; + } } // Uses the last GL matrices set in set_perspective to project a point from // the agent's region space to the nearest edge in screen coordinates. // Returns TRUE if projection succeeds. BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, - LLCoordGL &out_point) const + LLCoordGL &out_point) const { - LLVector3 dir_to_point = pos_agent - getOrigin(); - dir_to_point /= dir_to_point.magVec(); - - BOOL in_front = TRUE; - if (dir_to_point * getAtAxis() < 0.f) - { - in_front = FALSE; - } - - LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); - S32 viewport[4]; - viewport[0] = world_view_rect.mLeft; - viewport[1] = world_view_rect.mBottom; - viewport[2] = world_view_rect.getWidth(); - viewport[3] = world_view_rect.getHeight(); - GLdouble x, y, z; // object's window coords, GL-style - - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - - if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], - pos_agent.mV[VZ], mdlv, - proj, (GLint*)viewport, - &x, &y, &z)) - { - x /= gViewerWindow->getDisplayScale().mV[VX]; - y /= gViewerWindow->getDisplayScale().mV[VY]; - // should now have the x,y coords of grab_point in screen space - const LLRect& world_rect = gViewerWindow->getWorldViewRectScaled(); - - // ...sanity check - S32 int_x = lltrunc(x); - S32 int_y = lltrunc(y); - - // find the center - GLdouble center_x = (GLdouble)world_rect.getCenterX(); - GLdouble center_y = (GLdouble)world_rect.getCenterY(); - - if (x == center_x && y == center_y) - { - // can't project to edge from exact center - return FALSE; - } - - // find the line from center to local - GLdouble line_x = x - center_x; - GLdouble line_y = y - center_y; - - int_x = lltrunc(center_x); - int_y = lltrunc(center_y); - - - if (0.f == line_x) - { - // the slope of the line is undefined - if (line_y > 0.f) - { - int_y = world_rect.mTop; - } - else - { - int_y = world_rect.mBottom; - } - } - else if (0 == world_rect.getWidth()) - { - // the diagonal slope of the view is undefined - if (y < world_rect.mBottom) - { - int_y = world_rect.mBottom; - } - else if ( y > world_rect.mTop) - { - int_y = world_rect.mTop; - } - } - else - { - F32 line_slope = (F32)(line_y / line_x); - F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth()); - - if (fabs(line_slope) > rect_slope) - { - if (line_y < 0.f) - { - // bottom - int_y = world_rect.mBottom; - } - else - { - // top - int_y = world_rect.mTop; - } - int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x); - } - else if (fabs(line_slope) < rect_slope) - { - if (line_x < 0.f) - { - // left - int_x = world_rect.mLeft; - } - else - { - // right - int_x = world_rect.mRight; - } - int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y); - } - else - { - // exactly parallel ==> push to the corners - if (line_x > 0.f) - { - int_x = world_rect.mRight; - } - else - { - int_x = world_rect.mLeft; - } - if (line_y > 0.0f) - { - int_y = world_rect.mTop; - } - else - { - int_y = world_rect.mBottom; - } - } - } - if (!in_front) - { - int_x = world_rect.mLeft + world_rect.mRight - int_x; - int_y = world_rect.mBottom + world_rect.mTop - int_y; - } - - out_point.mX = int_x + world_rect.mLeft; - out_point.mY = int_y + world_rect.mBottom; - return TRUE; - } - return FALSE; + LLVector3 dir_to_point = pos_agent - getOrigin(); + dir_to_point /= dir_to_point.magVec(); + + BOOL in_front = TRUE; + if (dir_to_point * getAtAxis() < 0.f) + { + in_front = FALSE; + } + + LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); + S32 viewport[4]; + viewport[0] = world_view_rect.mLeft; + viewport[1] = world_view_rect.mBottom; + viewport[2] = world_view_rect.getWidth(); + viewport[3] = world_view_rect.getHeight(); + GLdouble x, y, z; // object's window coords, GL-style + + F64 mdlv[16]; + F64 proj[16]; + + for (U32 i = 0; i < 16; i++) + { + mdlv[i] = (F64) gGLModelView[i]; + proj[i] = (F64) gGLProjection[i]; + } + + if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], + pos_agent.mV[VZ], mdlv, + proj, (GLint*)viewport, + &x, &y, &z)) + { + x /= gViewerWindow->getDisplayScale().mV[VX]; + y /= gViewerWindow->getDisplayScale().mV[VY]; + // should now have the x,y coords of grab_point in screen space + const LLRect& world_rect = gViewerWindow->getWorldViewRectScaled(); + + // ...sanity check + S32 int_x = lltrunc(x); + S32 int_y = lltrunc(y); + + // find the center + GLdouble center_x = (GLdouble)world_rect.getCenterX(); + GLdouble center_y = (GLdouble)world_rect.getCenterY(); + + if (x == center_x && y == center_y) + { + // can't project to edge from exact center + return FALSE; + } + + // find the line from center to local + GLdouble line_x = x - center_x; + GLdouble line_y = y - center_y; + + int_x = lltrunc(center_x); + int_y = lltrunc(center_y); + + + if (0.f == line_x) + { + // the slope of the line is undefined + if (line_y > 0.f) + { + int_y = world_rect.mTop; + } + else + { + int_y = world_rect.mBottom; + } + } + else if (0 == world_rect.getWidth()) + { + // the diagonal slope of the view is undefined + if (y < world_rect.mBottom) + { + int_y = world_rect.mBottom; + } + else if ( y > world_rect.mTop) + { + int_y = world_rect.mTop; + } + } + else + { + F32 line_slope = (F32)(line_y / line_x); + F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth()); + + if (fabs(line_slope) > rect_slope) + { + if (line_y < 0.f) + { + // bottom + int_y = world_rect.mBottom; + } + else + { + // top + int_y = world_rect.mTop; + } + int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x); + } + else if (fabs(line_slope) < rect_slope) + { + if (line_x < 0.f) + { + // left + int_x = world_rect.mLeft; + } + else + { + // right + int_x = world_rect.mRight; + } + int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y); + } + else + { + // exactly parallel ==> push to the corners + if (line_x > 0.f) + { + int_x = world_rect.mRight; + } + else + { + int_x = world_rect.mLeft; + } + if (line_y > 0.0f) + { + int_y = world_rect.mTop; + } + else + { + int_y = world_rect.mBottom; + } + } + } + if (!in_front) + { + int_x = world_rect.mLeft + world_rect.mRight - int_x; + int_y = world_rect.mBottom + world_rect.mTop - int_y; + } + + out_point.mX = int_x + world_rect.mLeft; + out_point.mY = int_y + world_rect.mBottom; + return TRUE; + } + return FALSE; } void LLViewerCamera::getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right) { - LLVector3 to_vec = pos_agent - getOrigin(); + LLVector3 to_vec = pos_agent - getOrigin(); - F32 at_dist = to_vec * getAtAxis(); + F32 at_dist = to_vec * getAtAxis(); - F32 height_meters = at_dist* (F32)tan(getView()/2.f); - F32 height_pixels = getViewHeightInPixels()/2.f; + F32 height_meters = at_dist* (F32)tan(getView()/2.f); + F32 height_pixels = getViewHeightInPixels()/2.f; - F32 pixel_aspect = gViewerWindow->getWindow()->getPixelAspectRatio(); + F32 pixel_aspect = gViewerWindow->getWindow()->getPixelAspectRatio(); - F32 meters_per_pixel = height_meters / height_pixels; - up = getUpAxis() * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY]; - right = -1.f * pixel_aspect * meters_per_pixel * getLeftAxis() * gViewerWindow->getDisplayScale().mV[VX]; + F32 meters_per_pixel = height_meters / height_pixels; + up = getUpAxis() * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY]; + right = -1.f * pixel_aspect * meters_per_pixel * getLeftAxis() * gViewerWindow->getDisplayScale().mV[VX]; } LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent) { - F32 dist = (pos_agent - getOrigin()).magVec(); - // Convert to screen space and back, preserving the depth. - LLCoordGL screen_point; - if (!projectPosAgentToScreen(pos_agent, screen_point, FALSE)) - { - // Off the screen, just return the original position. - return pos_agent; - } - - LLVector3 ray_dir; - - projectScreenToPosAgent(screen_point.mX, screen_point.mY, &ray_dir); - ray_dir -= getOrigin(); - ray_dir.normVec(); - - LLVector3 pos_agent_rounded = getOrigin() + ray_dir*dist; - - /* - LLVector3 pixel_x, pixel_y; - getPixelVectors(pos_agent_rounded, pixel_y, pixel_x); - pos_agent_rounded += 0.5f*pixel_x, 0.5f*pixel_y; - */ - return pos_agent_rounded; + F32 dist = (pos_agent - getOrigin()).magVec(); + // Convert to screen space and back, preserving the depth. + LLCoordGL screen_point; + if (!projectPosAgentToScreen(pos_agent, screen_point, FALSE)) + { + // Off the screen, just return the original position. + return pos_agent; + } + + LLVector3 ray_dir; + + projectScreenToPosAgent(screen_point.mX, screen_point.mY, &ray_dir); + ray_dir -= getOrigin(); + ray_dir.normVec(); + + LLVector3 pos_agent_rounded = getOrigin() + ray_dir*dist; + + /* + LLVector3 pixel_x, pixel_y; + getPixelVectors(pos_agent_rounded, pixel_y, pixel_x); + pos_agent_rounded += 0.5f*pixel_x, 0.5f*pixel_y; + */ + return pos_agent_rounded; } BOOL LLViewerCamera::cameraUnderWater() const @@ -775,69 +775,69 @@ BOOL LLViewerCamera::cameraUnderWater() const regionp = gAgent.getRegion(); } - if(!regionp) - { - return FALSE ; - } + if(!regionp) + { + return FALSE ; + } - return getOrigin().mV[VZ] < regionp->getWaterHeight(); + return getOrigin().mV[VZ] < regionp->getWaterHeight(); } BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) { - S32 i, num_faces; - LLDrawable* drawablep = volumep->mDrawable; - - if (!drawablep) - { - return FALSE; - } - - LLVolume* volume = volumep->getVolume(); - if (!volume) - { - return FALSE; - } - - LLVOVolume* vo_volume = (LLVOVolume*) volumep; - - vo_volume->updateRelativeXform(); - LLMatrix4 mat = vo_volume->getRelativeXform(); - - LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); - - LLMatrix4a render_mata; - render_mata.loadu(render_mat); - LLMatrix4a mata; - mata.loadu(mat); - - num_faces = volume->getNumVolumeFaces(); - for (i = 0; i < num_faces; i++) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - - for (U32 v = 0; v < face.mNumVertices; v++) - { - const LLVector4a& src_vec = face.mPositions[v]; - LLVector4a vec; - mata.affineTransform(src_vec, vec); - - if (drawablep->isActive()) - { - LLVector4a t = vec; - render_mata.affineTransform(t, vec); - } - - BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0; - - if (( !in_frustum && all_verts) || - (in_frustum && !all_verts)) - { - return !all_verts; - } - } - } - return all_verts; + S32 i, num_faces; + LLDrawable* drawablep = volumep->mDrawable; + + if (!drawablep) + { + return FALSE; + } + + LLVolume* volume = volumep->getVolume(); + if (!volume) + { + return FALSE; + } + + LLVOVolume* vo_volume = (LLVOVolume*) volumep; + + vo_volume->updateRelativeXform(); + LLMatrix4 mat = vo_volume->getRelativeXform(); + + LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); + + LLMatrix4a render_mata; + render_mata.loadu(render_mat); + LLMatrix4a mata; + mata.loadu(mat); + + num_faces = volume->getNumVolumeFaces(); + for (i = 0; i < num_faces; i++) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + + for (U32 v = 0; v < face.mNumVertices; v++) + { + const LLVector4a& src_vec = face.mPositions[v]; + LLVector4a vec; + mata.affineTransform(src_vec, vec); + + if (drawablep->isActive()) + { + LLVector4a t = vec; + render_mata.affineTransform(t, vec); + } + + BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0; + + if (( !in_frustum && all_verts) || + (in_frustum && !all_verts)) + { + return !all_verts; + } + } + } + return all_verts; } extern BOOL gCubeSnapshot; @@ -847,29 +847,29 @@ extern BOOL gCubeSnapshot; { llassert(!gCubeSnapshot); - F32 old_fov = LLViewerCamera::getInstance()->getView(); + F32 old_fov = LLViewerCamera::getInstance()->getView(); - // cap the FoV - vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); + // cap the FoV + vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); - if (vertical_fov_rads == old_fov) return; + if (vertical_fov_rads == old_fov) return; - // send the new value to the simulator - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_AgentFOV); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); + // send the new value to the simulator + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentFOV); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); - msg->nextBlockFast(_PREHASH_FOVBlock); - msg->addU32Fast(_PREHASH_GenCounter, 0); - msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads); + msg->nextBlockFast(_PREHASH_FOVBlock); + msg->addU32Fast(_PREHASH_GenCounter, 0); + msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads); - gAgent.sendReliableMessage(); + gAgent.sendReliableMessage(); - // sync the camera with the new value - LLCamera::setView(vertical_fov_rads); // call base implementation + // sync the camera with the new value + LLCamera::setView(vertical_fov_rads); // call base implementation } void LLViewerCamera::setViewNoBroadcast(F32 vertical_fov_rads) @@ -877,28 +877,28 @@ void LLViewerCamera::setViewNoBroadcast(F32 vertical_fov_rads) LLCamera::setView(vertical_fov_rads); } -void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) +void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) { - vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); - setView(vertical_fov_rads); - mCameraFOVDefault = vertical_fov_rads; - mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); + vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); + setView(vertical_fov_rads); + mCameraFOVDefault = vertical_fov_rads; + mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); } BOOL LLViewerCamera::isDefaultFOVChanged() { - if(mPrevCameraFOVDefault != mCameraFOVDefault) - { - mPrevCameraFOVDefault = mCameraFOVDefault; - return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs"); - } - return FALSE; + if(mPrevCameraFOVDefault != mCameraFOVDefault) + { + mPrevCameraFOVDefault = mCameraFOVDefault; + return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs"); + } + return FALSE; } // static void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value) { - LLViewerCamera* self=(LLViewerCamera*)user_data; - self->setDefaultFOV(value.asReal()); + LLViewerCamera* self=(LLViewerCamera*)user_data; + self->setDefaultFOV(value.asReal()); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 1fc51ac23c..9f2e9a62b7 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llviewercontrol.cpp * @brief Viewer configuration * @author Richard Nelson @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,7 +30,7 @@ #include "llviewercontrol.h" // Library includes -#include "llwindow.h" // getGamma() +#include "llwindow.h" // getGamma() // For Listeners #include "llaudioengine.h" @@ -81,15 +81,15 @@ #include #ifdef TOGGLE_HACKED_GODLIKE_VIEWER -BOOL gHackGodmode = FALSE; +BOOL gHackGodmode = FALSE; #endif // Should you contemplate changing the name "Global", please first grep for // that string literal. There are at least a couple other places in the C++ // code that assume the LLControlGroup named "Global" is gSavedSettings. -LLControlGroup gSavedSettings("Global"); // saved at end of session +LLControlGroup gSavedSettings("Global"); // saved at end of session LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session -LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session +LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings std::string gLastRunVersion; @@ -102,8 +102,8 @@ extern BOOL gDebugGL; static bool handleRenderAvatarMouselookChanged(const LLSD& newvalue) { - LLVOAvatar::sVisibleInFirstPerson = newvalue.asBoolean(); - return true; + LLVOAvatar::sVisibleInFirstPerson = newvalue.asBoolean(); + return true; } static bool handleRenderFarClipChanged(const LLSD& newvalue) @@ -111,9 +111,9 @@ static bool handleRenderFarClipChanged(const LLSD& newvalue) if (LLStartUp::getStartupState() >= STATE_STARTED) { F32 draw_distance = (F32)newvalue.asReal(); - gAgentCamera.mDrawDistance = draw_distance; - LLWorld::getInstance()->setLandFarClip(draw_distance); - return true; + gAgentCamera.mDrawDistance = draw_distance; + LLWorld::getInstance()->setLandFarClip(draw_distance); + return true; } return false; } @@ -125,7 +125,7 @@ static bool handleTerrainScaleChanged(const LLSD& newvalue) { LLDrawPoolTerrain::sDetailScale = F32(1.0 / scale); } - return true; + return true; } static bool handlePBRTerrainScaleChanged(const LLSD& newvalue) @@ -135,7 +135,7 @@ static bool handlePBRTerrainScaleChanged(const LLSD& newvalue) { LLDrawPoolTerrain::sPBRDetailScale = F32(1.0 / scale); } - return true; + return true; } static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) @@ -147,19 +147,19 @@ static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue) { - if (isAgentAvatarValid()) - { - gAgentAvatarp->setHoverIfRegionEnabled(); - } - return true; + if (isAgentAvatarValid()) + { + gAgentAvatarp->setHoverIfRegionEnabled(); + } + return true; } static bool handleSetShaderChanged(const LLSD& newvalue) { - // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache - gBumpImageList.destroyGL(); - gBumpImageList.restoreGL(); + // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache + gBumpImageList.destroyGL(); + gBumpImageList.restoreGL(); if (gPipeline.isInit()) { @@ -167,9 +167,9 @@ static bool handleSetShaderChanged(const LLSD& newvalue) LLPipeline::refreshCachedSettings(); } - // else, leave terrain detail as is - LLViewerShaderMgr::instance()->setShaders(); - return true; + // else, leave terrain detail as is + LLViewerShaderMgr::instance()->setShaders(); + return true; } static bool handleRenderPerfTestChanged(const LLSD& newvalue) @@ -186,10 +186,10 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue) LLPipeline::RENDER_TYPE_HUD, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_HUD_PARTICLES, - LLPipeline::END_RENDER_TYPES); + LLPipeline::END_RENDER_TYPES); gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, false); } - else + else { gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY, LLPipeline::RENDER_TYPE_TERRAIN, @@ -209,55 +209,55 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue) bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { - if (gPipeline.isInit()) - { - gPipeline.updateRenderTransparentWater(); - gPipeline.releaseGLBuffers(); - gPipeline.createGLBuffers(); - LLViewerShaderMgr::instance()->setShaders(); - } - LLWorld::getInstance()->updateWaterObjects(); - return true; + if (gPipeline.isInit()) + { + gPipeline.updateRenderTransparentWater(); + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + LLViewerShaderMgr::instance()->setShaders(); + } + LLWorld::getInstance()->updateWaterObjects(); + return true; } static bool handleShadowsResized(const LLSD& newvalue) { - gPipeline.requestResizeShadowTexture(); - return true; + gPipeline.requestResizeShadowTexture(); + return true; } static bool handleWindowResized(const LLSD& newvalue) { - gPipeline.requestResizeScreenTexture(); - return true; + gPipeline.requestResizeScreenTexture(); + return true; } static bool handleReleaseGLBufferChanged(const LLSD& newvalue) { - if (gPipeline.isInit()) - { - gPipeline.releaseGLBuffers(); - gPipeline.createGLBuffers(); - } - return true; + if (gPipeline.isInit()) + { + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + } + return true; } static bool handleLUTBufferChanged(const LLSD& newvalue) { - if (gPipeline.isInit()) - { - gPipeline.releaseLUTBuffers(); - gPipeline.createLUTBuffers(); - } - return true; + if (gPipeline.isInit()) + { + gPipeline.releaseLUTBuffers(); + gPipeline.createLUTBuffers(); + } + return true; } static bool handleAnisotropicChanged(const LLSD& newvalue) { - LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); - LLImageGL::dirtyTexOptions(); - return true; + LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); + LLImageGL::dirtyTexOptions(); + return true; } static bool handleVSyncChanged(const LLSD& newvalue) @@ -276,62 +276,62 @@ static bool handleVSyncChanged(const LLSD& newvalue) static bool handleVolumeLODChanged(const LLSD& newvalue) { - LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); - LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; - return true; + LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); + LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; + return true; } static bool handleAvatarLODChanged(const LLSD& newvalue) { - LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); - return true; + LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); + return true; } static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue) { - LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); - return true; + LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); + return true; } static bool handleTerrainLODChanged(const LLSD& newvalue) { - LLVOSurfacePatch::sLODFactor = (F32)newvalue.asReal(); - //sqaure lod factor to get exponential range of [0,4] and keep - //a value of 1 in the middle of the detail slider for consistency - //with other detail sliders (see panel_preferences_graphics1.xml) - LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; - return true; + LLVOSurfacePatch::sLODFactor = (F32)newvalue.asReal(); + //sqaure lod factor to get exponential range of [0,4] and keep + //a value of 1 in the middle of the detail slider for consistency + //with other detail sliders (see panel_preferences_graphics1.xml) + LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; + return true; } static bool handleTreeLODChanged(const LLSD& newvalue) { - LLVOTree::sTreeFactor = (F32) newvalue.asReal(); - return true; + LLVOTree::sTreeFactor = (F32) newvalue.asReal(); + return true; } static bool handleFlexLODChanged(const LLSD& newvalue) { - LLVolumeImplFlexible::sUpdateFactor = (F32) newvalue.asReal(); - return true; + LLVolumeImplFlexible::sUpdateFactor = (F32) newvalue.asReal(); + return true; } static bool handleGammaChanged(const LLSD& newvalue) { - F32 gamma = (F32) newvalue.asReal(); - if (gamma == 0.0f) - { - gamma = 1.0f; // restore normal gamma - } - if (gViewerWindow && gViewerWindow->getWindow() && gamma != gViewerWindow->getWindow()->getGamma()) - { - // Only save it if it's changed - if (!gViewerWindow->getWindow()->setGamma(gamma)) - { - LL_WARNS() << "setGamma failed!" << LL_ENDL; - } - } + F32 gamma = (F32) newvalue.asReal(); + if (gamma == 0.0f) + { + gamma = 1.0f; // restore normal gamma + } + if (gViewerWindow && gViewerWindow->getWindow() && gamma != gViewerWindow->getWindow()->getGamma()) + { + // Only save it if it's changed + if (!gViewerWindow->getWindow()->setGamma(gamma)) + { + LL_WARNS() << "setGamma failed!" << LL_ENDL; + } + } - return true; + return true; } const F32 MAX_USER_FOG_RATIO = 10.f; @@ -339,93 +339,93 @@ const F32 MIN_USER_FOG_RATIO = 0.5f; static bool handleFogRatioChanged(const LLSD& newvalue) { - F32 fog_ratio = llmax(MIN_USER_FOG_RATIO, llmin((F32) newvalue.asReal(), MAX_USER_FOG_RATIO)); - gSky.setFogRatio(fog_ratio); - return true; + F32 fog_ratio = llmax(MIN_USER_FOG_RATIO, llmin((F32) newvalue.asReal(), MAX_USER_FOG_RATIO)); + gSky.setFogRatio(fog_ratio); + return true; } static bool handleMaxPartCountChanged(const LLSD& newvalue) { - LLViewerPartSim::setMaxPartCount(newvalue.asInteger()); - return true; + LLViewerPartSim::setMaxPartCount(newvalue.asInteger()); + return true; } static bool handleChatFontSizeChanged(const LLSD& newvalue) { - if(gConsole) - { - gConsole->setFontSize(newvalue.asInteger()); - } - return true; + if(gConsole) + { + gConsole->setFontSize(newvalue.asInteger()); + } + return true; } static bool handleChatPersistTimeChanged(const LLSD& newvalue) { - if(gConsole) - { - gConsole->setLinePersistTime((F32) newvalue.asReal()); - } - return true; + if(gConsole) + { + gConsole->setLinePersistTime((F32) newvalue.asReal()); + } + return true; } static bool handleConsoleMaxLinesChanged(const LLSD& newvalue) { - if(gConsole) - { - gConsole->setMaxLines(newvalue.asInteger()); - } - return true; + if(gConsole) + { + gConsole->setMaxLines(newvalue.asInteger()); + } + return true; } static void handleAudioVolumeChanged(const LLSD& newvalue) { - audio_update_volume(true); + audio_update_volume(true); } static bool handleJoystickChanged(const LLSD& newvalue) { - LLViewerJoystick::getInstance()->setCameraNeedsUpdate(TRUE); - return true; + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(TRUE); + return true; } static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() - && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; - return true; + LLPipeline::sUseOcclusion = (newvalue.asBoolean() + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; + return true; } static bool handleUploadBakedTexOldChanged(const LLSD& newvalue) { - LLPipeline::sForceOldBakedUpload = newvalue.asBoolean(); - return true; + LLPipeline::sForceOldBakedUpload = newvalue.asBoolean(); + return true; } static bool handleWLSkyDetailChanged(const LLSD&) { - if (gSky.mVOWLSkyp.notNull()) - { - gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable); - } - return true; + if (gSky.mVOWLSkyp.notNull()) + { + gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable); + } + return true; } static bool handleRepartition(const LLSD&) { - if (gPipeline.isInit()) - { - gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); - gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); - gObjectList.repartitionObjects(); - } - return true; + if (gPipeline.isInit()) + { + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); + gObjectList.repartitionObjects(); + } + return true; } static bool handleRenderDynamicLODChanged(const LLSD& newvalue) { - LLPipeline::sDynamicLOD = newvalue.asBoolean(); - return true; + LLPipeline::sDynamicLOD = newvalue.asBoolean(); + return true; } static bool handleReflectionProbeDetailChanged(const LLSD& newvalue) @@ -456,161 +456,161 @@ static bool handleHeroProbeResolutionChanged(const LLSD &newvalue) static bool handleRenderDebugPipelineChanged(const LLSD& newvalue) { - gDebugPipeline = newvalue.asBoolean(); - return true; + gDebugPipeline = newvalue.asBoolean(); + return true; } static bool handleRenderResolutionDivisorChanged(const LLSD&) { - gResizeScreenTexture = TRUE; - return true; + gResizeScreenTexture = TRUE; + return true; } static bool handleDebugViewsChanged(const LLSD& newvalue) { - LLView::sDebugRects = newvalue.asBoolean(); - return true; + LLView::sDebugRects = newvalue.asBoolean(); + return true; } static bool handleLogFileChanged(const LLSD& newvalue) { - std::string log_filename = newvalue.asString(); - LLFile::remove(log_filename); - LLError::logToFile(log_filename); - return true; + std::string log_filename = newvalue.asString(); + LLFile::remove(log_filename); + LLError::logToFile(log_filename); + return true; } bool handleHideGroupTitleChanged(const LLSD& newvalue) { - gAgent.setHideGroupTitle(newvalue); - return true; + gAgent.setHideGroupTitle(newvalue); + return true; } bool handleEffectColorChanged(const LLSD& newvalue) { - gAgent.setEffectColor(LLColor4(newvalue)); - return true; + gAgent.setEffectColor(LLColor4(newvalue)); + return true; } bool handleHighResSnapshotChanged(const LLSD& newvalue) { - // High Res Snapshot active, must uncheck RenderUIInSnapshot - if (newvalue.asBoolean()) - { - gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE ); - } - return true; + // High Res Snapshot active, must uncheck RenderUIInSnapshot + if (newvalue.asBoolean()) + { + gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE ); + } + return true; } bool handleVoiceClientPrefsChanged(const LLSD& newvalue) { - if (LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->updateSettings(); - } - return true; + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->updateSettings(); + } + return true; } bool handleVelocityInterpolate(const LLSD& newvalue) { - LLMessageSystem* msg = gMessageSystem; - if ( newvalue.asBoolean() ) - { - msg->newMessageFast(_PREHASH_VelocityInterpolateOn); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gAgent.sendReliableMessage(); - LL_INFOS() << "Velocity Interpolation On" << LL_ENDL; - } - else - { - msg->newMessageFast(_PREHASH_VelocityInterpolateOff); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gAgent.sendReliableMessage(); - LL_INFOS() << "Velocity Interpolation Off" << LL_ENDL; - } - return true; + LLMessageSystem* msg = gMessageSystem; + if ( newvalue.asBoolean() ) + { + msg->newMessageFast(_PREHASH_VelocityInterpolateOn); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + LL_INFOS() << "Velocity Interpolation On" << LL_ENDL; + } + else + { + msg->newMessageFast(_PREHASH_VelocityInterpolateOff); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + LL_INFOS() << "Velocity Interpolation Off" << LL_ENDL; + } + return true; } bool handleForceShowGrid(const LLSD& newvalue) { - LLPanelLogin::updateLocationSelectorsVisibility(); - return true; + LLPanelLogin::updateLocationSelectorsVisibility(); + return true; } bool handleLoginLocationChanged() { - /* - * This connects the default preference setting to the state of the login - * panel if it is displayed; if you open the preferences panel before - * logging in, and change the default login location there, the login - * panel immediately changes to match your new preference. - */ - std::string new_login_location = gSavedSettings.getString("LoginLocation"); - LL_DEBUGS("AppInit")< dict_list; - std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); - boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); - if (!dict_list.empty()) - { - LLSpellChecker::setUseSpellCheck(dict_list.front()); - dict_list.pop_front(); - LLSpellChecker::instance().setSecondaryDictionaries(dict_list); - return true; - } - } - LLSpellChecker::setUseSpellCheck(LLStringUtil::null); - return true; + if (gSavedSettings.getBOOL("SpellCheck")) + { + std::list dict_list; + std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); + boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); + if (!dict_list.empty()) + { + LLSpellChecker::setUseSpellCheck(dict_list.front()); + dict_list.pop_front(); + LLSpellChecker::instance().setSecondaryDictionaries(dict_list); + return true; + } + } + LLSpellChecker::setUseSpellCheck(LLStringUtil::null); + return true; } bool toggle_agent_pause(const LLSD& newvalue) { - if ( newvalue.asBoolean() ) - { - send_agent_pause(); - } - else - { - send_agent_resume(); - } - return true; + if ( newvalue.asBoolean() ) + { + send_agent_pause(); + } + else + { + send_agent_resume(); + } + return true; } bool toggle_show_navigation_panel(const LLSD& newvalue) { - bool value = newvalue.asBoolean(); + bool value = newvalue.asBoolean(); - LLNavigationBar::getInstance()->setVisible(value); - gSavedSettings.setBOOL("ShowMiniLocationPanel", !value); + LLNavigationBar::getInstance()->setVisible(value); + gSavedSettings.setBOOL("ShowMiniLocationPanel", !value); gViewerWindow->reshapeStatusBarContainer(); - return true; + return true; } bool toggle_show_mini_location_panel(const LLSD& newvalue) { - bool value = newvalue.asBoolean(); + bool value = newvalue.asBoolean(); - LLPanelTopInfoBar::getInstance()->setVisible(value); - gSavedSettings.setBOOL("ShowNavbarNavigationPanel", !value); + LLPanelTopInfoBar::getInstance()->setVisible(value); + gSavedSettings.setBOOL("ShowNavbarNavigationPanel", !value); - return true; + return true; } bool toggle_show_object_render_cost(const LLSD& newvalue) { - LLFloaterTools::sShowObjectCost = newvalue.asBoolean(); - return true; + LLFloaterTools::sShowObjectCost = newvalue.asBoolean(); + return true; } void handleTargetFPSChanged(const LLSD& newValue) @@ -757,7 +757,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); - setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); @@ -848,7 +848,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); - setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); @@ -904,21 +904,21 @@ static LLCachedControl test_BrowserHomePage("BrowserHomePage", "hah void test_cached_control() { #define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL; } while(0) - TEST_LLCC(U32, 666); - TEST_LLCC(S32, (S32)-666); - TEST_LLCC(F32, (F32)-666.666); - TEST_LLCC(bool, true); - TEST_LLCC(BOOL, FALSE); - if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; - TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); - TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); - TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); - TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); - TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); - TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); -//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); - - if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL; + TEST_LLCC(U32, 666); + TEST_LLCC(S32, (S32)-666); + TEST_LLCC(F32, (F32)-666.666); + TEST_LLCC(bool, true); + TEST_LLCC(BOOL, FALSE); + if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; + TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); + TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); + TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); + TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); + TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); + TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); +//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); + + if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL; } #endif // TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 2a77146101..75e5049370 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewerdisplay.cpp * @brief LLViewerDisplay class implementation * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -87,10 +87,10 @@ extern bool gShiftFrame; LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport -BOOL gTeleportDisplay = FALSE; +BOOL gTeleportDisplay = FALSE; LLFrameTimer gTeleportDisplayTimer; LLFrameTimer gTeleportArrivalTimer; -const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain +const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain BOOL gForceRenderLandFence = FALSE; BOOL gDisplaySwapBuffers = FALSE; @@ -125,84 +125,84 @@ void render_disconnected_background(); void display_startup() { - if ( !gViewerWindow - || !gViewerWindow->getActive() - || !gViewerWindow->getWindow()->getVisible() - || gViewerWindow->getWindow()->getMinimized() - || gNonInteractive) - { - return; - } - - gPipeline.updateGL(); - - // Written as branch to appease GCC which doesn't like different - // pointer types across ternary ops - // - if (!LLViewerFetchedTexture::sWhiteImagep.isNull()) - { - LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); - } - - LLGLSDefault gls_default; - - // Required for HTML update in login screen - static S32 frame_count = 0; - - LLGLState::checkStates(); - - if (frame_count++ > 1) // make sure we have rendered a frame first - { - LLViewerDynamicTexture::updateAllInstances(); - } + if ( !gViewerWindow + || !gViewerWindow->getActive() + || !gViewerWindow->getWindow()->getVisible() + || gViewerWindow->getWindow()->getMinimized() + || gNonInteractive) + { + return; + } + + gPipeline.updateGL(); + + // Written as branch to appease GCC which doesn't like different + // pointer types across ternary ops + // + if (!LLViewerFetchedTexture::sWhiteImagep.isNull()) + { + LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); + } + + LLGLSDefault gls_default; + + // Required for HTML update in login screen + static S32 frame_count = 0; + + LLGLState::checkStates(); + + if (frame_count++ > 1) // make sure we have rendered a frame first + { + LLViewerDynamicTexture::updateAllInstances(); + } else { LL_DEBUGS("Window") << "First display_startup frame" << LL_ENDL; } - LLGLState::checkStates(); + LLGLState::checkStates(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT); - LLGLSUIDefault gls_ui; - gPipeline.disableLights(); + LLGLSUIDefault gls_ui; + gPipeline.disableLights(); - if (gViewerWindow) - gViewerWindow->setup2DRender(); - if (gViewerWindow) - gViewerWindow->draw(); - gGL.flush(); + if (gViewerWindow) + gViewerWindow->setup2DRender(); + if (gViewerWindow) + gViewerWindow->draw(); + gGL.flush(); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); + LLGLState::checkStates(); - if (gViewerWindow && gViewerWindow->getWindow()) - gViewerWindow->getWindow()->swapBuffers(); + if (gViewerWindow && gViewerWindow->getWindow()) + gViewerWindow->getWindow()->swapBuffers(); - glClear(GL_DEPTH_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); } void display_update_camera() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Camera"); - // TODO: cut draw distance down if customizing avatar? - // TODO: cut draw distance on per-parcel basis? + // TODO: cut draw distance down if customizing avatar? + // TODO: cut draw distance on per-parcel basis? - // Cut draw distance in half when customizing avatar, - // but on the viewer only. - F32 final_far = gAgentCamera.mDrawDistance; + // Cut draw distance in half when customizing avatar, + // but on the viewer only. + F32 final_far = gAgentCamera.mDrawDistance; if (gCubeSnapshot) { final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance"); } else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) - - { - final_far *= 0.5f; - } - LLViewerCamera::getInstance()->setFar(final_far); - gViewerWindow->setup3DRender(); - + + { + final_far *= 0.5f; + } + LLViewerCamera::getInstance()->setFar(final_far); + gViewerWindow->setup3DRender(); + if (!gCubeSnapshot) { // Update land visibility too @@ -213,30 +213,30 @@ void display_update_camera() // Write some stats to LL_INFOS() void display_stats() { - LL_PROFILE_ZONE_SCOPED - F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); - if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS"); - F32 fps = gRecentFrameCount / fps_log_freq; - LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL; - gRecentFrameCount = 0; - gRecentFPSTime.reset(); - } - F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); - if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory"); - gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS()); - U32Megabytes memory = gMemoryAllocated; - LL_INFOS() << "MEMORY: " << memory << LL_ENDL; - LLMemory::logMemoryInfo(TRUE) ; - gRecentMemoryTime.reset(); - } + LL_PROFILE_ZONE_SCOPED + F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); + if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS"); + F32 fps = gRecentFrameCount / fps_log_freq; + LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL; + gRecentFrameCount = 0; + gRecentFPSTime.reset(); + } + F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); + if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory"); + gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS()); + U32Megabytes memory = gMemoryAllocated; + LL_INFOS() << "MEMORY: " << memory << LL_ENDL; + LLMemory::logMemoryInfo(TRUE) ; + gRecentMemoryTime.reset(); + } F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency"); if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage"); + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage"); gAssetStorageLogTime.reset(); gAssetStorage->logAssetStorageInfo(); } @@ -244,144 +244,144 @@ void display_stats() static void update_tp_display(bool minimized) { - static LLCachedControl teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay"); - static LLCachedControl teleport_local_delay(gSavedSettings, "TeleportLocalDelay"); - - S32 attach_count = 0; - if (isAgentAvatarValid()) - { - attach_count = gAgentAvatarp->getAttachmentCount(); - } - F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; - F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); - F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); - if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f) - { - // Give up. Don't keep the UI locked forever. - LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL; - gAgent.setTeleportState(LLAgent::TELEPORT_NONE); - gAgent.setTeleportMessage(std::string()); - } - - // Make sure the TP progress panel gets hidden in case the viewer window - // is minimized *during* a TP. HB - if (minimized) - { - gViewerWindow->setShowProgress(FALSE); - } - - const std::string& message = gAgent.getTeleportMessage(); - switch (gAgent.getTeleportState()) - { - case LLAgent::TELEPORT_PENDING: - { - gTeleportDisplayTimer.reset(); - const std::string& msg = LLAgent::sTeleportProgressMessages["pending"]; - if (!minimized) - { - gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); - gViewerWindow->setProgressString(msg); - } - gAgent.setTeleportMessage(msg); - break; - } - - case LLAgent::TELEPORT_START: - { - // Transition to REQUESTED. Viewer has sent some kind - // of TeleportRequest to the source simulator - gTeleportDisplayTimer.reset(); - const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"]; - LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL; - gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED); - gAgent.setTeleportMessage(msg); - if (!minimized) - { - gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); - gViewerWindow->setProgressString(msg); - gViewerWindow->setProgressMessage(gAgent.mMOTD); - } - break; - } - - case LLAgent::TELEPORT_REQUESTED: - // Waiting for source simulator to respond - if (!minimized) - { - gViewerWindow->setProgressPercent(llmin(teleport_percent, 37.5f)); - gViewerWindow->setProgressString(message); - } - break; - - case LLAgent::TELEPORT_MOVING: - // Viewer has received destination location from source simulator - if (!minimized) - { - gViewerWindow->setProgressPercent(llmin(teleport_percent, 75.f)); - gViewerWindow->setProgressString(message); - } - break; - - case LLAgent::TELEPORT_START_ARRIVAL: - // Transition to ARRIVING. Viewer has received avatar update, etc., - // from destination simulator - gTeleportArrivalTimer.reset(); - LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL; - gAgent.setTeleportState(LLAgent::TELEPORT_ARRIVING); - gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["arriving"]); - gAgent.sheduleTeleportIM(); - gTextureList.mForceResetTextureStats = TRUE; - gAgentCamera.resetView(TRUE, TRUE); - if (!minimized) - { - gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); - gViewerWindow->setProgressPercent(75.f); - } - break; - - case LLAgent::TELEPORT_ARRIVING: - // Make the user wait while content "pre-caches" - { - F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay()); - if (arrival_fraction > 1.f) - { - arrival_fraction = 1.f; - //LLFirstUse::useTeleport(); - LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL; - gAgent.setTeleportState(LLAgent::TELEPORT_NONE); - } - if (!minimized) - { - gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); - gViewerWindow->setProgressPercent(arrival_fraction * 25.f + 75.f); - gViewerWindow->setProgressString(message); - } - break; - } - - case LLAgent::TELEPORT_LOCAL: - // Short delay when teleporting in the same sim (progress screen active but not shown - did not - // fall-through from TELEPORT_START) - { - if (gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay()) - { - //LLFirstUse::useTeleport(); - LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32() - << " exceeds teleport_local_delete " << teleport_local_delay - << "; setting state to TELEPORT_NONE" - << LL_ENDL; - gAgent.setTeleportState(LLAgent::TELEPORT_NONE); - } - break; - } - - case LLAgent::TELEPORT_NONE: - // No teleport in progress - gViewerWindow->setShowProgress(FALSE); - gTeleportDisplay = FALSE; - } + static LLCachedControl teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay"); + static LLCachedControl teleport_local_delay(gSavedSettings, "TeleportLocalDelay"); + + S32 attach_count = 0; + if (isAgentAvatarValid()) + { + attach_count = gAgentAvatarp->getAttachmentCount(); + } + F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; + F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); + F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); + if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f) + { + // Give up. Don't keep the UI locked forever. + LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL; + gAgent.setTeleportState(LLAgent::TELEPORT_NONE); + gAgent.setTeleportMessage(std::string()); + } + + // Make sure the TP progress panel gets hidden in case the viewer window + // is minimized *during* a TP. HB + if (minimized) + { + gViewerWindow->setShowProgress(FALSE); + } + + const std::string& message = gAgent.getTeleportMessage(); + switch (gAgent.getTeleportState()) + { + case LLAgent::TELEPORT_PENDING: + { + gTeleportDisplayTimer.reset(); + const std::string& msg = LLAgent::sTeleportProgressMessages["pending"]; + if (!minimized) + { + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gViewerWindow->setProgressString(msg); + } + gAgent.setTeleportMessage(msg); + break; + } + + case LLAgent::TELEPORT_START: + { + // Transition to REQUESTED. Viewer has sent some kind + // of TeleportRequest to the source simulator + gTeleportDisplayTimer.reset(); + const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"]; + LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL; + gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED); + gAgent.setTeleportMessage(msg); + if (!minimized) + { + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gViewerWindow->setProgressString(msg); + gViewerWindow->setProgressMessage(gAgent.mMOTD); + } + break; + } + + case LLAgent::TELEPORT_REQUESTED: + // Waiting for source simulator to respond + if (!minimized) + { + gViewerWindow->setProgressPercent(llmin(teleport_percent, 37.5f)); + gViewerWindow->setProgressString(message); + } + break; + + case LLAgent::TELEPORT_MOVING: + // Viewer has received destination location from source simulator + if (!minimized) + { + gViewerWindow->setProgressPercent(llmin(teleport_percent, 75.f)); + gViewerWindow->setProgressString(message); + } + break; + + case LLAgent::TELEPORT_START_ARRIVAL: + // Transition to ARRIVING. Viewer has received avatar update, etc., + // from destination simulator + gTeleportArrivalTimer.reset(); + LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL; + gAgent.setTeleportState(LLAgent::TELEPORT_ARRIVING); + gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["arriving"]); + gAgent.sheduleTeleportIM(); + gTextureList.mForceResetTextureStats = TRUE; + gAgentCamera.resetView(TRUE, TRUE); + if (!minimized) + { + gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); + gViewerWindow->setProgressPercent(75.f); + } + break; + + case LLAgent::TELEPORT_ARRIVING: + // Make the user wait while content "pre-caches" + { + F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay()); + if (arrival_fraction > 1.f) + { + arrival_fraction = 1.f; + //LLFirstUse::useTeleport(); + LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL; + gAgent.setTeleportState(LLAgent::TELEPORT_NONE); + } + if (!minimized) + { + gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); + gViewerWindow->setProgressPercent(arrival_fraction * 25.f + 75.f); + gViewerWindow->setProgressString(message); + } + break; + } + + case LLAgent::TELEPORT_LOCAL: + // Short delay when teleporting in the same sim (progress screen active but not shown - did not + // fall-through from TELEPORT_START) + { + if (gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay()) + { + //LLFirstUse::useTeleport(); + LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32() + << " exceeds teleport_local_delete " << teleport_local_delay + << "; setting state to TELEPORT_NONE" + << LL_ENDL; + gAgent.setTeleportState(LLAgent::TELEPORT_NONE); + } + break; + } + + case LLAgent::TELEPORT_NONE: + // No teleport in progress + gViewerWindow->setShowProgress(FALSE); + gTeleportDisplay = FALSE; + } } // Paint the display! @@ -390,521 +390,521 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Render"); LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering. - - if (gWindowResized) - { //skip render on frames where window has been resized - LL_DEBUGS("Window") << "Resizing window" << LL_ENDL; + + if (gWindowResized) + { //skip render on frames where window has been resized + LL_DEBUGS("Window") << "Resizing window" << LL_ENDL; LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Resize Window"); - gGL.flush(); - glClear(GL_COLOR_BUFFER_BIT); - gViewerWindow->getWindow()->swapBuffers(); - LLPipeline::refreshCachedSettings(); - gPipeline.resizeScreenTexture(); - gResizeScreenTexture = FALSE; - gWindowResized = FALSE; - return; - } + gGL.flush(); + glClear(GL_COLOR_BUFFER_BIT); + gViewerWindow->getWindow()->swapBuffers(); + LLPipeline::refreshCachedSettings(); + gPipeline.resizeScreenTexture(); + gResizeScreenTexture = FALSE; + gWindowResized = FALSE; + return; + } if (gResizeShadowTexture) - { //skip render on frames where window has been resized - gPipeline.resizeShadowTexture(); - gResizeShadowTexture = FALSE; - } - - gSnapshot = for_snapshot; - - if (LLPipeline::sRenderDeferred) - { //hack to make sky show up in deferred snapshots - for_snapshot = FALSE; - } - - LLGLSDefault gls_default; - LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); - - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); - - gPipeline.disableLights(); - - // Don't draw if the window is hidden or minimized. - // In fact, must explicitly check the minimized state before drawing. - // Attempting to draw into a minimized window causes a GL error. JC - if ( !gViewerWindow->getActive() - || !gViewerWindow->getWindow()->getVisible() - || gViewerWindow->getWindow()->getMinimized() - || gNonInteractive) - { - // Clean up memory the pools may have allocated - if (rebuild) - { - stop_glerror(); - gPipeline.rebuildPools(); - stop_glerror(); - } - - stop_glerror(); - gViewerWindow->returnEmptyPicks(); - stop_glerror(); - - // We still need to update the teleport progress (to get changes done - // in TP states, else the sim does not get the messages signaling the - // agent's arrival). This fixes BUG-230616. HB - if (gTeleportDisplay) - { - // true = minimized, do not show/update the TP screen. HB - update_tp_display(true); - } - return; - } - - gViewerWindow->checkSettings(); - - { + { //skip render on frames where window has been resized + gPipeline.resizeShadowTexture(); + gResizeShadowTexture = FALSE; + } + + gSnapshot = for_snapshot; + + if (LLPipeline::sRenderDeferred) + { //hack to make sky show up in deferred snapshots + for_snapshot = FALSE; + } + + LLGLSDefault gls_default; + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); + + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + + gPipeline.disableLights(); + + // Don't draw if the window is hidden or minimized. + // In fact, must explicitly check the minimized state before drawing. + // Attempting to draw into a minimized window causes a GL error. JC + if ( !gViewerWindow->getActive() + || !gViewerWindow->getWindow()->getVisible() + || gViewerWindow->getWindow()->getMinimized() + || gNonInteractive) + { + // Clean up memory the pools may have allocated + if (rebuild) + { + stop_glerror(); + gPipeline.rebuildPools(); + stop_glerror(); + } + + stop_glerror(); + gViewerWindow->returnEmptyPicks(); + stop_glerror(); + + // We still need to update the teleport progress (to get changes done + // in TP states, else the sim does not get the messages signaling the + // agent's arrival). This fixes BUG-230616. HB + if (gTeleportDisplay) + { + // true = minimized, do not show/update the TP screen. HB + update_tp_display(true); + } + return; + } + + gViewerWindow->checkSettings(); + + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Picking"); - gViewerWindow->performPick(); - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); - LLGLState::checkStates(); - - ////////////////////////////////////////////////////////// - // - // Logic for forcing window updates if we're in drone mode. - // - - // *TODO: Investigate running display() during gHeadlessClient. See if this early exit is needed DK 2011-02-18 - if (gHeadlessClient) - { + gViewerWindow->performPick(); + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); + LLGLState::checkStates(); + + ////////////////////////////////////////////////////////// + // + // Logic for forcing window updates if we're in drone mode. + // + + // *TODO: Investigate running display() during gHeadlessClient. See if this early exit is needed DK 2011-02-18 + if (gHeadlessClient) + { #if LL_WINDOWS - static F32 last_update_time = 0.f; - if ((gFrameTimeSeconds - last_update_time) > 1.f) - { - InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); - last_update_time = gFrameTimeSeconds; - } + static F32 last_update_time = 0.f; + if ((gFrameTimeSeconds - last_update_time) > 1.f) + { + InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); + last_update_time = gFrameTimeSeconds; + } #elif LL_DARWIN - // MBW -- Do something clever here. + // MBW -- Do something clever here. #endif - // Not actually rendering, don't bother. - return; - } - - - // - // Bail out if we're in the startup state and don't want to try to - // render the world. - // - if (LLStartUp::getStartupState() < STATE_PRECACHE) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:Startup"); - display_startup(); - return; - } - - - if (gShaderProfileFrame) - { - LLGLSLShader::initProfile(); - } - - //LLGLState::verify(FALSE); - - ///////////////////////////////////////////////// - // - // Update GL Texture statistics (used for discard logic?) - // - - LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); - stop_glerror(); - - LLImageGL::updateStats(gFrameTimeSeconds); - - LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); - LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode")); - - gPipeline.mBackfaceCull = TRUE; - gFrameCount++; - gRecentFrameCount++; - if (gFocusMgr.getAppHasFocus()) - { - gForegroundFrameCount++; - } - - ////////////////////////////////////////////////////////// - // - // Display start screen if we're teleporting, and skip render - // - - if (gTeleportDisplay) - { + // Not actually rendering, don't bother. + return; + } + + + // + // Bail out if we're in the startup state and don't want to try to + // render the world. + // + if (LLStartUp::getStartupState() < STATE_PRECACHE) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:Startup"); + display_startup(); + return; + } + + + if (gShaderProfileFrame) + { + LLGLSLShader::initProfile(); + } + + //LLGLState::verify(FALSE); + + ///////////////////////////////////////////////// + // + // Update GL Texture statistics (used for discard logic?) + // + + LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); + stop_glerror(); + + LLImageGL::updateStats(gFrameTimeSeconds); + + LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); + LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode")); + + gPipeline.mBackfaceCull = TRUE; + gFrameCount++; + gRecentFrameCount++; + if (gFocusMgr.getAppHasFocus()) + { + gForegroundFrameCount++; + } + + ////////////////////////////////////////////////////////// + // + // Display start screen if we're teleporting, and skip render + // + + if (gTeleportDisplay) + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Teleport Display"); - LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); - // Note: false = not minimized, do update the TP screen. HB - update_tp_display(false); - } + LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); + // Note: false = not minimized, do update the TP screen. HB + update_tp_display(false); + } else if(LLAppViewer::instance()->logoutRequestSent()) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:Logout"); - F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; - if (percent_done > 100.f) - { - percent_done = 100.f; - } - - if( LLApp::isExiting() ) - { - percent_done = 100.f; - } - - gViewerWindow->setProgressPercent( percent_done ); - gViewerWindow->setProgressMessage(std::string()); - } - else - if (gRestoreGL) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL"); - F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; - if( percent_done > 100.f ) - { - gViewerWindow->setShowProgress(FALSE); - gRestoreGL = FALSE; - } - else - { - - if( LLApp::isExiting() ) - { - percent_done = 100.f; - } - - gViewerWindow->setProgressPercent( percent_done ); - } - gViewerWindow->setProgressMessage(std::string()); - } - - ////////////////////////// - // - // Prepare for the next frame - // - - ///////////////////////////// - // - // Update the camera - // - // - - LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); + { + LLAppViewer::instance()->pingMainloopTimeout("Display:Logout"); + F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; + if (percent_done > 100.f) + { + percent_done = 100.f; + } + + if( LLApp::isExiting() ) + { + percent_done = 100.f; + } + + gViewerWindow->setProgressPercent( percent_done ); + gViewerWindow->setProgressMessage(std::string()); + } + else + if (gRestoreGL) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL"); + F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; + if( percent_done > 100.f ) + { + gViewerWindow->setShowProgress(FALSE); + gRestoreGL = FALSE; + } + else + { + + if( LLApp::isExiting() ) + { + percent_done = 100.f; + } + + gViewerWindow->setProgressPercent( percent_done ); + } + gViewerWindow->setProgressMessage(std::string()); + } + + ////////////////////////// + // + // Prepare for the next frame + // + + ///////////////////////////// + // + // Update the camera + // + // + + LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); if (LLViewerCamera::instanceExists()) { LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); } - ////////////////////////// - // - // clear the next buffer - // (must follow dynamic texture writing since that uses the frame buffer) - // - - if (gDisconnected) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); - render_ui(); - swap(); - } - - ////////////////////////// - // - // Set rendering options - // - // - LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup"); - stop_glerror(); - - /////////////////////////////////////// - // - // Slam lighting parameters back to our defaults. - // Note that these are not the same as GL defaults... - - stop_glerror(); - gGL.setAmbientLightColor(LLColor4::white); - stop_glerror(); - - ///////////////////////////////////// - // - // Render - // - // Actually push all of our triangles to the screen. - // - - // do render-to-texture stuff here - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); + ////////////////////////// + // + // clear the next buffer + // (must follow dynamic texture writing since that uses the frame buffer) + // + + if (gDisconnected) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); + render_ui(); + swap(); + } + + ////////////////////////// + // + // Set rendering options + // + // + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup"); + stop_glerror(); + + /////////////////////////////////////// + // + // Slam lighting parameters back to our defaults. + // Note that these are not the same as GL defaults... + + stop_glerror(); + gGL.setAmbientLightColor(LLColor4::white); + stop_glerror(); + + ///////////////////////////////////// + // + // Render + // + // Actually push all of our triangles to the screen. + // + + // do render-to-texture stuff here + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Dynamic Textures"); - if (LLViewerDynamicTexture::updateAllInstances()) - { - gGL.setColorMask(true, true); - glClear(GL_DEPTH_BUFFER_BIT); - } - } - - gViewerWindow->setup3DViewport(); - - gPipeline.resetFrameStats(); // Reset per-frame statistics. - - if (!gDisconnected) - { - // Render mirrors and associated hero probes before we render the rest of the scene. - // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. + if (LLViewerDynamicTexture::updateAllInstances()) + { + gGL.setColorMask(true, true); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + + gViewerWindow->setup3DViewport(); + + gPipeline.resetFrameStats(); // Reset per-frame statistics. + + if (!gDisconnected) + { + // Render mirrors and associated hero probes before we render the rest of the scene. + // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. if (gPipeline.RenderMirrors && !gSnapshot && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0)) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes"); gPipeline.mHeroProbeManager.update(); } - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); - LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { //don't draw hud objects in this frame - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } - - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) - { //don't draw hud particles in this frame - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); - } - - stop_glerror(); - display_update_camera(); - stop_glerror(); - - { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); + LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { //don't draw hud objects in this frame + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) + { //don't draw hud particles in this frame + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); + } + + stop_glerror(); + display_update_camera(); + stop_glerror(); + + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Env Update"); // update all the sky/atmospheric/water settings LLEnvironment::instance().update(LLViewerCamera::getInstance()); - } + } - // *TODO: merge these two methods - { + // *TODO: merge these two methods + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("HUD Update"); - LLHUDManager::getInstance()->updateEffects(); - LLHUDObject::updateAll(); - stop_glerror(); - } + LLHUDManager::getInstance()->updateEffects(); + LLHUDObject::updateAll(); + stop_glerror(); + } - { + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Geom"); - const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time - gPipeline.createObjects(max_geom_update_time); - gPipeline.processPartitionQ(); - gPipeline.updateGeom(max_geom_update_time); - stop_glerror(); - } - - gPipeline.updateGL(); - - stop_glerror(); - - LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); - - //Increment drawable frame counter - LLDrawable::incrementVisible(); - - LLSpatialGroup::sNoDelete = TRUE; - LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); - - S32 occlusion = LLPipeline::sUseOcclusion; - if (gDepthDirty) - { //depth buffer is invalid, don't overwrite occlusion state - LLPipeline::sUseOcclusion = llmin(occlusion, 1); - } - gDepthDirty = FALSE; - - LLGLState::checkStates(); - - static LLCullResult result; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater(); - gPipeline.updateCull(*LLViewerCamera::getInstance(), result); - stop_glerror(); - - LLGLState::checkStates(); - - LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2") - if (gResizeScreenTexture) - { - gPipeline.resizeScreenTexture(); + const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time + gPipeline.createObjects(max_geom_update_time); + gPipeline.processPartitionQ(); + gPipeline.updateGeom(max_geom_update_time); + stop_glerror(); + } + + gPipeline.updateGL(); + + stop_glerror(); + + LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); + + //Increment drawable frame counter + LLDrawable::incrementVisible(); + + LLSpatialGroup::sNoDelete = TRUE; + LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); + + S32 occlusion = LLPipeline::sUseOcclusion; + if (gDepthDirty) + { //depth buffer is invalid, don't overwrite occlusion state + LLPipeline::sUseOcclusion = llmin(occlusion, 1); + } + gDepthDirty = FALSE; + + LLGLState::checkStates(); + + static LLCullResult result; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater(); + gPipeline.updateCull(*LLViewerCamera::getInstance(), result); + stop_glerror(); + + LLGLState::checkStates(); + + LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2") + if (gResizeScreenTexture) + { + gPipeline.resizeScreenTexture(); gResizeScreenTexture = FALSE; - } + } - gGL.setColorMask(true, true); - glClearColor(0,0,0,0); + gGL.setColorMask(true, true); + glClearColor(0,0,0,0); - LLGLState::checkStates(); + LLGLState::checkStates(); - if (!for_snapshot) - { + if (!for_snapshot) + { if (gFrameCount > 1 && !for_snapshot) - { //for some reason, ATI 4800 series will error out if you + { //for some reason, ATI 4800 series will error out if you //try to generate a shadow before the first frame is through gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); + LLGLState::checkStates(); - glh::matrix4f proj = get_current_projection(); - glh::matrix4f mod = get_current_modelview(); - glViewport(0,0,512,512); + glh::matrix4f proj = get_current_projection(); + glh::matrix4f mod = get_current_modelview(); + glViewport(0,0,512,512); - LLVOAvatar::updateImpostors(); + LLVOAvatar::updateImpostors(); - set_current_projection(proj); - set_current_modelview(mod); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj.m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(mod.m); - gViewerWindow->setup3DViewport(); + set_current_projection(proj); + set_current_modelview(mod); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadMatrix(proj.m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(mod.m); + gViewerWindow->setup3DViewport(); - LLGLState::checkStates(); - } + LLGLState::checkStates(); + } glClear(GL_DEPTH_BUFFER_BIT); - } - - ////////////////////////////////////// - // - // Update images, using the image stats generated during object update/culling - // - // Can put objects onto the retextured list. - // - // Doing this here gives hardware occlusion queries extra time to complete - LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); - - { + } + + ////////////////////////////////////// + // + // Update images, using the image stats generated during object update/culling + // + // Can put objects onto the retextured list. + // + // Doing this here gives hardware occlusion queries extra time to complete + LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); + + { LL_PROFILE_ZONE_NAMED("Update Images"); - - { + + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Class"); - LLViewerTexture::updateClass(); - } + LLViewerTexture::updateClass(); + } - { + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Image Update Bump"); - gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. - } + gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. + } - { + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("List"); - F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time - max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame) - gTextureList.updateImages(max_image_decode_time); - } + F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time + max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame) + gTextureList.updateImages(max_image_decode_time); + } - { + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("GLTF Materials Cleanup"); - //remove dead gltf materials + //remove dead gltf materials gGLTFMaterialList.flushMaterials(); - } - } - - LLGLState::checkStates(); - - /////////////////////////////////// - // - // StateSort - // - // Responsible for taking visible objects, and adding them to the appropriate draw orders. - // In the case of alpha objects, z-sorts them first. - // Also creates special lists for outlines and selected face rendering. - // - LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 4") - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - gPipeline.stateSort(*LLViewerCamera::getInstance(), result); - stop_glerror(); - - if (rebuild) - { - ////////////////////////////////////// - // - // rebuildPools - // - // - gPipeline.rebuildPools(); - stop_glerror(); - } - } - - LLSceneMonitor::getInstance()->fetchQueryResult(); - - LLGLState::checkStates(); - - LLPipeline::sUseOcclusion = occlusion; - - { - LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); - LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT("update sky"); //LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY); - gSky.updateSky(); - } - - if(gUseWireframe) - { - glClearColor(0.5f, 0.5f, 0.5f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); - - //// render frontmost floater opaque for occlusion culling purposes - //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); - //// assumes frontmost floater with focus is opaque - //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) - //{ - // gGL.matrixMode(LLRender::MM_MODELVIEW); - // gGL.pushMatrix(); - // { - // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - // gGL.loadIdentity(); - - // LLRect floater_rect = frontmost_floaterp->calcScreenRect(); - // // deflate by one pixel so rounding errors don't occlude outside of floater extents - // floater_rect.stretch(-1); - // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(), - // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(), - // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(), - // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled()); - // floater_3d_rect.translate(-0.5f, -0.5f); - // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear()); - // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f); - // gGL.color4fv(LLColor4::white.mV); - // gGL.begin(LLVertexBuffer::QUADS); - // { - // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); - // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); - // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); - // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); - // } - // gGL.end(); - // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - // } - // gGL.popMatrix(); - //} - - LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; - - LLGLState::checkStates(); - - stop_glerror(); + } + } + + LLGLState::checkStates(); + + /////////////////////////////////// + // + // StateSort + // + // Responsible for taking visible objects, and adding them to the appropriate draw orders. + // In the case of alpha objects, z-sorts them first. + // Also creates special lists for outlines and selected face rendering. + // + LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 4") + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + gPipeline.stateSort(*LLViewerCamera::getInstance(), result); + stop_glerror(); + + if (rebuild) + { + ////////////////////////////////////// + // + // rebuildPools + // + // + gPipeline.rebuildPools(); + stop_glerror(); + } + } + + LLSceneMonitor::getInstance()->fetchQueryResult(); + + LLGLState::checkStates(); + + LLPipeline::sUseOcclusion = occlusion; + + { + LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); + LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT("update sky"); //LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY); + gSky.updateSky(); + } + + if(gUseWireframe) + { + glClearColor(0.5f, 0.5f, 0.5f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); + + //// render frontmost floater opaque for occlusion culling purposes + //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); + //// assumes frontmost floater with focus is opaque + //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) + //{ + // gGL.matrixMode(LLRender::MM_MODELVIEW); + // gGL.pushMatrix(); + // { + // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + // gGL.loadIdentity(); + + // LLRect floater_rect = frontmost_floaterp->calcScreenRect(); + // // deflate by one pixel so rounding errors don't occlude outside of floater extents + // floater_rect.stretch(-1); + // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(), + // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(), + // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(), + // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled()); + // floater_3d_rect.translate(-0.5f, -0.5f); + // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear()); + // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f); + // gGL.color4fv(LLColor4::white.mV); + // gGL.begin(LLVertexBuffer::QUADS); + // { + // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); + // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); + // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); + // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); + // } + // gGL.end(); + // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + // } + // gGL.popMatrix(); + //} + + LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; + + LLGLState::checkStates(); + + stop_glerror(); gGL.setColorMask(true, true); @@ -936,94 +936,94 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gGL.setColorMask(true, false); LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); - - if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) - && !gRestoreGL) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5") - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - if (gSavedSettings.getBOOL("RenderDepthPrePass")) - { - gGL.setColorMask(false, false); - - static const U32 types[] = { - LLRenderPass::PASS_SIMPLE, - LLRenderPass::PASS_FULLBRIGHT, - LLRenderPass::PASS_SHINY - }; - - U32 num_types = LL_ARRAY_SIZE(types); - gOcclusionProgram.bind(); - for (U32 i = 0; i < num_types; i++) - { - gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - - gOcclusionProgram.unbind(); - - } - - gGL.setColorMask(true, true); - gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true); - } - - { + + if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) + && !gRestoreGL) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5") + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + + if (gSavedSettings.getBOOL("RenderDepthPrePass")) + { + gGL.setColorMask(false, false); + + static const U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY + }; + + U32 num_types = LL_ARRAY_SIZE(types); + gOcclusionProgram.bind(); + for (U32 i = 0; i < num_types; i++) + { + gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + + gOcclusionProgram.unbind(); + + } + + gGL.setColorMask(true, true); + gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true); + } + + { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Texture Unbind"); - for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) - { //dummy cleanup of any currently bound textures - if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) - { - gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); - gGL.getTexUnit(i)->disable(); - } - } - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); + for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) + { //dummy cleanup of any currently bound textures + if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) + { + gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); + gGL.getTexUnit(i)->disable(); + } + } + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen); rt.flush(); if (LLPipeline::sRenderDeferred) { - gPipeline.renderDeferredLighting(); - } - - LLPipeline::sUnderWaterRender = FALSE; - - { - //capture the frame buffer. - LLSceneMonitor::getInstance()->capture(); - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); - if (!for_snapshot) - { - render_ui(); - swap(); - } - - - LLSpatialGroup::sNoDelete = FALSE; - gPipeline.clearReferences(); - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); - - stop_glerror(); - - display_stats(); - - LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); - - gShiftFrame = false; - - if (gShaderProfileFrame) - { - gShaderProfileFrame = FALSE; - LLGLSLShader::finishProfile(); - } + gPipeline.renderDeferredLighting(); + } + + LLPipeline::sUnderWaterRender = FALSE; + + { + //capture the frame buffer. + LLSceneMonitor::getInstance()->capture(); + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); + if (!for_snapshot) + { + render_ui(); + swap(); + } + + + LLSpatialGroup::sNoDelete = FALSE; + gPipeline.clearReferences(); + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); + + stop_glerror(); + + display_stats(); + + LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + + gShiftFrame = false; + + if (gShaderProfileFrame) + { + gShaderProfileFrame = FALSE; + LLGLSLShader::finishProfile(); + } } // WIP simplified copy of display() that does minimal work @@ -1070,7 +1070,7 @@ void display_cube_face() } LLSpatialGroup::sNoDelete = TRUE; - + S32 occlusion = LLPipeline::sUseOcclusion; LLPipeline::sUseOcclusion = 1; // occlusion data is from main camera point of view, don't read or write it during cube snapshots //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data @@ -1084,7 +1084,7 @@ void display_cube_face() glClearColor(0, 0, 0, 0); gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); - + glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT); { @@ -1102,7 +1102,7 @@ void display_cube_face() stop_glerror(); } } - + LLPipeline::sUseOcclusion = occlusion; LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); @@ -1121,13 +1121,13 @@ void display_cube_face() glClearColor(1, 0, 1, 1); } gPipeline.mRT->deferredScreen.clear(); - + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); gPipeline.mRT->deferredScreen.flush(); - + gPipeline.renderDeferredLighting(); LLPipeline::sUnderWaterRender = FALSE; @@ -1143,200 +1143,200 @@ void render_hud_attachments() { LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches) gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - - glh::matrix4f current_proj = get_current_projection(); - glh::matrix4f current_mod = get_current_modelview(); - - // clamp target zoom level to reasonable values - gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f); - // smoothly interpolate current zoom level - gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f)); - - if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices()) - { - LLPipeline::sRenderingHUDs = TRUE; - LLCamera hud_cam = *LLViewerCamera::getInstance(); - hud_cam.setOrigin(-1.f,0,0); - hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); - LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); - - bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles"); - - //only render hud objects - gPipeline.pushRenderTypeMask(); - - // turn off everything - gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); - // turn on HUD - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - // turn on HUD particles - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); - - // if particles are off, turn off hud-particles as well - if (!render_particles) - { - // turn back off HUD particles - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); - } - - bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); - if (has_ui) - { - gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); - } - - S32 use_occlusion = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 0; - - //cull, sort, and render hud objects - static LLCullResult result; - LLSpatialGroup::sNoDelete = TRUE; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - gPipeline.updateCull(hud_cam, result); + gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + + glh::matrix4f current_proj = get_current_projection(); + glh::matrix4f current_mod = get_current_modelview(); + + // clamp target zoom level to reasonable values + gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f); + // smoothly interpolate current zoom level + gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f)); + + if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices()) + { + LLPipeline::sRenderingHUDs = TRUE; + LLCamera hud_cam = *LLViewerCamera::getInstance(); + hud_cam.setOrigin(-1.f,0,0); + hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); + LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); + + bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles"); + + //only render hud objects + gPipeline.pushRenderTypeMask(); + + // turn off everything + gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); + // turn on HUD + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + // turn on HUD particles + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); + + // if particles are off, turn off hud-particles as well + if (!render_particles) + { + // turn back off HUD particles + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); + } + + bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); + if (has_ui) + { + gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + + S32 use_occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; + + //cull, sort, and render hud objects + static LLCullResult result; + LLSpatialGroup::sNoDelete = TRUE; + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + gPipeline.updateCull(hud_cam, result); // Toggle render types - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR_ALPHA_MASK); // Toggle render passes - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK); - - gPipeline.stateSort(hud_cam, result); - - gPipeline.renderGeomPostDeferred(hud_cam); - - LLSpatialGroup::sNoDelete = FALSE; - //gPipeline.clearReferences(); - - render_hud_elements(); - - //restore type mask - gPipeline.popRenderTypeMask(); - - if (has_ui) - { - gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); - } - LLPipeline::sUseOcclusion = use_occlusion; - LLPipeline::sRenderingHUDs = FALSE; - } - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - set_current_projection(current_proj); - set_current_modelview(current_mod); + + gPipeline.stateSort(hud_cam, result); + + gPipeline.renderGeomPostDeferred(hud_cam); + + LLSpatialGroup::sNoDelete = FALSE; + //gPipeline.clearReferences(); + + render_hud_elements(); + + //restore type mask + gPipeline.popRenderTypeMask(); + + if (has_ui) + { + gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + LLPipeline::sUseOcclusion = use_occlusion; + LLPipeline::sRenderingHUDs = FALSE; + } + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + + set_current_projection(current_proj); + set_current_modelview(current_mod); } LLRect get_whole_screen_region() { - LLRect whole_screen = gViewerWindow->getWorldViewRectScaled(); - - // apply camera zoom transform (for high res screenshots) - F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); - S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); - if (zoom_factor > 1.f) - { - S32 num_horizontal_tiles = llceil(zoom_factor); - S32 tile_width = ll_round((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor); - S32 tile_height = ll_round((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor); - int tile_y = sub_region / num_horizontal_tiles; - int tile_x = sub_region - (tile_y * num_horizontal_tiles); - - whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height); - } - return whole_screen; + LLRect whole_screen = gViewerWindow->getWorldViewRectScaled(); + + // apply camera zoom transform (for high res screenshots) + F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); + S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); + if (zoom_factor > 1.f) + { + S32 num_horizontal_tiles = llceil(zoom_factor); + S32 tile_width = ll_round((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor); + S32 tile_height = ll_round((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor); + int tile_y = sub_region / num_horizontal_tiles; + int tile_x = sub_region - (tile_y * num_horizontal_tiles); + + whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height); + } + return whole_screen; } bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::matrix4f &model) { - if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) - { - F32 zoom_level = gAgentCamera.mHUDCurZoom; - LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); - - F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); - proj.element(2,2) = -0.01f; - - F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); - - glh::matrix4f mat; - F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); - F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); - mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); - mat.set_translate( - glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), - clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), - 0.f)); - proj *= mat; - - glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION); - - mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); - mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); - - tmp_model *= mat; - model = tmp_model; - return TRUE; - } - else - { - return FALSE; - } + if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) + { + F32 zoom_level = gAgentCamera.mHUDCurZoom; + LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); + + F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); + proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); + proj.element(2,2) = -0.01f; + + F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); + + glh::matrix4f mat; + F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); + F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); + mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); + mat.set_translate( + glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), + clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), + 0.f)); + proj *= mat; + + glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION); + + mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); + mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); + + tmp_model *= mat; + model = tmp_model; + return TRUE; + } + else + { + return FALSE; + } } bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model) { - LLRect whole_screen = get_whole_screen_region(); - return get_hud_matrices(whole_screen, proj, model); + LLRect whole_screen = get_whole_screen_region(); + return get_hud_matrices(whole_screen, proj, model); } bool setup_hud_matrices() { - LLRect whole_screen = get_whole_screen_region(); - return setup_hud_matrices(whole_screen); + LLRect whole_screen = get_whole_screen_region(); + return setup_hud_matrices(whole_screen); } bool setup_hud_matrices(const LLRect& screen_region) { - glh::matrix4f proj, model; - bool result = get_hud_matrices(screen_region, proj, model); - if (!result) return result; - - // set up transform to keep HUD objects in front of camera - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj.m); - set_current_projection(proj); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(model.m); - set_current_modelview(model); - return TRUE; + glh::matrix4f proj, model; + bool result = get_hud_matrices(screen_region, proj, model); + if (!result) return result; + + // set up transform to keep HUD objects in front of camera + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadMatrix(proj.m); + set_current_projection(proj); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(model.m); + set_current_modelview(model); + return TRUE; } void render_ui(F32 zoom_factor, int subfield) @@ -1344,45 +1344,45 @@ void render_ui(F32 zoom_factor, int subfield) LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO) LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); LL_PROFILE_GPU_ZONE("ui"); - LLGLState::checkStates(); - - glh::matrix4f saved_view = get_current_modelview(); - - if (!gSnapshot) - { - gGL.pushMatrix(); - gGL.loadMatrix(gGLLastModelView); - set_current_modelview(copy_matrix(gGLLastModelView)); - } - - if(LLSceneMonitor::getInstance()->needsUpdate()) - { - gGL.pushMatrix(); - gViewerWindow->setup2DRender(); - LLSceneMonitor::getInstance()->compare(); - gViewerWindow->setup3DRender(); - gGL.popMatrix(); - } + LLGLState::checkStates(); + + glh::matrix4f saved_view = get_current_modelview(); + + if (!gSnapshot) + { + gGL.pushMatrix(); + gGL.loadMatrix(gGLLastModelView); + set_current_modelview(copy_matrix(gGLLastModelView)); + } + + if(LLSceneMonitor::getInstance()->needsUpdate()) + { + gGL.pushMatrix(); + gViewerWindow->setup2DRender(); + LLSceneMonitor::getInstance()->compare(); + gViewerWindow->setup3DRender(); + gGL.popMatrix(); + } // apply gamma correction and post effects gPipeline.renderFinalize(); - { + { LLGLState::checkStates(); LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD"); - render_hud_elements(); + render_hud_elements(); LLGLState::checkStates(); - render_hud_attachments(); + render_hud_attachments(); LLGLState::checkStates(); - LLGLSDefault gls_default; - LLGLSUIDefault gls_ui; - { - gPipeline.disableLights(); - } + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; + { + gPipeline.disableLights(); + } bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (render_ui) @@ -1410,13 +1410,13 @@ void render_ui(F32 zoom_factor, int subfield) gViewerWindow->setup2DRender(); gViewerWindow->updateDebugText(); gViewerWindow->drawDebugText(); - } + } - if (!gSnapshot) - { - set_current_modelview(saved_view); - gGL.popMatrix(); - } + if (!gSnapshot) + { + set_current_modelview(saved_view); + gGL.popMatrix(); + } } void swap() @@ -1424,112 +1424,112 @@ void swap() LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Swap"); LL_PROFILE_GPU_ZONE("swap"); - if (gDisplaySwapBuffers) - { - gViewerWindow->getWindow()->swapBuffers(); - } - gDisplaySwapBuffers = TRUE; + if (gDisplaySwapBuffers) + { + gViewerWindow->getWindow()->swapBuffers(); + } + gDisplaySwapBuffers = TRUE; } void renderCoordinateAxes() { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::LINES); - gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(2.0f, 0.0f, 0.0f); - gGL.vertex3f(3.0f, 0.0f, 0.0f); - gGL.vertex3f(5.0f, 0.0f, 0.0f); - gGL.vertex3f(6.0f, 0.0f, 0.0f); - gGL.vertex3f(8.0f, 0.0f, 0.0f); - // Make an X - gGL.vertex3f(11.0f, 1.0f, 1.0f); - gGL.vertex3f(11.0f, -1.0f, -1.0f); - gGL.vertex3f(11.0f, 1.0f, -1.0f); - gGL.vertex3f(11.0f, -1.0f, 1.0f); - - gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(0.0f, 2.0f, 0.0f); - gGL.vertex3f(0.0f, 3.0f, 0.0f); - gGL.vertex3f(0.0f, 5.0f, 0.0f); - gGL.vertex3f(0.0f, 6.0f, 0.0f); - gGL.vertex3f(0.0f, 8.0f, 0.0f); - // Make a Y - gGL.vertex3f(1.0f, 11.0f, 1.0f); - gGL.vertex3f(0.0f, 11.0f, 0.0f); - gGL.vertex3f(-1.0f, 11.0f, 1.0f); - gGL.vertex3f(0.0f, 11.0f, 0.0f); - gGL.vertex3f(0.0f, 11.0f, 0.0f); - gGL.vertex3f(0.0f, 11.0f, -1.0f); - - gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(0.0f, 0.0f, 2.0f); - gGL.vertex3f(0.0f, 0.0f, 3.0f); - gGL.vertex3f(0.0f, 0.0f, 5.0f); - gGL.vertex3f(0.0f, 0.0f, 6.0f); - gGL.vertex3f(0.0f, 0.0f, 8.0f); - // Make a Z - gGL.vertex3f(-1.0f, 1.0f, 11.0f); - gGL.vertex3f(1.0f, 1.0f, 11.0f); - gGL.vertex3f(1.0f, 1.0f, 11.0f); - gGL.vertex3f(-1.0f, -1.0f, 11.0f); - gGL.vertex3f(-1.0f, -1.0f, 11.0f); - gGL.vertex3f(1.0f, -1.0f, 11.0f); - gGL.end(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.begin(LLRender::LINES); + gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(2.0f, 0.0f, 0.0f); + gGL.vertex3f(3.0f, 0.0f, 0.0f); + gGL.vertex3f(5.0f, 0.0f, 0.0f); + gGL.vertex3f(6.0f, 0.0f, 0.0f); + gGL.vertex3f(8.0f, 0.0f, 0.0f); + // Make an X + gGL.vertex3f(11.0f, 1.0f, 1.0f); + gGL.vertex3f(11.0f, -1.0f, -1.0f); + gGL.vertex3f(11.0f, 1.0f, -1.0f); + gGL.vertex3f(11.0f, -1.0f, 1.0f); + + gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 2.0f, 0.0f); + gGL.vertex3f(0.0f, 3.0f, 0.0f); + gGL.vertex3f(0.0f, 5.0f, 0.0f); + gGL.vertex3f(0.0f, 6.0f, 0.0f); + gGL.vertex3f(0.0f, 8.0f, 0.0f); + // Make a Y + gGL.vertex3f(1.0f, 11.0f, 1.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(-1.0f, 11.0f, 1.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(0.0f, 11.0f, -1.0f); + + gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 2.0f); + gGL.vertex3f(0.0f, 0.0f, 3.0f); + gGL.vertex3f(0.0f, 0.0f, 5.0f); + gGL.vertex3f(0.0f, 0.0f, 6.0f); + gGL.vertex3f(0.0f, 0.0f, 8.0f); + // Make a Z + gGL.vertex3f(-1.0f, 1.0f, 11.0f); + gGL.vertex3f(1.0f, 1.0f, 11.0f); + gGL.vertex3f(1.0f, 1.0f, 11.0f); + gGL.vertex3f(-1.0f, -1.0f, 11.0f); + gGL.vertex3f(-1.0f, -1.0f, 11.0f); + gGL.vertex3f(1.0f, -1.0f, 11.0f); + gGL.end(); } -void draw_axes() +void draw_axes() { - LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // A vertical white line at origin - LLVector3 v = gAgent.getPositionAgent(); - gGL.begin(LLRender::LINES); - gGL.color3f(1.0f, 1.0f, 1.0f); - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(0.0f, 0.0f, 40.0f); - gGL.end(); - // Some coordinate axes - gGL.pushMatrix(); - gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); - renderCoordinateAxes(); - gGL.popMatrix(); + LLGLSUIDefault gls_ui; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + // A vertical white line at origin + LLVector3 v = gAgent.getPositionAgent(); + gGL.begin(LLRender::LINES); + gGL.color3f(1.0f, 1.0f, 1.0f); + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 40.0f); + gGL.end(); + // Some coordinate axes + gGL.pushMatrix(); + gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); + renderCoordinateAxes(); + gGL.popMatrix(); } void render_ui_3d() { - LLGLSPipeline gls_pipeline; - - ////////////////////////////////////// - // - // Render 3D UI elements - // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD, - // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD - // - - ///////////////////////////////////////////////////////////// - // - // Render 2.5D elements (2D elements in the world) - // Stuff without z writes - // - - // Debugging stuff goes before the UI. - - stop_glerror(); - - gUIProgram.bind(); + LLGLSPipeline gls_pipeline; + + ////////////////////////////////////// + // + // Render 3D UI elements + // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD, + // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD + // + + ///////////////////////////////////////////////////////////// + // + // Render 2.5D elements (2D elements in the world) + // Stuff without z writes + // + + // Debugging stuff goes before the UI. + + stop_glerror(); + + gUIProgram.bind(); gGL.color4f(1, 1, 1, 1); - // Coordinate axes - if (gSavedSettings.getBOOL("ShowAxes")) - { - draw_axes(); - } + // Coordinate axes + if (gSavedSettings.getBOOL("ShowAxes")) + { + draw_axes(); + } - gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements + gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { @@ -1539,205 +1539,205 @@ void render_ui_3d() gSky.addSunMoonBeacons(); } - stop_glerror(); + stop_glerror(); } void render_ui_2d() { - LLGLSUIDefault gls_ui; + LLGLSUIDefault gls_ui; - ///////////////////////////////////////////////////////////// - // - // Render 2D UI elements that overlay the world (no z compare) + ///////////////////////////////////////////////////////////// + // + // Render 2D UI elements that overlay the world (no z compare) - // Disable wireframe mode below here, as this is HUD/menus - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + // Disable wireframe mode below here, as this is HUD/menus + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // Menu overlays, HUD, etc - gViewerWindow->setup2DRender(); + // Menu overlays, HUD, etc + gViewerWindow->setup2DRender(); - F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); - S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); + F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); + S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); - if (zoom_factor > 1.f) - { - //decompose subregion number to x and y values - int pos_y = sub_region / llceil(zoom_factor); - int pos_x = sub_region - (pos_y*llceil(zoom_factor)); - // offset for this tile - LLFontGL::sCurOrigin.mX -= ll_round((F32)gViewerWindow->getWindowWidthScaled() * (F32)pos_x / zoom_factor); - LLFontGL::sCurOrigin.mY -= ll_round((F32)gViewerWindow->getWindowHeightScaled() * (F32)pos_y / zoom_factor); - } + if (zoom_factor > 1.f) + { + //decompose subregion number to x and y values + int pos_y = sub_region / llceil(zoom_factor); + int pos_x = sub_region - (pos_y*llceil(zoom_factor)); + // offset for this tile + LLFontGL::sCurOrigin.mX -= ll_round((F32)gViewerWindow->getWindowWidthScaled() * (F32)pos_x / zoom_factor); + LLFontGL::sCurOrigin.mY -= ll_round((F32)gViewerWindow->getWindowHeightScaled() * (F32)pos_y / zoom_factor); + } - stop_glerror(); + stop_glerror(); - // render outline for HUD - if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f) - { + // render outline for HUD + if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f) + { gUIProgram.bind(); - gGL.pushMatrix(); - S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); - S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); - gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f); - gGL.translatef((F32)half_width, (F32)half_height, 0.f); - F32 zoom = gAgentCamera.mHUDCurZoom; - gGL.scalef(zoom,zoom,1.f); - gGL.color4fv(LLColor4::white.mV); - gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); - gGL.popMatrix(); + gGL.pushMatrix(); + S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); + S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); + gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f); + gGL.translatef((F32)half_width, (F32)half_height, 0.f); + F32 zoom = gAgentCamera.mHUDCurZoom; + gGL.scalef(zoom,zoom,1.f); + gGL.color4fv(LLColor4::white.mV); + gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); + gGL.popMatrix(); gUIProgram.unbind(); - stop_glerror(); - } - - - if (gSavedSettings.getBOOL("RenderUIBuffer")) - { - if (LLView::sIsRectDirty) - { + stop_glerror(); + } + + + if (gSavedSettings.getBOOL("RenderUIBuffer")) + { + if (LLView::sIsRectDirty) + { LLView::sIsRectDirty = false; - LLRect t_rect; + LLRect t_rect; - gPipeline.mRT->uiScreen.bindTarget(); - gGL.setColorMask(true, true); - { - static const S32 pad = 8; + gPipeline.mRT->uiScreen.bindTarget(); + gGL.setColorMask(true, true); + { + static const S32 pad = 8; LLView::sDirtyRect.mLeft -= pad; LLView::sDirtyRect.mRight += pad; LLView::sDirtyRect.mBottom -= pad; LLView::sDirtyRect.mTop += pad; - LLGLEnable scissor(GL_SCISSOR_TEST); - static LLRect last_rect = LLView::sDirtyRect; + LLGLEnable scissor(GL_SCISSOR_TEST); + static LLRect last_rect = LLView::sDirtyRect; + + //union with last rect to avoid mouse poop + last_rect.unionWith(LLView::sDirtyRect); - //union with last rect to avoid mouse poop - last_rect.unionWith(LLView::sDirtyRect); - - t_rect = LLView::sDirtyRect; + t_rect = LLView::sDirtyRect; LLView::sDirtyRect = last_rect; - last_rect = t_rect; + last_rect = t_rect; + + last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]); + last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]); + last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]); + last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]); - last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]); - last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]); - last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]); - last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]); + LLRect clip_rect(last_rect); - LLRect clip_rect(last_rect); - - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); - gViewerWindow->draw(); - } + gViewerWindow->draw(); + } - gPipeline.mRT->uiScreen.flush(); - gGL.setColorMask(true, false); + gPipeline.mRT->uiScreen.flush(); + gGL.setColorMask(true, false); LLView::sDirtyRect = t_rect; - } - - LLGLDisable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - S32 width = gViewerWindow->getWindowWidthScaled(); - S32 height = gViewerWindow->getWindowHeightScaled(); - gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0); - gGL.texCoord2f(width, 0); gGL.vertex2i(width, 0); - gGL.texCoord2f(0, height); gGL.vertex2i(0, height); - gGL.texCoord2f(width, height); gGL.vertex2i(width, height); - gGL.end(); - } - else - { - gViewerWindow->draw(); - } - - - - // reset current origin for font rendering, in case of tiling render - LLFontGL::sCurOrigin.set(0, 0); + } + + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + S32 width = gViewerWindow->getWindowWidthScaled(); + S32 height = gViewerWindow->getWindowHeightScaled(); + gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.color4f(1,1,1,1); + gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0); + gGL.texCoord2f(width, 0); gGL.vertex2i(width, 0); + gGL.texCoord2f(0, height); gGL.vertex2i(0, height); + gGL.texCoord2f(width, height); gGL.vertex2i(width, height); + gGL.end(); + } + else + { + gViewerWindow->draw(); + } + + + + // reset current origin for font rendering, in case of tiling render + LLFontGL::sCurOrigin.set(0, 0); } void render_disconnected_background() { - gUIProgram.bind(); - - gGL.color4f(1,1,1,1); - if (!gDisconnectedImagep && gDisconnected) - { - LL_INFOS() << "Loading last bitmap..." << LL_ENDL; - - std::string temp_str; - temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getScreenLastFilename(); - - LLPointer image_png = new LLImagePNG; - if( !image_png->load(temp_str) ) - { - //LL_INFOS() << "Bitmap load failed" << LL_ENDL; - return; - } - - LLPointer raw = new LLImageRaw; - if (!image_png->decode(raw, 0.0f)) - { - LL_INFOS() << "Bitmap decode failed" << LL_ENDL; - gDisconnectedImagep = NULL; - return; - } - - U8 *rawp = raw->getData(); - S32 npixels = (S32)image_png->getWidth()*(S32)image_png->getHeight(); - for (S32 i = 0; i < npixels; i++) - { - S32 sum = 0; - sum = *rawp + *(rawp+1) + *(rawp+2); - sum /= 3; - *rawp = ((S32)sum*6 + *rawp)/7; - rawp++; - *rawp = ((S32)sum*6 + *rawp)/7; - rawp++; - *rawp = ((S32)sum*6 + *rawp)/7; - rawp++; - } - - - raw->expandToPowerOfTwo(); - gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE ); - gStartTexture = gDisconnectedImagep; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - - // Make sure the progress view always fills the entire window. - S32 width = gViewerWindow->getWindowWidthScaled(); - S32 height = gViewerWindow->getWindowHeightScaled(); - - if (gDisconnectedImagep) - { - LLGLSUIDefault gls_ui; - gViewerWindow->setup2DRender(); - gGL.pushMatrix(); - { - // scale ui to reflect UIScaleFactor - // this can't be done in setup2DRender because it requires a - // pushMatrix/popMatrix pair - const LLVector2& display_scale = gViewerWindow->getDisplayScale(); - gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); - - gGL.getTexUnit(0)->bind(gDisconnectedImagep); - gGL.color4f(1.f, 1.f, 1.f, 1.f); - gl_rect_2d_simple_tex(width, height); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - gGL.popMatrix(); - } - gGL.flush(); - - gUIProgram.unbind(); + gUIProgram.bind(); + + gGL.color4f(1,1,1,1); + if (!gDisconnectedImagep && gDisconnected) + { + LL_INFOS() << "Loading last bitmap..." << LL_ENDL; + + std::string temp_str; + temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getScreenLastFilename(); + + LLPointer image_png = new LLImagePNG; + if( !image_png->load(temp_str) ) + { + //LL_INFOS() << "Bitmap load failed" << LL_ENDL; + return; + } + + LLPointer raw = new LLImageRaw; + if (!image_png->decode(raw, 0.0f)) + { + LL_INFOS() << "Bitmap decode failed" << LL_ENDL; + gDisconnectedImagep = NULL; + return; + } + + U8 *rawp = raw->getData(); + S32 npixels = (S32)image_png->getWidth()*(S32)image_png->getHeight(); + for (S32 i = 0; i < npixels; i++) + { + S32 sum = 0; + sum = *rawp + *(rawp+1) + *(rawp+2); + sum /= 3; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + } + + + raw->expandToPowerOfTwo(); + gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE ); + gStartTexture = gDisconnectedImagep; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + + // Make sure the progress view always fills the entire window. + S32 width = gViewerWindow->getWindowWidthScaled(); + S32 height = gViewerWindow->getWindowHeightScaled(); + + if (gDisconnectedImagep) + { + LLGLSUIDefault gls_ui; + gViewerWindow->setup2DRender(); + gGL.pushMatrix(); + { + // scale ui to reflect UIScaleFactor + // this can't be done in setup2DRender because it requires a + // pushMatrix/popMatrix pair + const LLVector2& display_scale = gViewerWindow->getDisplayScale(); + gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); + + gGL.getTexUnit(0)->bind(gDisconnectedImagep); + gGL.color4f(1.f, 1.f, 1.f, 1.f); + gl_rect_2d_simple_tex(width, height); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + gGL.popMatrix(); + } + gGL.flush(); + + gUIProgram.unbind(); } void display_cleanup() { - gDisconnectedImagep = NULL; + gDisconnectedImagep = NULL; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c1a8c5df9e..8da467021d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewermenu.cpp * @brief Builds menus out of items. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2014, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,7 +30,7 @@ #include "vld.h" #endif -#include "llviewermenu.h" +#include "llviewermenu.h" // linden library includes #include "llavatarnamecache.h" // IDEVO (I Are Not Men!) @@ -115,7 +115,7 @@ #include "llviewerdisplay.h" //for gWindowResized #include "llviewergenericmessage.h" #include "llviewerhelp.h" -#include "llviewermenufile.h" // init_menu_file() +#include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" @@ -160,7 +160,7 @@ void handle_test_load_url(void*); // // Evil hackish imported globals -//extern BOOL gHideSelectedObjects; +//extern BOOL gHideSelectedObjects; //extern BOOL gAllowSelectAvatar; //extern BOOL gDebugAvatarRotation; extern BOOL gDebugClicks; @@ -174,20 +174,20 @@ extern BOOL gShaderProfileFrame; // Globals // -LLMenuBarGL *gMenuBarView = NULL; -LLViewerMenuHolderGL *gMenuHolder = NULL; -LLMenuGL *gPopupMenuView = NULL; -LLMenuGL *gEditMenu = NULL; -LLMenuBarGL *gLoginMenuBarView = NULL; +LLMenuBarGL *gMenuBarView = NULL; +LLViewerMenuHolderGL *gMenuHolder = NULL; +LLMenuGL *gPopupMenuView = NULL; +LLMenuGL *gEditMenu = NULL; +LLMenuBarGL *gLoginMenuBarView = NULL; // Pie menus -LLContextMenu *gMenuAvatarSelf = NULL; -LLContextMenu *gMenuAvatarOther = NULL; -LLContextMenu *gMenuObject = NULL; -LLContextMenu *gMenuAttachmentSelf = NULL; -LLContextMenu *gMenuAttachmentOther = NULL; -LLContextMenu *gMenuLand = NULL; -LLContextMenu *gMenuMuteParticle = NULL; +LLContextMenu *gMenuAvatarSelf = NULL; +LLContextMenu *gMenuAvatarOther = NULL; +LLContextMenu *gMenuObject = NULL; +LLContextMenu *gMenuAttachmentSelf = NULL; +LLContextMenu *gMenuAttachmentOther = NULL; +LLContextMenu *gMenuLand = NULL; +LLContextMenu *gMenuMuteParticle = NULL; const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"); @@ -285,7 +285,7 @@ void handle_force_parcel_owner_to_me(void*); void handle_force_parcel_to_content(void*); void handle_claim_public_land(void*); -void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry +void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry void reload_vertex_shader(void *); void handle_disconnect_viewer(void *); @@ -345,9 +345,9 @@ void menu_toggle_attached_particles(void* user_data); class LLMenuParcelObserver : public LLParcelObserver { public: - LLMenuParcelObserver(); - ~LLMenuParcelObserver(); - virtual void changed(); + LLMenuParcelObserver(); + ~LLMenuParcelObserver(); + virtual void changed(); }; static LLMenuParcelObserver* gMenuParcelObserver = NULL; @@ -356,17 +356,17 @@ static LLUIListener sUIListener; LLMenuParcelObserver::LLMenuParcelObserver() { - LLViewerParcelMgr::getInstance()->addObserver(this); + LLViewerParcelMgr::getInstance()->addObserver(this); } LLMenuParcelObserver::~LLMenuParcelObserver() { - LLViewerParcelMgr::getInstance()->removeObserver(this); + LLViewerParcelMgr::getInstance()->removeObserver(this); } void LLMenuParcelObserver::changed() { - LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); if (gMenuLand && parcel) { LLView* child = gMenuLand->findChild("Land Buy Pass"); @@ -439,129 +439,129 @@ void check_merchant_status(bool force) void init_menus() { - // Initialize actions - initialize_menus(); - - /// - /// Popup menu - /// - /// The popup menu is now populated by the show_context_menu() - /// method. - - LLMenuGL::Params menu_params; - menu_params.name = "Popup"; - menu_params.visible = false; - gPopupMenuView = LLUICtrlFactory::create(menu_params); - gMenuHolder->addChild( gPopupMenuView ); - - /// - /// Context menus - /// - - const widget_registry_t& registry = - LLViewerMenuHolderGL::child_registry_t::instance(); - gEditMenu = LLUICtrlFactory::createFromFile("menu_edit.xml", gMenuHolder, registry); - gMenuAvatarSelf = LLUICtrlFactory::createFromFile( - "menu_avatar_self.xml", gMenuHolder, registry); - gMenuAvatarOther = LLUICtrlFactory::createFromFile( - "menu_avatar_other.xml", gMenuHolder, registry); - - gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); - gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); - - gMenuObject = LLUICtrlFactory::createFromFile( - "menu_object.xml", gMenuHolder, registry); - - gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); - gAttachPieMenu = gMenuHolder->getChild("Object Attach"); - - gMenuAttachmentSelf = LLUICtrlFactory::createFromFile( - "menu_attachment_self.xml", gMenuHolder, registry); - gMenuAttachmentOther = LLUICtrlFactory::createFromFile( - "menu_attachment_other.xml", gMenuHolder, registry); - - gDetachHUDAttSelfMenu = gMenuHolder->getChild("Detach Self HUD", true); - gDetachAttSelfMenu = gMenuHolder->getChild("Detach Self", true); - - gMenuLand = LLUICtrlFactory::createFromFile( - "menu_land.xml", gMenuHolder, registry); - - gMenuMuteParticle = LLUICtrlFactory::createFromFile( - "menu_mute_particle.xml", gMenuHolder, registry); - - /// - /// set up the colors - /// - LLColor4 color; - - LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor"); - - gMenuAvatarSelf->setBackgroundColor( context_menu_color ); - gMenuAvatarOther->setBackgroundColor( context_menu_color ); - gMenuObject->setBackgroundColor( context_menu_color ); - gMenuAttachmentSelf->setBackgroundColor( context_menu_color ); - gMenuAttachmentOther->setBackgroundColor( context_menu_color ); - - gMenuLand->setBackgroundColor( context_menu_color ); - - color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" ); - gPopupMenuView->setBackgroundColor( color ); - - // If we are not in production, use a different color to make it apparent. - if (LLGridManager::getInstance()->isInProductionGrid()) - { - color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); - } - else - { - color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); - } - - LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder"); - - gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT)); - gMenuBarView->setBackgroundColor( color ); - - menu_bar_holder->addChild(gMenuBarView); - - gViewerWindow->setMenuBackgroundColor(false, + // Initialize actions + initialize_menus(); + + /// + /// Popup menu + /// + /// The popup menu is now populated by the show_context_menu() + /// method. + + LLMenuGL::Params menu_params; + menu_params.name = "Popup"; + menu_params.visible = false; + gPopupMenuView = LLUICtrlFactory::create(menu_params); + gMenuHolder->addChild( gPopupMenuView ); + + /// + /// Context menus + /// + + const widget_registry_t& registry = + LLViewerMenuHolderGL::child_registry_t::instance(); + gEditMenu = LLUICtrlFactory::createFromFile("menu_edit.xml", gMenuHolder, registry); + gMenuAvatarSelf = LLUICtrlFactory::createFromFile( + "menu_avatar_self.xml", gMenuHolder, registry); + gMenuAvatarOther = LLUICtrlFactory::createFromFile( + "menu_avatar_other.xml", gMenuHolder, registry); + + gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); + gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); + + gMenuObject = LLUICtrlFactory::createFromFile( + "menu_object.xml", gMenuHolder, registry); + + gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); + gAttachPieMenu = gMenuHolder->getChild("Object Attach"); + + gMenuAttachmentSelf = LLUICtrlFactory::createFromFile( + "menu_attachment_self.xml", gMenuHolder, registry); + gMenuAttachmentOther = LLUICtrlFactory::createFromFile( + "menu_attachment_other.xml", gMenuHolder, registry); + + gDetachHUDAttSelfMenu = gMenuHolder->getChild("Detach Self HUD", true); + gDetachAttSelfMenu = gMenuHolder->getChild("Detach Self", true); + + gMenuLand = LLUICtrlFactory::createFromFile( + "menu_land.xml", gMenuHolder, registry); + + gMenuMuteParticle = LLUICtrlFactory::createFromFile( + "menu_mute_particle.xml", gMenuHolder, registry); + + /// + /// set up the colors + /// + LLColor4 color; + + LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor"); + + gMenuAvatarSelf->setBackgroundColor( context_menu_color ); + gMenuAvatarOther->setBackgroundColor( context_menu_color ); + gMenuObject->setBackgroundColor( context_menu_color ); + gMenuAttachmentSelf->setBackgroundColor( context_menu_color ); + gMenuAttachmentOther->setBackgroundColor( context_menu_color ); + + gMenuLand->setBackgroundColor( context_menu_color ); + + color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" ); + gPopupMenuView->setBackgroundColor( color ); + + // If we are not in production, use a different color to make it apparent. + if (LLGridManager::getInstance()->isInProductionGrid()) + { + color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); + } + else + { + color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); + } + + LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder"); + + gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT)); + gMenuBarView->setBackgroundColor( color ); + + menu_bar_holder->addChild(gMenuBarView); + + gViewerWindow->setMenuBackgroundColor(false, LLGridManager::getInstance()->isInProductionGrid()); - // *TODO:Also fix cost in llfolderview.cpp for Inventory menus - const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); - const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); - gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str); - gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str); - - gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); - gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); - - gDetachAvatarMenu = gMenuHolder->getChild("Avatar Detach", true); - gDetachHUDAvatarMenu = gMenuHolder->getChild("Avatar Detach HUD", true); - - // Don't display the Memory console menu if the feature is turned off - LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild("Memory", TRUE); - if (memoryMenu) - { - memoryMenu->setVisible(FALSE); - } - - gMenuBarView->createJumpKeys(); - - // Let land based option enable when parcel changes - gMenuParcelObserver = new LLMenuParcelObserver(); - - gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gLoginMenuBarView->arrangeAndClear(); - LLRect menuBarRect = gLoginMenuBarView->getRect(); - menuBarRect.setLeftTopAndSize(0, menu_bar_holder->getRect().getHeight(), menuBarRect.getWidth(), menuBarRect.getHeight()); - gLoginMenuBarView->setRect(menuBarRect); - gLoginMenuBarView->setBackgroundColor( color ); - menu_bar_holder->addChild(gLoginMenuBarView); - - // tooltips are on top of EVERYTHING, including menus - gViewerWindow->getRootView()->sendChildToFront(gToolTipView); + // *TODO:Also fix cost in llfolderview.cpp for Inventory menus + const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); + const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); + gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str); + gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str); + + gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); + gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); + + gDetachAvatarMenu = gMenuHolder->getChild("Avatar Detach", true); + gDetachHUDAvatarMenu = gMenuHolder->getChild("Avatar Detach HUD", true); + + // Don't display the Memory console menu if the feature is turned off + LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild("Memory", TRUE); + if (memoryMenu) + { + memoryMenu->setVisible(FALSE); + } + + gMenuBarView->createJumpKeys(); + + // Let land based option enable when parcel changes + gMenuParcelObserver = new LLMenuParcelObserver(); + + gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + gLoginMenuBarView->arrangeAndClear(); + LLRect menuBarRect = gLoginMenuBarView->getRect(); + menuBarRect.setLeftTopAndSize(0, menu_bar_holder->getRect().getHeight(), menuBarRect.getWidth(), menuBarRect.getHeight()); + gLoginMenuBarView->setRect(menuBarRect); + gLoginMenuBarView->setBackgroundColor( color ); + menu_bar_holder->addChild(gLoginMenuBarView); + + // tooltips are on top of EVERYTHING, including menus + gViewerWindow->getRootView()->sendChildToFront(gToolTipView); } /////////////////// @@ -571,62 +571,62 @@ void init_menus() class LLAdvancedToggleConsole : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string console_type = userdata.asString(); - if ("texture" == console_type) - { - toggle_visibility( (void*)gTextureView ); - } - else if ("debug" == console_type) - { - toggle_visibility( (void*)static_cast(gDebugView->mDebugConsolep)); - } - else if ("fast timers" == console_type) - { - LLFloaterReg::toggleInstance("block_timers"); - } - else if ("scene view" == console_type) - { - toggle_visibility( (void*)gSceneView); - } - else if ("scene monitor" == console_type) - { - toggle_visibility( (void*)gSceneMonitorView); - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string console_type = userdata.asString(); + if ("texture" == console_type) + { + toggle_visibility( (void*)gTextureView ); + } + else if ("debug" == console_type) + { + toggle_visibility( (void*)static_cast(gDebugView->mDebugConsolep)); + } + else if ("fast timers" == console_type) + { + LLFloaterReg::toggleInstance("block_timers"); + } + else if ("scene view" == console_type) + { + toggle_visibility( (void*)gSceneView); + } + else if ("scene monitor" == console_type) + { + toggle_visibility( (void*)gSceneMonitorView); + } + + return true; + } }; class LLAdvancedCheckConsole : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string console_type = userdata.asString(); - bool new_value = false; - if ("texture" == console_type) - { - new_value = get_visibility( (void*)gTextureView ); - } - else if ("debug" == console_type) - { - new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) ); - } - else if ("fast timers" == console_type) - { - new_value = LLFloaterReg::instanceVisible("block_timers"); - } - else if ("scene view" == console_type) - { - new_value = get_visibility( (void*) gSceneView); - } - else if ("scene monitor" == console_type) - { - new_value = get_visibility( (void*) gSceneMonitorView); - } - - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + std::string console_type = userdata.asString(); + bool new_value = false; + if ("texture" == console_type) + { + new_value = get_visibility( (void*)gTextureView ); + } + else if ("debug" == console_type) + { + new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) ); + } + else if ("fast timers" == console_type) + { + new_value = LLFloaterReg::instanceVisible("block_timers"); + } + else if ("scene view" == console_type) + { + new_value = get_visibility( (void*) gSceneView); + } + else if ("scene monitor" == console_type) + { + new_value = get_visibility( (void*) gSceneMonitorView); + } + + return new_value; + } }; @@ -637,24 +637,24 @@ class LLAdvancedCheckConsole : public view_listener_t class LLAdvancedDumpInfoToConsole : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gDebugView->mDebugConsolep->setVisible(TRUE); - std::string info_type = userdata.asString(); - if ("region" == info_type) - { - handle_region_dump_settings(NULL); - } - else if ("group" == info_type) - { - handle_dump_group_info(NULL); - } - else if ("capabilities" == info_type) - { - handle_dump_capabilities_info(NULL); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + gDebugView->mDebugConsolep->setVisible(TRUE); + std::string info_type = userdata.asString(); + if ("region" == info_type) + { + handle_region_dump_settings(NULL); + } + else if ("group" == info_type) + { + handle_dump_group_info(NULL); + } + else if ("capabilities" == info_type) + { + handle_dump_capabilities_info(NULL); + } + return true; + } }; @@ -665,54 +665,54 @@ class LLAdvancedDumpInfoToConsole : public view_listener_t class LLAdvancedToggleHUDInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string info_type = userdata.asString(); - - if ("camera" == info_type) - { - gDisplayCameraPos = !(gDisplayCameraPos); - } - else if ("wind" == info_type) - { - gDisplayWindInfo = !(gDisplayWindInfo); - } - else if ("fov" == info_type) - { - gDisplayFOV = !(gDisplayFOV); - } - else if ("badge" == info_type) - { - gDisplayBadge = !(gDisplayBadge); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string info_type = userdata.asString(); + + if ("camera" == info_type) + { + gDisplayCameraPos = !(gDisplayCameraPos); + } + else if ("wind" == info_type) + { + gDisplayWindInfo = !(gDisplayWindInfo); + } + else if ("fov" == info_type) + { + gDisplayFOV = !(gDisplayFOV); + } + else if ("badge" == info_type) + { + gDisplayBadge = !(gDisplayBadge); + } + return true; + } }; class LLAdvancedCheckHUDInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string info_type = userdata.asString(); - bool new_value = false; - if ("camera" == info_type) - { - new_value = gDisplayCameraPos; - } - else if ("wind" == info_type) - { - new_value = gDisplayWindInfo; - } - else if ("fov" == info_type) - { - new_value = gDisplayFOV; - } - else if ("badge" == info_type) - { - new_value = gDisplayBadge; - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + std::string info_type = userdata.asString(); + bool new_value = false; + if ("camera" == info_type) + { + new_value = gDisplayCameraPos; + } + else if ("wind" == info_type) + { + new_value = gDisplayWindInfo; + } + else if ("fov" == info_type) + { + new_value = gDisplayFOV; + } + else if ("badge" == info_type) + { + new_value = gDisplayBadge; + } + return new_value; + } }; @@ -722,11 +722,11 @@ class LLAdvancedCheckHUDInfo : public view_listener_t class LLAdvancedClearGroupCache : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLGroupMgr::debugClearAllGroups(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLGroupMgr::debugClearAllGroups(NULL); + return true; + } }; @@ -737,18 +737,18 @@ class LLAdvancedClearGroupCache : public view_listener_t ///////////////// U32 render_type_from_string(std::string render_type) { - if ("simple" == render_type) - { - return LLPipeline::RENDER_TYPE_SIMPLE; - } + if ("simple" == render_type) + { + return LLPipeline::RENDER_TYPE_SIMPLE; + } if ("materials" == render_type) { return LLPipeline::RENDER_TYPE_MATERIALS; } - else if ("alpha" == render_type) - { - return LLPipeline::RENDER_TYPE_ALPHA; - } + else if ("alpha" == render_type) + { + return LLPipeline::RENDER_TYPE_ALPHA; + } else if ("alpha_mask" == render_type) { return LLPipeline::RENDER_TYPE_ALPHA_MASK; @@ -765,89 +765,89 @@ U32 render_type_from_string(std::string render_type) { return LLPipeline::RENDER_TYPE_GLOW; } - else if ("tree" == render_type) - { - return LLPipeline::RENDER_TYPE_TREE; - } - else if ("character" == render_type) - { - return LLPipeline::RENDER_TYPE_AVATAR; - } - else if ("controlAV" == render_type) // Animesh - { - return LLPipeline::RENDER_TYPE_CONTROL_AV; - } - else if ("surfacePatch" == render_type) - { - return LLPipeline::RENDER_TYPE_TERRAIN; - } - else if ("sky" == render_type) - { - return LLPipeline::RENDER_TYPE_SKY; - } - else if ("water" == render_type) - { - return LLPipeline::RENDER_TYPE_WATER; - } - else if ("volume" == render_type) - { - return LLPipeline::RENDER_TYPE_VOLUME; - } - else if ("grass" == render_type) - { - return LLPipeline::RENDER_TYPE_GRASS; - } - else if ("clouds" == render_type) - { - return LLPipeline::RENDER_TYPE_CLOUDS; - } - else if ("particles" == render_type) - { - return LLPipeline::RENDER_TYPE_PARTICLES; - } - else if ("bump" == render_type) - { - return LLPipeline::RENDER_TYPE_BUMP; - } - else if ("pbr" == render_type) + else if ("tree" == render_type) + { + return LLPipeline::RENDER_TYPE_TREE; + } + else if ("character" == render_type) + { + return LLPipeline::RENDER_TYPE_AVATAR; + } + else if ("controlAV" == render_type) // Animesh + { + return LLPipeline::RENDER_TYPE_CONTROL_AV; + } + else if ("surfacePatch" == render_type) + { + return LLPipeline::RENDER_TYPE_TERRAIN; + } + else if ("sky" == render_type) + { + return LLPipeline::RENDER_TYPE_SKY; + } + else if ("water" == render_type) + { + return LLPipeline::RENDER_TYPE_WATER; + } + else if ("volume" == render_type) + { + return LLPipeline::RENDER_TYPE_VOLUME; + } + else if ("grass" == render_type) + { + return LLPipeline::RENDER_TYPE_GRASS; + } + else if ("clouds" == render_type) + { + return LLPipeline::RENDER_TYPE_CLOUDS; + } + else if ("particles" == render_type) + { + return LLPipeline::RENDER_TYPE_PARTICLES; + } + else if ("bump" == render_type) + { + return LLPipeline::RENDER_TYPE_BUMP; + } + else if ("pbr" == render_type) { return LLPipeline::RENDER_TYPE_GLTF_PBR; } - else - { - return 0; - } + else + { + return 0; + } } class LLAdvancedToggleRenderType : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - U32 render_type = render_type_from_string( userdata.asString() ); - if ( render_type != 0 ) - { - LLPipeline::toggleRenderTypeControl( render_type ); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + U32 render_type = render_type_from_string( userdata.asString() ); + if ( render_type != 0 ) + { + LLPipeline::toggleRenderTypeControl( render_type ); + } + return true; + } }; class LLAdvancedCheckRenderType : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - U32 render_type = render_type_from_string( userdata.asString() ); - bool new_value = false; + bool handleEvent(const LLSD& userdata) + { + U32 render_type = render_type_from_string( userdata.asString() ); + bool new_value = false; - if ( render_type != 0 ) - { - new_value = LLPipeline::hasRenderTypeControl( render_type ); - } + if ( render_type != 0 ) + { + new_value = LLPipeline::hasRenderTypeControl( render_type ); + } - return new_value; - } + return new_value; + } }; @@ -855,140 +855,140 @@ class LLAdvancedCheckRenderType : public view_listener_t // FEATURE // ///////////// U32 feature_from_string(std::string feature) -{ - if ("ui" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_UI; - } - else if ("selected" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED; - } - else if ("highlighted" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED; - } - else if ("dynamic textures" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES; - } - else if ("foot shadows" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS; - } - else if ("fog" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_FOG; - } - else if ("fr info" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO; - } - else if ("flexible" == feature) - { - return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE; - } - else - { - return 0; - } +{ + if ("ui" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_UI; + } + else if ("selected" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED; + } + else if ("highlighted" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED; + } + else if ("dynamic textures" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES; + } + else if ("foot shadows" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS; + } + else if ("fog" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_FOG; + } + else if ("fr info" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO; + } + else if ("flexible" == feature) + { + return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE; + } + else + { + return 0; + } }; class LLAdvancedToggleFeature : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - U32 feature = feature_from_string( userdata.asString() ); - if ( feature != 0 ) - { - LLPipeline::toggleRenderDebugFeature( feature ); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + U32 feature = feature_from_string( userdata.asString() ); + if ( feature != 0 ) + { + LLPipeline::toggleRenderDebugFeature( feature ); + } + return true; + } }; class LLAdvancedCheckFeature : public view_listener_t { - bool handleEvent(const LLSD& userdata) + bool handleEvent(const LLSD& userdata) { - U32 feature = feature_from_string( userdata.asString() ); - bool new_value = false; + U32 feature = feature_from_string( userdata.asString() ); + bool new_value = false; - if ( feature != 0 ) - { - new_value = LLPipeline::toggleRenderDebugFeatureControl( feature ); - } + if ( feature != 0 ) + { + new_value = LLPipeline::toggleRenderDebugFeatureControl( feature ); + } - return new_value; + return new_value; } }; class LLAdvancedCheckDisplayTextureDensity : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string mode = userdata.asString(); - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) - { - return mode == "none"; - } - if (mode == "current") - { - return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT; - } - else if (mode == "desired") - { - return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED; - } - else if (mode == "full") - { - return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL; - } - return false; - } + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + return mode == "none"; + } + if (mode == "current") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL; + } + return false; + } }; class LLAdvancedSetDisplayTextureDensity : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string mode = userdata.asString(); - if (mode == "none") - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE) - { - gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); - } - LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; - } - else if (mode == "current") - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) - { - gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); - } - LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; - } - else if (mode == "desired") - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) - { - gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); - } - gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); - LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; - } - else if (mode == "full") - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) - { - gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); - } - LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (mode == "none") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE) + { + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; + } + else if (mode == "current") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; + } + return true; + } }; @@ -997,236 +997,236 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t ////////////////// U64 info_display_from_string(std::string info_display) { - if ("verify" == info_display) - { - return LLPipeline::RENDER_DEBUG_VERIFY; - } - else if ("bboxes" == info_display) - { - return LLPipeline::RENDER_DEBUG_BBOXES; - } - else if ("normals" == info_display) - { - return LLPipeline::RENDER_DEBUG_NORMALS; - } - else if ("points" == info_display) - { - return LLPipeline::RENDER_DEBUG_POINTS; - } - else if ("octree" == info_display) - { - return LLPipeline::RENDER_DEBUG_OCTREE; - } + if ("verify" == info_display) + { + return LLPipeline::RENDER_DEBUG_VERIFY; + } + else if ("bboxes" == info_display) + { + return LLPipeline::RENDER_DEBUG_BBOXES; + } + else if ("normals" == info_display) + { + return LLPipeline::RENDER_DEBUG_NORMALS; + } + else if ("points" == info_display) + { + return LLPipeline::RENDER_DEBUG_POINTS; + } + else if ("octree" == info_display) + { + return LLPipeline::RENDER_DEBUG_OCTREE; + } else if ("nodes" == info_display) { return LLPipeline::RENDER_DEBUG_NODES; } - else if ("shadow frusta" == info_display) - { - return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA; - } - else if ("physics shapes" == info_display) - { - return LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES; - } - else if ("occlusion" == info_display) - { - return LLPipeline::RENDER_DEBUG_OCCLUSION; - } - else if ("render batches" == info_display) - { - return LLPipeline::RENDER_DEBUG_BATCH_SIZE; - } - else if ("update type" == info_display) - { - return LLPipeline::RENDER_DEBUG_UPDATE_TYPE; - } - else if ("texture anim" == info_display) - { - return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM; - } - else if ("texture priority" == info_display) - { - return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY; - } - else if ("texture area" == info_display) - { - return LLPipeline::RENDER_DEBUG_TEXTURE_AREA; - } - else if ("face area" == info_display) - { - return LLPipeline::RENDER_DEBUG_FACE_AREA; - } - else if ("lod info" == info_display) - { - return LLPipeline::RENDER_DEBUG_LOD_INFO; - } - else if ("lights" == info_display) - { - return LLPipeline::RENDER_DEBUG_LIGHTS; - } - else if ("particles" == info_display) - { - return LLPipeline::RENDER_DEBUG_PARTICLES; - } - else if ("composition" == info_display) - { - return LLPipeline::RENDER_DEBUG_COMPOSITION; - } - else if ("avatardrawinfo" == info_display) - { - return (LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO); - } - else if ("glow" == info_display) - { - return LLPipeline::RENDER_DEBUG_GLOW; - } - else if ("collision skeleton" == info_display) - { - return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME; - } - else if ("joints" == info_display) - { - return LLPipeline::RENDER_DEBUG_AVATAR_JOINTS; - } - else if ("raycast" == info_display) - { - return LLPipeline::RENDER_DEBUG_RAYCAST; - } - else if ("agent target" == info_display) - { - return LLPipeline::RENDER_DEBUG_AGENT_TARGET; - } - else if ("sculpt" == info_display) - { - return LLPipeline::RENDER_DEBUG_SCULPTED; - } - else if ("wind vectors" == info_display) - { - return LLPipeline::RENDER_DEBUG_WIND_VECTORS; - } - else if ("texel density" == info_display) - { - return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; - } - else if ("triangle count" == info_display) - { - return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT; - } - else if ("impostors" == info_display) - { - return LLPipeline::RENDER_DEBUG_IMPOSTORS; - } - else if ("reflection probes" == info_display) + else if ("shadow frusta" == info_display) { - return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES; + return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA; } - else if ("probe updates" == info_display) + else if ("physics shapes" == info_display) { - return LLPipeline::RENDER_DEBUG_PROBE_UPDATES; + return LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES; } - else - { - LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL; - return 0; - } -}; - -class LLAdvancedToggleInfoDisplay : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - U64 info_display = info_display_from_string( userdata.asString() ); - - LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL; - - if ( info_display != 0 ) - { - LLPipeline::toggleRenderDebug( info_display ); - } - - return true; - } -}; - - -class LLAdvancedCheckInfoDisplay : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - U64 info_display = info_display_from_string( userdata.asString() ); - bool new_value = false; - - if ( info_display != 0 ) - { - new_value = LLPipeline::toggleRenderDebugControl( info_display ); - } - - return new_value; - } -}; - - -/////////////////////////// -//// RANDOMIZE FRAMERATE // -/////////////////////////// - - -class LLAdvancedToggleRandomizeFramerate : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - gRandomizeFramerate = !(gRandomizeFramerate); - return true; - } -}; - -class LLAdvancedCheckRandomizeFramerate : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gRandomizeFramerate; - return new_value; - } -}; - -/////////////////////////// -//// PERIODIC SLOW FRAME // -/////////////////////////// - - -class LLAdvancedTogglePeriodicSlowFrame : public view_listener_t + else if ("occlusion" == info_display) + { + return LLPipeline::RENDER_DEBUG_OCCLUSION; + } + else if ("render batches" == info_display) + { + return LLPipeline::RENDER_DEBUG_BATCH_SIZE; + } + else if ("update type" == info_display) + { + return LLPipeline::RENDER_DEBUG_UPDATE_TYPE; + } + else if ("texture anim" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM; + } + else if ("texture priority" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY; + } + else if ("texture area" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXTURE_AREA; + } + else if ("face area" == info_display) + { + return LLPipeline::RENDER_DEBUG_FACE_AREA; + } + else if ("lod info" == info_display) + { + return LLPipeline::RENDER_DEBUG_LOD_INFO; + } + else if ("lights" == info_display) + { + return LLPipeline::RENDER_DEBUG_LIGHTS; + } + else if ("particles" == info_display) + { + return LLPipeline::RENDER_DEBUG_PARTICLES; + } + else if ("composition" == info_display) + { + return LLPipeline::RENDER_DEBUG_COMPOSITION; + } + else if ("avatardrawinfo" == info_display) + { + return (LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO); + } + else if ("glow" == info_display) + { + return LLPipeline::RENDER_DEBUG_GLOW; + } + else if ("collision skeleton" == info_display) + { + return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME; + } + else if ("joints" == info_display) + { + return LLPipeline::RENDER_DEBUG_AVATAR_JOINTS; + } + else if ("raycast" == info_display) + { + return LLPipeline::RENDER_DEBUG_RAYCAST; + } + else if ("agent target" == info_display) + { + return LLPipeline::RENDER_DEBUG_AGENT_TARGET; + } + else if ("sculpt" == info_display) + { + return LLPipeline::RENDER_DEBUG_SCULPTED; + } + else if ("wind vectors" == info_display) + { + return LLPipeline::RENDER_DEBUG_WIND_VECTORS; + } + else if ("texel density" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; + } + else if ("triangle count" == info_display) + { + return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT; + } + else if ("impostors" == info_display) + { + return LLPipeline::RENDER_DEBUG_IMPOSTORS; + } + else if ("reflection probes" == info_display) + { + return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES; + } + else if ("probe updates" == info_display) + { + return LLPipeline::RENDER_DEBUG_PROBE_UPDATES; + } + else + { + LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL; + return 0; + } +}; + +class LLAdvancedToggleInfoDisplay : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + U64 info_display = info_display_from_string( userdata.asString() ); + + LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL; + + if ( info_display != 0 ) + { + LLPipeline::toggleRenderDebug( info_display ); + } + + return true; + } +}; + + +class LLAdvancedCheckInfoDisplay : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + U64 info_display = info_display_from_string( userdata.asString() ); + bool new_value = false; + + if ( info_display != 0 ) + { + new_value = LLPipeline::toggleRenderDebugControl( info_display ); + } + + return new_value; + } +}; + + +/////////////////////////// +//// RANDOMIZE FRAMERATE // +/////////////////////////// + + +class LLAdvancedToggleRandomizeFramerate : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + gRandomizeFramerate = !(gRandomizeFramerate); + return true; + } +}; + +class LLAdvancedCheckRandomizeFramerate : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool new_value = gRandomizeFramerate; + return new_value; + } +}; + +/////////////////////////// +//// PERIODIC SLOW FRAME // +/////////////////////////// + + +class LLAdvancedTogglePeriodicSlowFrame : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gPeriodicSlowFrame = !(gPeriodicSlowFrame); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gPeriodicSlowFrame = !(gPeriodicSlowFrame); + return true; + } }; class LLAdvancedCheckPeriodicSlowFrame : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gPeriodicSlowFrame; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gPeriodicSlowFrame; + return new_value; + } }; /////////////////////////// // SELECTED TEXTURE INFO // -// +// /////////////////////////// class LLAdvancedSelectedTextureInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_selected_texture_info(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_selected_texture_info(NULL); + return true; + } }; ////////////////////// @@ -1235,33 +1235,33 @@ class LLAdvancedSelectedTextureInfo : public view_listener_t class LLAdvancedToggleWireframe : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gUseWireframe = !(gUseWireframe); + bool handleEvent(const LLSD& userdata) + { + gUseWireframe = !(gUseWireframe); - return true; - } + return true; + } }; class LLAdvancedCheckWireframe : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gUseWireframe; - } + bool handleEvent(const LLSD& userdata) + { + return gUseWireframe; + } }; - + ////////////////////////// // DUMP SCRIPTED CAMERA // ////////////////////////// - + class LLAdvancedDumpScriptedCamera : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_dump_followcam(NULL); - return true; + bool handleEvent(const LLSD& userdata) + { + handle_dump_followcam(NULL); + return true; } }; @@ -1274,11 +1274,11 @@ class LLAdvancedDumpScriptedCamera : public view_listener_t class LLAdvancedDumpRegionObjectCache : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_dump_region_object_cache(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_dump_region_object_cache(NULL); + return true; + } }; class LLAdvancedToggleInterestList360Mode : public view_listener_t @@ -1289,22 +1289,22 @@ public: // Toggle the mode - regions will get updated if (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360) { - gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_DEFAULT); - } - else - { - gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360); - } + gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_DEFAULT); + } + else + { + gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360); + } return true; } }; class LLAdvancedCheckInterestList360Mode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360); - } + bool handleEvent(const LLSD& userdata) + { + return (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360); + } }; class LLAdvancedToggleStatsRecorder : public view_listener_t @@ -1312,13 +1312,13 @@ class LLAdvancedToggleStatsRecorder : public view_listener_t bool handleEvent(const LLSD &userdata) { if (LLViewerStatsRecorder::instance().isEnabled()) - { // Turn off both recording and logging - LLViewerStatsRecorder::instance().enableObjectStatsRecording(false); - } - else - { // Turn on both recording and logging - LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true); - } + { // Turn off both recording and logging + LLViewerStatsRecorder::instance().enableObjectStatsRecording(false); + } + else + { // Turn on both recording and logging + LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true); + } return true; } }; @@ -1326,7 +1326,7 @@ class LLAdvancedToggleStatsRecorder : public view_listener_t class LLAdvancedCheckStatsRecorder : public view_listener_t { bool handleEvent(const LLSD &userdata) - { // Use the logging state as the indicator of whether the stats recorder is on + { // Use the logging state as the indicator of whether the stats recorder is on return LLViewerStatsRecorder::instance().isLogging(); } }; @@ -1334,7 +1334,7 @@ class LLAdvancedCheckStatsRecorder : public view_listener_t class LLAdvancedResetInterestLists : public view_listener_t { bool handleEvent(const LLSD &userdata) - { // Reset all region interest lists + { // Reset all region interest lists handle_reset_interest_lists(NULL); return true; } @@ -1342,12 +1342,12 @@ class LLAdvancedResetInterestLists : public view_listener_t class LLAdvancedBuyCurrencyTest : public view_listener_t - { - bool handleEvent(const LLSD& userdata) - { - handle_buy_currency_test(NULL); - return true; - } + { + bool handleEvent(const LLSD& userdata) + { + handle_buy_currency_test(NULL); + return true; + } }; @@ -1358,11 +1358,11 @@ class LLAdvancedBuyCurrencyTest : public view_listener_t class LLAdvancedDumpSelectMgr : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - dump_select_mgr(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + dump_select_mgr(NULL); + return true; + } }; @@ -1374,11 +1374,11 @@ class LLAdvancedDumpSelectMgr : public view_listener_t class LLAdvancedDumpInventory : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - dump_inventory(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + dump_inventory(NULL); + return true; + } }; @@ -1390,11 +1390,11 @@ class LLAdvancedDumpInventory : public view_listener_t class LLAdvancedPrintSelectedObjectInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - print_object_info(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + print_object_info(NULL); + return true; + } }; @@ -1406,11 +1406,11 @@ class LLAdvancedPrintSelectedObjectInfo : public view_listener_t class LLAdvancedPrintAgentInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - print_agent_nvpairs(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + print_agent_nvpairs(NULL); + return true; + } }; ////////////////// @@ -1420,20 +1420,20 @@ class LLAdvancedPrintAgentInfo : public view_listener_t class LLAdvancedToggleDebugClicks : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gDebugClicks = !(gDebugClicks); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gDebugClicks = !(gDebugClicks); + return true; + } }; class LLAdvancedCheckDebugClicks : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gDebugClicks; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gDebugClicks; + return new_value; + } }; @@ -1445,20 +1445,20 @@ class LLAdvancedCheckDebugClicks : public view_listener_t class LLAdvancedToggleDebugViews : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLView::sDebugRects = !(LLView::sDebugRects); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugRects = !(LLView::sDebugRects); + return true; + } }; class LLAdvancedCheckDebugViews : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLView::sDebugRects; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLView::sDebugRects; + return new_value; + } }; @@ -1470,19 +1470,19 @@ class LLAdvancedCheckDebugViews : public view_listener_t class LLAdvancedToggleDebugUnicode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLView::sDebugUnicode = !(LLView::sDebugUnicode); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugUnicode = !(LLView::sDebugUnicode); + return true; + } }; class LLAdvancedCheckDebugUnicode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return LLView::sDebugUnicode; - } + bool handleEvent(const LLSD& userdata) + { + return LLView::sDebugUnicode; + } }; @@ -1494,20 +1494,20 @@ class LLAdvancedCheckDebugUnicode : public view_listener_t class LLAdvancedToggleDebugCamera : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLView::sDebugCamera = !(LLView::sDebugCamera); - LLFloaterCamera::onDebugCameraToggled(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugCamera = !(LLView::sDebugCamera); + LLFloaterCamera::onDebugCameraToggled(); + return true; + } }; class LLAdvancedCheckDebugCamera : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return LLView::sDebugCamera; - } + bool handleEvent(const LLSD& userdata) + { + return LLView::sDebugCamera; + } }; @@ -1519,20 +1519,20 @@ class LLAdvancedCheckDebugCamera : public view_listener_t class LLAdvancedToggleXUINameTooltips : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - toggle_show_xui_names(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + toggle_show_xui_names(NULL); + return true; + } }; class LLAdvancedCheckXUINameTooltips : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = check_show_xui_names(NULL); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = check_show_xui_names(NULL); + return new_value; + } }; @@ -1544,20 +1544,20 @@ class LLAdvancedCheckXUINameTooltips : public view_listener_t class LLAdvancedToggleDebugMouseEvents : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling); + return true; + } }; class LLAdvancedCheckDebugMouseEvents : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLView::sDebugMouseHandling; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLView::sDebugMouseHandling; + return new_value; + } }; @@ -1569,22 +1569,22 @@ class LLAdvancedCheckDebugMouseEvents : public view_listener_t class LLAdvancedToggleDebugKeys : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLView::sDebugKeys = !(LLView::sDebugKeys); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugKeys = !(LLView::sDebugKeys); + return true; + } }; - + class LLAdvancedCheckDebugKeys : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLView::sDebugKeys; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLView::sDebugKeys; + return new_value; + } }; - + /////////////////////// @@ -1594,30 +1594,30 @@ class LLAdvancedCheckDebugKeys : public view_listener_t class LLAdvancedToggleDebugWindowProc : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gDebugWindowProc = !(gDebugWindowProc); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gDebugWindowProc = !(gDebugWindowProc); + return true; + } }; class LLAdvancedCheckDebugWindowProc : public view_listener_t - { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gDebugWindowProc; - return new_value; - } + { + bool handleEvent(const LLSD& userdata) + { + bool new_value = gDebugWindowProc; + return new_value; + } }; // ------------------------------XUI MENU --------------------------- class LLAdvancedSendTestIms : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLIMModel::instance().testMessages(); - return true; + bool handleEvent(const LLSD& userdata) + { + LLIMModel::instance().testMessages(); + return true; } }; @@ -1629,20 +1629,20 @@ class LLAdvancedSendTestIms : public view_listener_t class LLAdvancedToggleXUINames : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - toggle_show_xui_names(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + toggle_show_xui_names(NULL); + return true; + } }; class LLAdvancedCheckXUINames : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = check_show_xui_names(NULL); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = check_show_xui_names(NULL); + return new_value; + } }; @@ -1653,73 +1653,73 @@ class LLAdvancedCheckXUINames : public view_listener_t class LLAdvancedGrabBakedTexture : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string texture_type = userdata.asString(); - if ("iris" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_EYES ); - } - else if ("head" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_HEAD ); - } - else if ("upper" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_UPPER ); - } - else if ("lower" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_LOWER ); - } - else if ("skirt" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_SKIRT ); - } - else if ("hair" == texture_type) - { - handle_grab_baked_texture( (void*)BAKED_HAIR ); - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string texture_type = userdata.asString(); + if ("iris" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_EYES ); + } + else if ("head" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_HEAD ); + } + else if ("upper" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_UPPER ); + } + else if ("lower" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_LOWER ); + } + else if ("skirt" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_SKIRT ); + } + else if ("hair" == texture_type) + { + handle_grab_baked_texture( (void*)BAKED_HAIR ); + } + + return true; + } }; class LLAdvancedEnableGrabBakedTexture : public view_listener_t { - bool handleEvent(const LLSD& userdata) -{ - std::string texture_type = userdata.asString(); - bool new_value = false; - - if ("iris" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_EYES ); - } - else if ("head" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_HEAD ); - } - else if ("upper" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_UPPER ); - } - else if ("lower" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_LOWER ); - } - else if ("skirt" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_SKIRT ); - } - else if ("hair" == texture_type) - { - new_value = enable_grab_baked_texture( (void*)BAKED_HAIR ); - } - - return new_value; -} -}; + bool handleEvent(const LLSD& userdata) +{ + std::string texture_type = userdata.asString(); + bool new_value = false; + + if ("iris" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_EYES ); + } + else if ("head" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_HEAD ); + } + else if ("upper" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_UPPER ); + } + else if ("lower" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_LOWER ); + } + else if ("skirt" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_SKIRT ); + } + else if ("hair" == texture_type) + { + new_value = enable_grab_baked_texture( (void*)BAKED_HAIR ); + } + + return new_value; +} +}; /////////////////////// // APPEARANCE TO XML // @@ -1728,8 +1728,8 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t class LLAdvancedEnableAppearanceToXML : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (obj && obj->isAnimatedObject() && obj->getControlAvatar()) { @@ -1744,18 +1744,18 @@ class LLAdvancedEnableAppearanceToXML : public view_listener_t // This has to be a non-control avatar, because control avs are invisible and unclickable. return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); } - else - { - return false; - } - } + else + { + return false; + } + } }; class LLAdvancedAppearanceToXML : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string emptyname; + bool handleEvent(const LLSD& userdata) + { + std::string emptyname; LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLVOAvatar *avatar = NULL; if (obj) @@ -1778,14 +1778,14 @@ class LLAdvancedAppearanceToXML : public view_listener_t else { // If no selection, use the self avatar. - avatar = gAgentAvatarp; + avatar = gAgentAvatarp; } if (avatar) { avatar->dumpArchetypeXML(emptyname); } - return true; - } + return true; + } }; @@ -1797,44 +1797,44 @@ class LLAdvancedAppearanceToXML : public view_listener_t class LLAdvancedToggleCharacterGeometry : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_god_request_avatar_geometry(NULL); - return true; + bool handleEvent(const LLSD& userdata) + { + handle_god_request_avatar_geometry(NULL); + return true; } }; - ///////////////////////////// + ///////////////////////////// // TEST MALE / TEST FEMALE // ///////////////////////////// class LLAdvancedTestMale : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_test_male(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_test_male(NULL); + return true; + } }; class LLAdvancedTestFemale : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_test_female(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_test_female(NULL); + return true; + } }; class LLAdvancedForceParamsToDefault : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLAgent::clearVisualParams(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLAgent::clearVisualParams(NULL); + return true; + } }; @@ -1843,47 +1843,47 @@ class LLAdvancedForceParamsToDefault : public view_listener_t ////////////////////////// // Utility function to set all AV time factors to the same global value -static void set_all_animation_time_factors(F32 time_factor) +static void set_all_animation_time_factors(F32 time_factor) { - LLMotionController::setCurrentTimeFactor(time_factor); - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - (*iter)->setAnimTimeFactor(time_factor); - } + LLMotionController::setCurrentTimeFactor(time_factor); + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + (*iter)->setAnimTimeFactor(time_factor); + } } class LLAdvancedAnimTenFaster : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - //LL_INFOS() << "LLAdvancedAnimTenFaster" << LL_ENDL; - F32 time_factor = LLMotionController::getCurrentTimeFactor(); - time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed - set_all_animation_time_factors(time_factor); - return true; - } + bool handleEvent(const LLSD& userdata) + { + //LL_INFOS() << "LLAdvancedAnimTenFaster" << LL_ENDL; + F32 time_factor = LLMotionController::getCurrentTimeFactor(); + time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed + set_all_animation_time_factors(time_factor); + return true; + } }; class LLAdvancedAnimTenSlower : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - //LL_INFOS() << "LLAdvancedAnimTenSlower" << LL_ENDL; - F32 time_factor = LLMotionController::getCurrentTimeFactor(); - time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed - set_all_animation_time_factors(time_factor); - return true; - } + bool handleEvent(const LLSD& userdata) + { + //LL_INFOS() << "LLAdvancedAnimTenSlower" << LL_ENDL; + F32 time_factor = LLMotionController::getCurrentTimeFactor(); + time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed + set_all_animation_time_factors(time_factor); + return true; + } }; class LLAdvancedAnimResetAll : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - set_all_animation_time_factors(1.f); - return true; - } + bool handleEvent(const LLSD& userdata) + { + set_all_animation_time_factors(1.f); + return true; + } }; @@ -1894,11 +1894,11 @@ class LLAdvancedAnimResetAll : public view_listener_t class LLAdvancedReloadVertexShader : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - reload_vertex_shader(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + reload_vertex_shader(NULL); + return true; + } }; @@ -1910,20 +1910,20 @@ class LLAdvancedReloadVertexShader : public view_listener_t class LLAdvancedToggleAnimationInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug); + return true; + } }; class LLAdvancedCheckAnimationInfo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLVOAvatar::sShowAnimationDebug; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLVOAvatar::sShowAnimationDebug; + return new_value; + } }; @@ -1934,20 +1934,20 @@ class LLAdvancedCheckAnimationInfo : public view_listener_t class LLAdvancedToggleShowLookAt : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt); + return true; + } }; class LLAdvancedCheckShowLookAt : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLHUDEffectLookAt::sDebugLookAt; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLHUDEffectLookAt::sDebugLookAt; + return new_value; + } }; @@ -1959,20 +1959,20 @@ class LLAdvancedCheckShowLookAt : public view_listener_t class LLAdvancedToggleShowPointAt : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt); + return true; + } }; class LLAdvancedCheckShowPointAt : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLHUDEffectPointAt::sDebugPointAt; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLHUDEffectPointAt::sDebugPointAt; + return new_value; + } }; @@ -1984,20 +1984,20 @@ class LLAdvancedCheckShowPointAt : public view_listener_t class LLAdvancedToggleDebugJointUpdates : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug); + return true; + } }; class LLAdvancedCheckDebugJointUpdates : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLVOAvatar::sJointDebug; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLVOAvatar::sJointDebug; + return new_value; + } }; @@ -2009,20 +2009,20 @@ class LLAdvancedCheckDebugJointUpdates : public view_listener_t class LLAdvancedToggleDisableLOD : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD); + return true; + } }; - + class LLAdvancedCheckDisableLOD : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLViewerJoint::sDisableLOD; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLViewerJoint::sDisableLOD; + return new_value; + } }; @@ -2034,20 +2034,20 @@ class LLAdvancedCheckDisableLOD : public view_listener_t class LLAdvancedToggleDebugCharacterVis : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible); + return true; + } }; class LLAdvancedCheckDebugCharacterVis : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLVOAvatar::sDebugInvisible; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLVOAvatar::sDebugInvisible; + return new_value; + } }; @@ -2055,33 +2055,33 @@ class LLAdvancedCheckDebugCharacterVis : public view_listener_t // DUMP ATTACHMENTS // ////////////////////// - + class LLAdvancedDumpAttachments : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_dump_attachments(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_dump_attachments(NULL); + return true; + } }; - + ///////////////////// // REBAKE TEXTURES // ///////////////////// - - + + class LLAdvancedRebakeTextures : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_rebake_textures(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_rebake_textures(NULL); + return true; + } }; - - + + #if 1 //ndef LL_RELEASE_FOR_DOWNLOAD /////////////////////////// // DEBUG AVATAR TEXTURES // @@ -2090,14 +2090,14 @@ class LLAdvancedRebakeTextures : public view_listener_t class LLAdvancedDebugAvatarTextures : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgent.isGodlike()) - { - handle_debug_avatar_textures(NULL); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgent.isGodlike()) + { + handle_debug_avatar_textures(NULL); + } + return true; + } }; //////////////////////////////// @@ -2107,17 +2107,17 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t class LLAdvancedDumpAvatarLocalTextures : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { #ifndef LL_RELEASE_FOR_DOWNLOAD - handle_dump_avatar_local_textures(NULL); + handle_dump_avatar_local_textures(NULL); #endif - return true; - } + return true; + } }; #endif - + ///////////////// // MESSAGE LOG // ///////////////// @@ -2125,20 +2125,20 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t class LLAdvancedEnableMessageLog : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_viewer_enable_message_log(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_viewer_enable_message_log(NULL); + return true; + } }; class LLAdvancedDisableMessageLog : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_viewer_disable_message_log(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_viewer_disable_message_log(NULL); + return true; + } }; ///////////////// @@ -2148,11 +2148,11 @@ class LLAdvancedDisableMessageLog : public view_listener_t class LLAdvancedDropPacket : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gMessageSystem->mPacketRing.dropPackets(1); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gMessageSystem->mPacketRing.dropPackets(1); + return true; + } }; ////////////////////// @@ -2162,8 +2162,8 @@ class LLAdvancedDropPacket : public view_listener_t class LLAdvancedPurgeDiskCache : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); llassert_always(main_queue); @@ -2177,8 +2177,8 @@ class LLAdvancedPurgeDiskCache : public view_listener_t }, [](){}); // Callback to main thread is empty as there is nothing left to do - return true; - } + return true; + } }; @@ -2189,12 +2189,12 @@ class LLAdvancedPurgeDiskCache : public view_listener_t class LLAdvancedPurgeShaderCache : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerShaderMgr::instance()->clearShaderCache(); - LLViewerShaderMgr::instance()->setShaders(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLViewerShaderMgr::instance()->clearShaderCache(); + LLViewerShaderMgr::instance()->setShaders(); + return true; + } }; ///////////////////// @@ -2204,11 +2204,11 @@ class LLAdvancedPurgeShaderCache : public view_listener_t class LLAdvancedRebuildTerrain : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { gPipeline.rebuildTerrain(); - return true; - } + return true; + } }; //////////////////// @@ -2218,32 +2218,32 @@ class LLAdvancedRebuildTerrain : public view_listener_t class LLAdvancedViewerEventRecorder : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string command = userdata.asString(); - if ("start playback" == command) - { - LL_INFOS() << "Event Playback starting" << LL_ENDL; - LLViewerEventRecorder::instance().playbackRecording(); - LL_INFOS() << "Event Playback completed" << LL_ENDL; - } - else if ("stop playback" == command) - { - // Future - } - else if ("start recording" == command) - { - LLViewerEventRecorder::instance().setEventLoggingOn(); - LL_INFOS() << "Event recording started" << LL_ENDL; - } - else if ("stop recording" == command) - { - LLViewerEventRecorder::instance().setEventLoggingOff(); - LL_INFOS() << "Event recording stopped" << LL_ENDL; - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string command = userdata.asString(); + if ("start playback" == command) + { + LL_INFOS() << "Event Playback starting" << LL_ENDL; + LLViewerEventRecorder::instance().playbackRecording(); + LL_INFOS() << "Event Playback completed" << LL_ENDL; + } + else if ("stop playback" == command) + { + // Future + } + else if ("start recording" == command) + { + LLViewerEventRecorder::instance().setEventLoggingOn(); + LL_INFOS() << "Event recording started" << LL_ENDL; + } + else if ("stop recording" == command) + { + LLViewerEventRecorder::instance().setEventLoggingOff(); + LL_INFOS() << "Event recording stopped" << LL_ENDL; + } + + return true; + } }; @@ -2256,29 +2256,29 @@ class LLAdvancedViewerEventRecorder : public view_listener_t class LLAdvancedAgentPilot : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string command = userdata.asString(); - if ("start playback" == command) - { - gAgentPilot.setNumRuns(-1); - gAgentPilot.startPlayback(); - } - else if ("stop playback" == command) - { - gAgentPilot.stopPlayback(); - } - else if ("start record" == command) - { - gAgentPilot.startRecord(); - } - else if ("stop record" == command) - { - gAgentPilot.stopRecord(); - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string command = userdata.asString(); + if ("start playback" == command) + { + gAgentPilot.setNumRuns(-1); + gAgentPilot.startPlayback(); + } + else if ("stop playback" == command) + { + gAgentPilot.stopPlayback(); + } + else if ("start record" == command) + { + gAgentPilot.startRecord(); + } + else if ("stop record" == command) + { + gAgentPilot.stopRecord(); + } + + return true; + } }; @@ -2290,20 +2290,20 @@ class LLAdvancedAgentPilot : public view_listener_t class LLAdvancedToggleAgentPilotLoop : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgentPilot.setLoop(!gAgentPilot.getLoop()); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gAgentPilot.setLoop(!gAgentPilot.getLoop()); + return true; + } }; class LLAdvancedCheckAgentPilotLoop : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gAgentPilot.getLoop(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gAgentPilot.getLoop(); + return new_value; + } }; @@ -2314,20 +2314,20 @@ class LLAdvancedCheckAgentPilotLoop : public view_listener_t class LLAdvancedToggleShowObjectUpdates : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gShowObjectUpdates = !(gShowObjectUpdates); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gShowObjectUpdates = !(gShowObjectUpdates); + return true; + } }; class LLAdvancedCheckShowObjectUpdates : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gShowObjectUpdates; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gShowObjectUpdates; + return new_value; + } }; @@ -2339,11 +2339,11 @@ class LLAdvancedCheckShowObjectUpdates : public view_listener_t class LLAdvancedCompressImage : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_compress_image(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_compress_image(NULL); + return true; + } }; @@ -2369,11 +2369,11 @@ class LLAdvancedCompressFileTest : public view_listener_t class LLAdvancedShowDebugSettings : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::showInstance("settings_debug",userdata); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloaterReg::showInstance("settings_debug",userdata); + return true; + } }; @@ -2384,40 +2384,40 @@ class LLAdvancedShowDebugSettings : public view_listener_t class LLAdvancedEnableViewAdminOptions : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // Don't enable in god mode since the admin menu is shown anyway. - // Only enable if the user has set the appropriate debug setting. - bool new_value = !gAgent.getAgentAccess().isGodlikeWithoutAdminMenuFakery() && gSavedSettings.getBOOL("AdminMenu"); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + // Don't enable in god mode since the admin menu is shown anyway. + // Only enable if the user has set the appropriate debug setting. + bool new_value = !gAgent.getAgentAccess().isGodlikeWithoutAdminMenuFakery() && gSavedSettings.getBOOL("AdminMenu"); + return new_value; + } }; class LLAdvancedToggleViewAdminOptions : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_admin_override_toggle(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_admin_override_toggle(NULL); + return true; + } }; class LLAdvancedToggleVisualLeakDetector : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_visual_leak_detector_toggle(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_visual_leak_detector_toggle(NULL); + return true; + } }; class LLAdvancedCheckViewAdminOptions : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = check_admin_override(NULL) || gAgent.isGodlike(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = check_admin_override(NULL) || gAgent.isGodlike(); + return new_value; + } }; ////////////////// @@ -2427,20 +2427,20 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t class LLAdvancedRequestAdminStatus : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_god_mode(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_god_mode(NULL); + return true; + } }; class LLAdvancedLeaveAdminStatus : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_leave_god_mode(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_leave_god_mode(NULL); + return true; + } }; ////////////////////////// @@ -2449,20 +2449,20 @@ class LLAdvancedLeaveAdminStatus : public view_listener_t class LLAdvancedForceErrorBreakpoint : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_breakpoint(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_breakpoint(NULL); + return true; + } }; class LLAdvancedForceErrorLlerror : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_llerror(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_llerror(NULL); + return true; + } }; class LLAdvancedForceErrorLlerrorMsg: public view_listener_t @@ -2476,11 +2476,11 @@ class LLAdvancedForceErrorLlerrorMsg: public view_listener_t class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_bad_memory_access(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_bad_memory_access(NULL); + return true; + } }; class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t @@ -2501,20 +2501,20 @@ class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t class LLAdvancedForceErrorInfiniteLoop : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_infinite_loop(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_infinite_loop(NULL); + return true; + } }; class LLAdvancedForceErrorSoftwareException : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_software_exception(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_software_exception(NULL); + return true; + } }; class LLAdvancedForceOSException: public view_listener_t @@ -2544,11 +2544,11 @@ class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t class LLAdvancedForceErrorDriverCrash : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_error_driver_crash(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_error_driver_crash(NULL); + return true; + } }; class LLAdvancedForceErrorCoroutineCrash : public view_listener_t @@ -2571,10 +2571,10 @@ class LLAdvancedForceErrorThreadCrash : public view_listener_t class LLAdvancedForceErrorDisconnectViewer : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_disconnect_viewer(NULL); - return true; + bool handleEvent(const LLSD& userdata) + { + handle_disconnect_viewer(NULL); + return true; } }; @@ -2583,29 +2583,29 @@ class LLAdvancedForceErrorDisconnectViewer : public view_listener_t class LLAdvancedHandleToggleHackedGodmode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_toggle_hacked_godmode(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_toggle_hacked_godmode(NULL); + return true; + } }; class LLAdvancedCheckToggleHackedGodmode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - check_toggle_hacked_godmode(NULL); - return true; - } -}; + bool handleEvent(const LLSD& userdata) + { + check_toggle_hacked_godmode(NULL); + return true; + } +}; class LLAdvancedEnableToggleHackedGodmode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = enable_toggle_hacked_godmode(NULL); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = enable_toggle_hacked_godmode(NULL); + return new_value; + } }; #endif @@ -2622,21 +2622,21 @@ class LLAdvancedEnableToggleHackedGodmode : public view_listener_t class LLDevelopCheckLoggingLevel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - U32 level = userdata.asInteger(); - return (static_cast(level) == LLError::getDefaultLevel()); - } + bool handleEvent(const LLSD& userdata) + { + U32 level = userdata.asInteger(); + return (static_cast(level) == LLError::getDefaultLevel()); + } }; class LLDevelopSetLoggingLevel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - U32 level = userdata.asInteger(); - LLError::setDefaultLevel(static_cast(level)); - return true; - } + bool handleEvent(const LLSD& userdata) + { + U32 level = userdata.asInteger(); + LLError::setDefaultLevel(static_cast(level)); + return true; + } }; ////////////////// @@ -2646,100 +2646,100 @@ class LLDevelopSetLoggingLevel : public view_listener_t // Admin > Object class LLAdminForceTakeCopy : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - force_take_copy(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + force_take_copy(NULL); + return true; + } }; class LLAdminHandleObjectOwnerSelf : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_object_owner_self(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_object_owner_self(NULL); + return true; + } }; class LLAdminHandleObjectOwnerPermissive : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_object_owner_permissive(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_object_owner_permissive(NULL); + return true; + } }; class LLAdminHandleForceDelete : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_force_delete(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_force_delete(NULL); + return true; + } }; class LLAdminHandleObjectLock : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_object_lock(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_object_lock(NULL); + return true; + } }; class LLAdminHandleObjectAssetIDs: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_object_asset_ids(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_object_asset_ids(NULL); + return true; + } }; //Admin >Parcel class LLAdminHandleForceParcelOwnerToMe: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_force_parcel_owner_to_me(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_force_parcel_owner_to_me(NULL); + return true; + } }; class LLAdminHandleForceParcelToContent: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_force_parcel_to_content(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_force_parcel_to_content(NULL); + return true; + } }; class LLAdminHandleClaimPublicLand: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_claim_public_land(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_claim_public_land(NULL); + return true; + } }; // Admin > Region class LLAdminHandleRegionDumpTempAssetData: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_region_dump_temp_asset_data(NULL); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_region_dump_temp_asset_data(NULL); + return true; + } }; //Admin (Top Level) class LLAdminOnSaveState: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLPanelRegionTools::onSaveState(NULL); - return true; + bool handleEvent(const LLSD& userdata) + { + LLPanelRegionTools::onSaveState(NULL); + return true; } }; @@ -2749,38 +2749,38 @@ class LLAdminOnSaveState: public view_listener_t //----------------------------------------------------------------------------- void cleanup_menus() { - delete gMenuParcelObserver; - gMenuParcelObserver = NULL; + delete gMenuParcelObserver; + gMenuParcelObserver = NULL; - delete gMenuAvatarSelf; - gMenuAvatarSelf = NULL; + delete gMenuAvatarSelf; + gMenuAvatarSelf = NULL; - delete gMenuAvatarOther; - gMenuAvatarOther = NULL; + delete gMenuAvatarOther; + gMenuAvatarOther = NULL; - delete gMenuObject; - gMenuObject = NULL; + delete gMenuObject; + gMenuObject = NULL; - delete gMenuAttachmentSelf; - gMenuAttachmentSelf = NULL; + delete gMenuAttachmentSelf; + gMenuAttachmentSelf = NULL; - delete gMenuAttachmentOther; - gMenuAttachmentSelf = NULL; + delete gMenuAttachmentOther; + gMenuAttachmentSelf = NULL; - delete gMenuLand; - gMenuLand = NULL; + delete gMenuLand; + gMenuLand = NULL; - delete gMenuMuteParticle; - gMenuMuteParticle = NULL; + delete gMenuMuteParticle; + gMenuMuteParticle = NULL; - delete gMenuBarView; - gMenuBarView = NULL; + delete gMenuBarView; + gMenuBarView = NULL; - delete gPopupMenuView; - gPopupMenuView = NULL; + delete gPopupMenuView; + gPopupMenuView = NULL; - delete gMenuHolder; - gMenuHolder = NULL; + delete gMenuHolder; + gMenuHolder = NULL; } //----------------------------------------------------------------------------- @@ -2789,40 +2789,40 @@ void cleanup_menus() class LLObjectReportAbuse : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (objectp) - { - LLFloaterReporter::showFromObject(objectp->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (objectp) + { + LLFloaterReporter::showFromObject(objectp->getID()); + } + return true; + } }; // Enabled it you clicked an object class LLObjectEnableReportAbuse : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0; + return new_value; + } }; void handle_object_touch() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return; + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return; - LLPickInfo pick = LLToolPie::getInstance()->getPick(); + LLPickInfo pick = LLToolPie::getInstance()->getPick(); - // *NOTE: Hope the packets arrive safely and in order or else - // there will be some problems. - // *TODO: Just fix this bad assumption. - send_ObjectGrab_message(object, pick, LLVector3::zero); - send_ObjectDeGrab_message(object, pick); + // *NOTE: Hope the packets arrive safely and in order or else + // there will be some problems. + // *TODO: Just fix this bad assumption. + send_ObjectGrab_message(object, pick, LLVector3::zero); + send_ObjectDeGrab_message(object, pick); } void handle_object_show_original() @@ -2855,75 +2855,75 @@ void handle_object_show_original() static void init_default_item_label(LLUICtrl* ctrl) { - const std::string& item_name = ctrl->getName(); - boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); - if (it == sDefaultItemLabels.end()) - { - // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value - // (doesn't seem to matter much ATM). - LLStringExplicit default_label = ctrl->getValue().asString(); - if (!default_label.empty()) - { - sDefaultItemLabels.insert(std::pair(item_name, default_label)); - } - } + const std::string& item_name = ctrl->getName(); + boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + if (it == sDefaultItemLabels.end()) + { + // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value + // (doesn't seem to matter much ATM). + LLStringExplicit default_label = ctrl->getValue().asString(); + if (!default_label.empty()) + { + sDefaultItemLabels.insert(std::pair(item_name, default_label)); + } + } } static LLStringExplicit get_default_item_label(const std::string& item_name) { - LLStringExplicit res(""); - boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); - if (it != sDefaultItemLabels.end()) - { - res = it->second; - } + LLStringExplicit res(""); + boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + if (it != sDefaultItemLabels.end()) + { + res = it->second; + } - return res; + return res; } bool enable_object_touch(LLUICtrl* ctrl) { - bool new_value = false; - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (obj) - { - LLViewerObject* parent = (LLViewerObject*)obj->getParent(); - new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch()); - } + bool new_value = false; + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (obj) + { + LLViewerObject* parent = (LLViewerObject*)obj->getParent(); + new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch()); + } - init_default_item_label(ctrl); + init_default_item_label(ctrl); - // Update label based on the node touch name if available. - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if (node && node->mValid && !node->mTouchName.empty()) - { - ctrl->setValue(node->mTouchName); - } - else - { - ctrl->setValue(get_default_item_label(ctrl->getName())); - } + // Update label based on the node touch name if available. + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (node && node->mValid && !node->mTouchName.empty()) + { + ctrl->setValue(node->mTouchName); + } + else + { + ctrl->setValue(get_default_item_label(ctrl->getName())); + } - return new_value; + return new_value; }; //void label_touch(std::string& label, void*) //{ -// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); -// if (node && node->mValid && !node->mTouchName.empty()) -// { -// label.assign(node->mTouchName); -// } -// else -// { -// label.assign("Touch"); -// } +// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); +// if (node && node->mValid && !node->mTouchName.empty()) +// { +// label.assign(node->mTouchName); +// } +// else +// { +// label.assign("Touch"); +// } //} void handle_object_open() { - LLFloaterReg::showInstance("openobject"); + LLFloaterReg::showInstance("openobject"); } bool enable_object_inspect() @@ -2978,67 +2978,67 @@ bool enable_object_edit_gltf_material() bool enable_object_open() { - // Look for contents in root object, which is all the LLFloaterOpenObject - // understands. - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!obj) return false; + // Look for contents in root object, which is all the LLFloaterOpenObject + // understands. + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!obj) return false; - LLViewerObject* root = obj->getRootEdit(); - if (!root) return false; + LLViewerObject* root = obj->getRootEdit(); + if (!root) return false; - return root->allowOpen(); + return root->allowOpen(); } class LLViewJoystickFlycam : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_toggle_flycam(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_toggle_flycam(); + return true; + } }; class LLViewCheckJoystickFlycam : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera(); + return new_value; + } }; void handle_toggle_flycam() { - LLViewerJoystick::getInstance()->toggleFlycam(); + LLViewerJoystick::getInstance()->toggleFlycam(); } class LLObjectBuild : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) - { - // zoom in if we're looking at the avatar - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gAgentCamera.cameraZoomIn(0.666f); - gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); - gViewerWindow->moveCursorToCenter(); - } - else if ( gSavedSettings.getBOOL("EditCameraMovement") ) - { - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gViewerWindow->moveCursorToCenter(); - } - - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); - - // Could be first use - //LLFirstUse::useBuild(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gAgentCamera.cameraZoomIn(0.666f); + gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gViewerWindow->moveCursorToCenter(); + } + + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); + + // Could be first use + //LLFirstUse::useBuild(); + return true; + } }; void update_camera() @@ -3077,17 +3077,17 @@ void handle_object_edit() { update_camera(); - LLFloaterReg::showInstance("build"); - - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); - - LLViewerJoystick::getInstance()->moveObjects(true); - LLViewerJoystick::getInstance()->setNeedsReset(true); - - // Could be first use - //LLFirstUse::useBuild(); - return; + LLFloaterReg::showInstance("build"); + + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + + LLViewerJoystick::getInstance()->moveObjects(true); + LLViewerJoystick::getInstance()->setNeedsReset(true); + + // Could be first use + //LLFirstUse::useBuild(); + return; } void handle_object_edit_gltf_material() @@ -3109,68 +3109,68 @@ void handle_object_edit_gltf_material() void handle_attachment_edit(const LLUUID& inv_item_id) { - if (isAgentAvatarValid()) - { - if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id)) - { - LLSelectMgr::getInstance()->deselectAll(); - LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj); + if (isAgentAvatarValid()) + { + if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id)) + { + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj); - handle_object_edit(); - } - } + handle_object_edit(); + } + } } void handle_attachment_touch(const LLUUID& inv_item_id) { - if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) ) - { - if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id))) - { - LLSelectMgr::getInstance()->deselectAll(); - - LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj); - if (!LLToolMgr::getInstance()->inBuildMode()) - { - struct SetTransient : public LLSelectedNodeFunctor - { - bool apply(LLSelectNode* node) - { - node->setTransient(TRUE); - return true; - } - } f; - sel->applyToNodes(&f); - } - - handle_object_touch(); - } - } + if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) ) + { + if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id))) + { + LLSelectMgr::getInstance()->deselectAll(); + + LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj); + if (!LLToolMgr::getInstance()->inBuildMode()) + { + struct SetTransient : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + node->setTransient(TRUE); + return true; + } + } f; + sel->applyToNodes(&f); + } + + handle_object_touch(); + } + } } bool enable_attachment_touch(const LLUUID& inv_item_id) { - if (isAgentAvatarValid()) - { - const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)); - return (attach_obj) && (attach_obj->flagHandleTouch()); - } - return false; + if (isAgentAvatarValid()) + { + const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)); + return (attach_obj) && (attach_obj->flagHandleTouch()); + } + return false; } void handle_object_inspect() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - LLViewerObject* selected_objectp = selection->getFirstRootObject(); - if (selected_objectp) - { + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* selected_objectp = selection->getFirstRootObject(); + if (selected_objectp) + { LLFloaterReg::showInstance("task_properties"); - } - - /* - // Old floater properties - LLFloaterReg::showInstance("inspect", LLSD()); - */ + } + + /* + // Old floater properties + LLFloaterReg::showInstance("inspect", LLSD()); + */ } //--------------------------------------------------------------------------- @@ -3178,133 +3178,133 @@ void handle_object_inspect() //--------------------------------------------------------------------------- class LLLandBuild : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerParcelMgr::getInstance()->deselectLand(); + bool handleEvent(const LLSD& userdata) + { + LLViewerParcelMgr::getInstance()->deselectLand(); - if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) - { - // zoom in if we're looking at the avatar - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gAgentCamera.cameraZoomIn(0.666f); - gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); - gViewerWindow->moveCursorToCenter(); - } - else if ( gSavedSettings.getBOOL("EditCameraMovement") ) - { - // otherwise just move focus - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gViewerWindow->moveCursorToCenter(); - } + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gAgentCamera.cameraZoomIn(0.666f); + gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + // otherwise just move focus + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gViewerWindow->moveCursorToCenter(); + } - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); - // Could be first use - //LLFirstUse::useBuild(); - return true; - } + // Could be first use + //LLFirstUse::useBuild(); + return true; + } }; class LLLandBuyPass : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLPanelLandGeneral::onClickBuyPass((void *)FALSE); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLPanelLandGeneral::onClickBuyPass((void *)FALSE); + return true; + } }; class LLLandEnableBuyPass : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLPanelLandGeneral::enableBuyPass(NULL); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLPanelLandGeneral::enableBuyPass(NULL); + return new_value; + } }; // BUG: Should really check if CLICK POINT is in a parcel where you can build. BOOL enable_land_build(void*) { - if (gAgent.isGodlike()) return TRUE; - if (gAgent.inPrelude()) return FALSE; + if (gAgent.isGodlike()) return TRUE; + if (gAgent.inPrelude()) return FALSE; - BOOL can_build = FALSE; - LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (agent_parcel) - { - can_build = agent_parcel->getAllowModify(); - } - return can_build; + BOOL can_build = FALSE; + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (agent_parcel) + { + can_build = agent_parcel->getAllowModify(); + } + return can_build; } // BUG: Should really check if OBJECT is in a parcel where you can build. BOOL enable_object_build(void*) { - if (gAgent.isGodlike()) return TRUE; - if (gAgent.inPrelude()) return FALSE; + if (gAgent.isGodlike()) return TRUE; + if (gAgent.inPrelude()) return FALSE; - BOOL can_build = FALSE; - LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (agent_parcel) - { - can_build = agent_parcel->getAllowModify(); - } - return can_build; + BOOL can_build = FALSE; + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (agent_parcel) + { + can_build = agent_parcel->getAllowModify(); + } + return can_build; } bool enable_object_edit() { - if (!isAgentAvatarValid()) return false; - - // *HACK: The new "prelude" Help Islands have a build sandbox area, - // so users need the Edit and Create pie menu options when they are - // there. Eventually this needs to be replaced with code that only - // lets you edit objects if you have permission to do so (edit perms, - // group edit, god). See also lltoolbar.cpp. JC - bool enable = false; - if (gAgent.inPrelude()) - { - enable = LLViewerParcelMgr::getInstance()->allowAgentBuild() - || LLSelectMgr::getInstance()->getSelection()->isAttachment(); - } - else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) - { - enable = true; - } - - return enable; + if (!isAgentAvatarValid()) return false; + + // *HACK: The new "prelude" Help Islands have a build sandbox area, + // so users need the Edit and Create pie menu options when they are + // there. Eventually this needs to be replaced with code that only + // lets you edit objects if you have permission to do so (edit perms, + // group edit, god). See also lltoolbar.cpp. JC + bool enable = false; + if (gAgent.inPrelude()) + { + enable = LLViewerParcelMgr::getInstance()->allowAgentBuild() + || LLSelectMgr::getInstance()->getSelection()->isAttachment(); + } + else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) + { + enable = true; + } + + return enable; } bool enable_mute_particle() { - const LLPickInfo& pick = LLToolPie::getInstance()->getPick(); + const LLPickInfo& pick = LLToolPie::getInstance()->getPick(); - return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID(); + return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID(); } // mutually exclusive - show either edit option or build in menu bool enable_object_build() { - return !enable_object_edit(); + return !enable_object_edit(); } bool enable_object_select_in_pathfinding_linksets() { - return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets(); + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets(); } bool visible_object_select_in_pathfinding_linksets() { - return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion(); + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion(); } bool enable_object_select_in_pathfinding_characters() { - return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters(); + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters(); } bool enable_os_exception() @@ -3318,40 +3318,40 @@ bool enable_os_exception() class LLSelfRemoveAllAttachments : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar(); + return true; + } }; class LLSelfEnableRemoveAllAttachments : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = false; - if (isAgentAvatarValid()) - { - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getNumObjects() > 0) - { - new_value = true; - break; - } - } - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = false; + if (isAgentAvatarValid()) + { + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getNumObjects() > 0) + { + new_value = true; + break; + } + } + } + return new_value; + } }; BOOL enable_has_attachments(void*) { - return FALSE; + return FALSE; } //--------------------------------------------------------------------------- @@ -3359,229 +3359,229 @@ BOOL enable_has_attachments(void*) //--------------------------------------------------------------------------- //void handle_follow(void *userdata) //{ -// // follow a given avatar by ID -// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -// if (objectp) -// { -// gAgent.startFollowPilot(objectp->getID()); -// } +// // follow a given avatar by ID +// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); +// if (objectp) +// { +// gAgent.startFollowPilot(objectp->getID()); +// } //} bool enable_object_mute() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return false; - - LLVOAvatar* avatar = find_avatar_from_object(object); - if (avatar) - { - // It's an avatar - LLNameValue *lastname = avatar->getNVPair("LastName"); - bool is_linden = - lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); - bool is_self = avatar->isSelf(); - return !is_linden && !is_self; - } - else - { - // Just a regular object - return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && - !LLMuteList::getInstance()->isMuted(object->getID()); - } + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + // It's an avatar + LLNameValue *lastname = avatar->getNVPair("LastName"); + bool is_linden = + lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); + bool is_self = avatar->isSelf(); + return !is_linden && !is_self; + } + else + { + // Just a regular object + return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && + !LLMuteList::getInstance()->isMuted(object->getID()); + } } bool enable_object_unmute() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return false; + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; - LLVOAvatar* avatar = find_avatar_from_object(object); - if (avatar) - { - // It's an avatar - LLNameValue *lastname = avatar->getNVPair("LastName"); - bool is_linden = - lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); - bool is_self = avatar->isSelf(); - return !is_linden && !is_self; - } - else - { - // Just a regular object - return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && - LLMuteList::getInstance()->isMuted(object->getID());; - } + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + // It's an avatar + LLNameValue *lastname = avatar->getNVPair("LastName"); + bool is_linden = + lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); + bool is_self = avatar->isSelf(); + return !is_linden && !is_self; + } + else + { + // Just a regular object + return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && + LLMuteList::getInstance()->isMuted(object->getID());; + } } // 0 = normal, 1 = always, 2 = never class LLAvatarCheckImpostorMode : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return false; - - LLVOAvatar* avatar = find_avatar_from_object(object); - if (!avatar) return false; - - U32 mode = userdata.asInteger(); - switch (mode) - { - case 0: - return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY); - case 1: - return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER); - case 2: - return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER); +{ + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (!avatar) return false; + + U32 mode = userdata.asInteger(); + switch (mode) + { + case 0: + return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY); + case 1: + return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER); + case 2: + return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER); case 4: return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY); - default: - return false; - } - } // handleEvent() + default: + return false; + } + } // handleEvent() }; // 0 = normal, 1 = always, 2 = never class LLAvatarSetImpostorMode : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return false; - - LLVOAvatar* avatar = find_avatar_from_object(object); - if (!avatar) return false; - - U32 mode = userdata.asInteger(); - switch (mode) - { - case 0: - avatar->setVisualMuteSettings(LLVOAvatar::AV_RENDER_NORMALLY); - break; - case 1: - avatar->setVisualMuteSettings(LLVOAvatar::AV_DO_NOT_RENDER); - break; - case 2: - avatar->setVisualMuteSettings(LLVOAvatar::AV_ALWAYS_RENDER); - break; - default: - return false; - } - - LLVOAvatar::cullAvatarsByPixelArea(); - return true; - } // handleEvent() + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (!avatar) return false; + + U32 mode = userdata.asInteger(); + switch (mode) + { + case 0: + avatar->setVisualMuteSettings(LLVOAvatar::AV_RENDER_NORMALLY); + break; + case 1: + avatar->setVisualMuteSettings(LLVOAvatar::AV_DO_NOT_RENDER); + break; + case 2: + avatar->setVisualMuteSettings(LLVOAvatar::AV_ALWAYS_RENDER); + break; + default: + return false; + } + + LLVOAvatar::cullAvatarsByPixelArea(); + return true; + } // handleEvent() }; class LLObjectMute : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return true; - - LLUUID id; - std::string name; - LLMute::EType type; - LLVOAvatar* avatar = find_avatar_from_object(object); - if (avatar) - { - avatar->mNeedsImpostorUpdate = TRUE; - avatar->mLastImpostorUpdateReason = 9; - - id = avatar->getID(); - - LLNameValue *firstname = avatar->getNVPair("FirstName"); - LLNameValue *lastname = avatar->getNVPair("LastName"); - if (firstname && lastname) - { - name = LLCacheName::buildFullName( - firstname->getString(), lastname->getString()); - } - - type = LLMute::AGENT; - } - else - { - // it's an object - id = object->getID(); - - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if (node) - { - name = node->mName; - } - - type = LLMute::OBJECT; - } - - LLMute mute(id, name, type); - if (LLMuteList::getInstance()->isMuted(mute.mID)) - { - LLMuteList::getInstance()->remove(mute); - } - else - { - LLMuteList::getInstance()->add(mute); - LLPanelBlockedList::showPanelAndSelect(mute.mID); - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return true; + + LLUUID id; + std::string name; + LLMute::EType type; + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + avatar->mNeedsImpostorUpdate = TRUE; + avatar->mLastImpostorUpdateReason = 9; + + id = avatar->getID(); + + LLNameValue *firstname = avatar->getNVPair("FirstName"); + LLNameValue *lastname = avatar->getNVPair("LastName"); + if (firstname && lastname) + { + name = LLCacheName::buildFullName( + firstname->getString(), lastname->getString()); + } + + type = LLMute::AGENT; + } + else + { + // it's an object + id = object->getID(); + + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (node) + { + name = node->mName; + } + + type = LLMute::OBJECT; + } + + LLMute mute(id, name, type); + if (LLMuteList::getInstance()->isMuted(mute.mID)) + { + LLMuteList::getInstance()->remove(mute); + } + else + { + LLMuteList::getInstance()->add(mute); + LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + + return true; + } }; bool handle_go_to() { - // try simulator autopilot - std::vector strings; - std::string val; - LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; - val = llformat("%g", pos.mdV[VX]); - strings.push_back(val); - val = llformat("%g", pos.mdV[VY]); - strings.push_back(val); - val = llformat("%g", pos.mdV[VZ]); - strings.push_back(val); - send_generic_message("autopilot", strings); - - LLViewerParcelMgr::getInstance()->deselectLand(); - - if (isAgentAvatarValid() && !gSavedSettings.getBOOL("AutoPilotLocksCamera")) - { - gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgentAvatarp->getID()); - } - else - { - // Snap camera back to behind avatar - gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); - } - - // Could be first use - //LLFirstUse::useGoTo(); - return true; + // try simulator autopilot + std::vector strings; + std::string val; + LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; + val = llformat("%g", pos.mdV[VX]); + strings.push_back(val); + val = llformat("%g", pos.mdV[VY]); + strings.push_back(val); + val = llformat("%g", pos.mdV[VZ]); + strings.push_back(val); + send_generic_message("autopilot", strings); + + LLViewerParcelMgr::getInstance()->deselectLand(); + + if (isAgentAvatarValid() && !gSavedSettings.getBOOL("AutoPilotLocksCamera")) + { + gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgentAvatarp->getID()); + } + else + { + // Snap camera back to behind avatar + gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); + } + + // Could be first use + //LLFirstUse::useGoTo(); + return true; } class LLGoToObject : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return handle_go_to(); - } + bool handleEvent(const LLSD& userdata) + { + return handle_go_to(); + } }; class LLAvatarReportAbuse : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - LLFloaterReporter::showFromObject(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLFloaterReporter::showFromObject(avatar->getID()); + } + return true; + } }; @@ -3590,230 +3590,230 @@ class LLAvatarReportAbuse : public view_listener_t //--------------------------------------------------------------------------- bool callback_freeze(const LLSD& notification, const LLSD& response) { - LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - - if (0 == option || 1 == option) - { - U32 flags = 0x0; - if (1 == option) - { - // unfreeze - flags |= 0x1; - } - - LLMessageSystem* msg = gMessageSystem; - LLViewerObject* avatar = gObjectList.findObject(avatar_id); - - if (avatar) - { - msg->newMessage("FreezeUser"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("Data"); - msg->addUUID("TargetID", avatar_id ); - msg->addU32("Flags", flags ); - msg->sendReliable( avatar->getRegion()->getHost() ); - } - } - return false; -} + LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option || 1 == option) + { + U32 flags = 0x0; + if (1 == option) + { + // unfreeze + flags |= 0x1; + } + LLMessageSystem* msg = gMessageSystem; + LLViewerObject* avatar = gObjectList.findObject(avatar_id); -void handle_avatar_freeze(const LLSD& avatar_id) -{ - // Use avatar_id if available, otherwise default to right-click avatar - LLVOAvatar* avatar = NULL; - if (avatar_id.asUUID().notNull()) - { - avatar = find_avatar_from_object(avatar_id.asUUID()); - } - else - { - avatar = find_avatar_from_object( - LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - } - - if( avatar ) - { - std::string fullname = avatar->getFullname(); - LLSD payload; - payload["avatar_id"] = avatar->getID(); - - if (!fullname.empty()) - { - LLSD args; - args["AVATAR_NAME"] = fullname; - LLNotificationsUtil::add("FreezeAvatarFullname", - args, - payload, - callback_freeze); - } - else - { - LLNotificationsUtil::add("FreezeAvatar", - LLSD(), - payload, - callback_freeze); - } - } + if (avatar) + { + msg->newMessage("FreezeUser"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("Data"); + msg->addUUID("TargetID", avatar_id ); + msg->addU32("Flags", flags ); + msg->sendReliable( avatar->getRegion()->getHost() ); + } + } + return false; } -class LLAvatarVisibleDebug : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - return gAgent.isGodlike(); - } -}; + +void handle_avatar_freeze(const LLSD& avatar_id) +{ + // Use avatar_id if available, otherwise default to right-click avatar + LLVOAvatar* avatar = NULL; + if (avatar_id.asUUID().notNull()) + { + avatar = find_avatar_from_object(avatar_id.asUUID()); + } + else + { + avatar = find_avatar_from_object( + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + } + + if( avatar ) + { + std::string fullname = avatar->getFullname(); + LLSD payload; + payload["avatar_id"] = avatar->getID(); + + if (!fullname.empty()) + { + LLSD args; + args["AVATAR_NAME"] = fullname; + LLNotificationsUtil::add("FreezeAvatarFullname", + args, + payload, + callback_freeze); + } + else + { + LLNotificationsUtil::add("FreezeAvatar", + LLSD(), + payload, + callback_freeze); + } + } +} + +class LLAvatarVisibleDebug : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gAgent.isGodlike(); + } +}; class LLAvatarDebug : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if( avatar ) - { - if (avatar->isSelf()) - { - ((LLVOAvatarSelf *)avatar)->dumpLocalTextures(); - } - LL_INFOS() << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << LL_ENDL; - std::vector strings; - strings.push_back(avatar->getID().asString()); - LLUUID invoice; - send_generic_message("dumptempassetdata", strings, invoice); - LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) ); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if( avatar ) + { + if (avatar->isSelf()) + { + ((LLVOAvatarSelf *)avatar)->dumpLocalTextures(); + } + LL_INFOS() << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << LL_ENDL; + std::vector strings; + strings.push_back(avatar->getID().asString()); + LLUUID invoice; + send_generic_message("dumptempassetdata", strings, invoice); + LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) ); + } + return true; + } }; bool callback_eject(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (2 == option) - { - // Cancel button. - return false; - } - LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); - bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean(); - - if (0 == option) - { - // Eject button - LLMessageSystem* msg = gMessageSystem; - LLViewerObject* avatar = gObjectList.findObject(avatar_id); - - if (avatar) - { - U32 flags = 0x0; - msg->newMessage("EjectUser"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID() ); - msg->addUUID("SessionID", gAgent.getSessionID() ); - msg->nextBlock("Data"); - msg->addUUID("TargetID", avatar_id ); - msg->addU32("Flags", flags ); - msg->sendReliable( avatar->getRegion()->getHost() ); - } - } - else if (ban_enabled) - { - // This is tricky. It is similar to say if it is not an 'Eject' button, - // and it is also not an 'Cancle' button, and ban_enabled==ture, - // it should be the 'Eject and Ban' button. - LLMessageSystem* msg = gMessageSystem; - LLViewerObject* avatar = gObjectList.findObject(avatar_id); - - if (avatar) - { - U32 flags = 0x1; - msg->newMessage("EjectUser"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID() ); - msg->addUUID("SessionID", gAgent.getSessionID() ); - msg->nextBlock("Data"); - msg->addUUID("TargetID", avatar_id ); - msg->addU32("Flags", flags ); - msg->sendReliable( avatar->getRegion()->getHost() ); - } - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (2 == option) + { + // Cancel button. + return false; + } + LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); + bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean(); + + if (0 == option) + { + // Eject button + LLMessageSystem* msg = gMessageSystem; + LLViewerObject* avatar = gObjectList.findObject(avatar_id); + + if (avatar) + { + U32 flags = 0x0; + msg->newMessage("EjectUser"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID() ); + msg->addUUID("SessionID", gAgent.getSessionID() ); + msg->nextBlock("Data"); + msg->addUUID("TargetID", avatar_id ); + msg->addU32("Flags", flags ); + msg->sendReliable( avatar->getRegion()->getHost() ); + } + } + else if (ban_enabled) + { + // This is tricky. It is similar to say if it is not an 'Eject' button, + // and it is also not an 'Cancle' button, and ban_enabled==ture, + // it should be the 'Eject and Ban' button. + LLMessageSystem* msg = gMessageSystem; + LLViewerObject* avatar = gObjectList.findObject(avatar_id); + + if (avatar) + { + U32 flags = 0x1; + msg->newMessage("EjectUser"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID() ); + msg->addUUID("SessionID", gAgent.getSessionID() ); + msg->nextBlock("Data"); + msg->addUUID("TargetID", avatar_id ); + msg->addU32("Flags", flags ); + msg->sendReliable( avatar->getRegion()->getHost() ); + } + } + return false; } void handle_avatar_eject(const LLSD& avatar_id) { - // Use avatar_id if available, otherwise default to right-click avatar - LLVOAvatar* avatar = NULL; - if (avatar_id.asUUID().notNull()) - { - avatar = find_avatar_from_object(avatar_id.asUUID()); - } - else - { - avatar = find_avatar_from_object( - LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - } - - if( avatar ) - { - LLSD payload; - payload["avatar_id"] = avatar->getID(); - std::string fullname = avatar->getFullname(); - - const LLVector3d& pos = avatar->getPositionGlobal(); - LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel(); - - if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED)) - { + // Use avatar_id if available, otherwise default to right-click avatar + LLVOAvatar* avatar = NULL; + if (avatar_id.asUUID().notNull()) + { + avatar = find_avatar_from_object(avatar_id.asUUID()); + } + else + { + avatar = find_avatar_from_object( + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + } + + if( avatar ) + { + LLSD payload; + payload["avatar_id"] = avatar->getID(); + std::string fullname = avatar->getFullname(); + + const LLVector3d& pos = avatar->getPositionGlobal(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel(); + + if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED)) + { payload["ban_enabled"] = true; - if (!fullname.empty()) - { - LLSD args; - args["AVATAR_NAME"] = fullname; - LLNotificationsUtil::add("EjectAvatarFullname", - args, - payload, - callback_eject); - } - else - { - LLNotificationsUtil::add("EjectAvatarFullname", - LLSD(), - payload, - callback_eject); - } - } - else - { + if (!fullname.empty()) + { + LLSD args; + args["AVATAR_NAME"] = fullname; + LLNotificationsUtil::add("EjectAvatarFullname", + args, + payload, + callback_eject); + } + else + { + LLNotificationsUtil::add("EjectAvatarFullname", + LLSD(), + payload, + callback_eject); + } + } + else + { payload["ban_enabled"] = false; - if (!fullname.empty()) - { - LLSD args; - args["AVATAR_NAME"] = fullname; - LLNotificationsUtil::add("EjectAvatarFullnameNoBan", - args, - payload, - callback_eject); - } - else - { - LLNotificationsUtil::add("EjectAvatarNoBan", - LLSD(), - payload, - callback_eject); - } - } - } + if (!fullname.empty()) + { + LLSD args; + args["AVATAR_NAME"] = fullname; + LLNotificationsUtil::add("EjectAvatarFullnameNoBan", + args, + payload, + callback_eject); + } + else + { + LLNotificationsUtil::add("EjectAvatarNoBan", + LLSD(), + payload, + callback_eject); + } + } + } } bool my_profile_visible() { - LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID); - return floaterp && floaterp->isInVisibleChain(); + LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID); + return floaterp && floaterp->isInVisibleChain(); } bool picks_tab_visible() @@ -3823,192 +3823,192 @@ bool picks_tab_visible() bool enable_freeze_eject(const LLSD& avatar_id) { - // Use avatar_id if available, otherwise default to right-click avatar - LLVOAvatar* avatar = NULL; - if (avatar_id.asUUID().notNull()) - { - avatar = find_avatar_from_object(avatar_id.asUUID()); - } - else - { - avatar = find_avatar_from_object( - LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - } - if (!avatar) return false; - - // Gods can always freeze - if (gAgent.isGodlike()) return true; - - // Estate owners / managers can freeze - // Parcel owners can also freeze - const LLVector3& pos = avatar->getPositionRegion(); - const LLVector3d& pos_global = avatar->getPositionGlobal(); - LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel(); - LLViewerRegion* region = avatar->getRegion(); - if (!region) return false; - - bool new_value = region->isOwnedSelf(pos); - if (!new_value || region->isOwnedGroup(pos)) - { - new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN); - } - return new_value; + // Use avatar_id if available, otherwise default to right-click avatar + LLVOAvatar* avatar = NULL; + if (avatar_id.asUUID().notNull()) + { + avatar = find_avatar_from_object(avatar_id.asUUID()); + } + else + { + avatar = find_avatar_from_object( + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + } + if (!avatar) return false; + + // Gods can always freeze + if (gAgent.isGodlike()) return true; + + // Estate owners / managers can freeze + // Parcel owners can also freeze + const LLVector3& pos = avatar->getPositionRegion(); + const LLVector3d& pos_global = avatar->getPositionGlobal(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel(); + LLViewerRegion* region = avatar->getRegion(); + if (!region) return false; + + bool new_value = region->isOwnedSelf(pos); + if (!new_value || region->isOwnedGroup(pos)) + { + new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN); + } + return new_value; } bool callback_leave_group(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - LLMessageSystem *msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_LeaveGroupRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_GroupData); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() ); - gAgent.sendReliableMessage(); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_LeaveGroupRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_GroupData); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() ); + gAgent.sendReliableMessage(); + } + return false; } void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt) { - LLAggregatePermissions::EValue val = ag_perm.getValue(bit); - std::string buffer; - switch(val) - { - case LLAggregatePermissions::AP_NONE: - buffer = llformat( "* %s None\n", txt); - break; - case LLAggregatePermissions::AP_SOME: - buffer = llformat( "* %s Some\n", txt); - break; - case LLAggregatePermissions::AP_ALL: - buffer = llformat( "* %s All\n", txt); - break; - case LLAggregatePermissions::AP_EMPTY: - default: - break; - } - string.append(buffer); + LLAggregatePermissions::EValue val = ag_perm.getValue(bit); + std::string buffer; + switch(val) + { + case LLAggregatePermissions::AP_NONE: + buffer = llformat( "* %s None\n", txt); + break; + case LLAggregatePermissions::AP_SOME: + buffer = llformat( "* %s Some\n", txt); + break; + case LLAggregatePermissions::AP_ALL: + buffer = llformat( "* %s All\n", txt); + break; + case LLAggregatePermissions::AP_EMPTY: + default: + break; + } + string.append(buffer); } bool enable_buy_object() { // In order to buy, there must only be 1 purchaseable object in // the selection manager. - if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false; + if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false; LLViewerObject* obj = NULL; LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if(node) + if(node) { obj = node->getObject(); if(!obj) return false; - if( for_sale_selection(node) ) - { - // *NOTE: Is this needed? This checks to see if anyone owns the - // object, dating back to when we had "public" objects owned by - // no one. JC - if(obj->permAnyOwner()) return true; - } + if( for_sale_selection(node) ) + { + // *NOTE: Is this needed? This checks to see if anyone owns the + // object, dating back to when we had "public" objects owned by + // no one. JC + if(obj->permAnyOwner()) return true; + } } - return false; + return false; } // Note: This will only work if the selected object's data has been // received by the viewer and cached in the selection manager. void handle_buy_object(LLSaleInfo sale_info) { - if(!LLSelectMgr::getInstance()->selectGetAllRootsValid()) - { - LLNotificationsUtil::add("UnableToBuyWhileDownloading"); - return; - } + if(!LLSelectMgr::getInstance()->selectGetAllRootsValid()) + { + LLNotificationsUtil::add("UnableToBuyWhileDownloading"); + return; + } - LLUUID owner_id; - std::string owner_name; - BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); - if (!owners_identical) - { - LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners"); - return; - } + LLUUID owner_id; + std::string owner_name; + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); + if (!owners_identical) + { + LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners"); + return; + } - LLPermissions perm; - BOOL valid = LLSelectMgr::getInstance()->selectGetPermissions(perm); - LLAggregatePermissions ag_perm; - valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm); - if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID())) - { - LLNotificationsUtil::add("ObjectNotForSale"); - return; - } + LLPermissions perm; + BOOL valid = LLSelectMgr::getInstance()->selectGetPermissions(perm); + LLAggregatePermissions ag_perm; + valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm); + if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID())) + { + LLNotificationsUtil::add("ObjectNotForSale"); + return; + } - LLFloaterBuy::show(sale_info); + LLFloaterBuy::show(sale_info); } void handle_buy_contents(LLSaleInfo sale_info) { - LLFloaterBuyContents::show(sale_info); + LLFloaterBuyContents::show(sale_info); } void handle_region_dump_temp_asset_data(void*) { - LL_INFOS() << "Dumping temporary asset data to simulator logs" << LL_ENDL; - std::vector strings; - LLUUID invoice; - send_generic_message("dumptempassetdata", strings, invoice); + LL_INFOS() << "Dumping temporary asset data to simulator logs" << LL_ENDL; + std::vector strings; + LLUUID invoice; + send_generic_message("dumptempassetdata", strings, invoice); } void handle_region_clear_temp_asset_data(void*) { - LL_INFOS() << "Clearing temporary asset data" << LL_ENDL; - std::vector strings; - LLUUID invoice; - send_generic_message("cleartempassetdata", strings, invoice); + LL_INFOS() << "Clearing temporary asset data" << LL_ENDL; + std::vector strings; + LLUUID invoice; + send_generic_message("cleartempassetdata", strings, invoice); } void handle_region_dump_settings(void*) { - LLViewerRegion* regionp = gAgent.getRegion(); - if (regionp) - { - LL_INFOS() << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << LL_ENDL; - LL_INFOS() << "Water: " << (regionp->getWaterHeight()) << LL_ENDL; - } + LLViewerRegion* regionp = gAgent.getRegion(); + if (regionp) + { + LL_INFOS() << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << LL_ENDL; + LL_INFOS() << "Water: " << (regionp->getWaterHeight()) << LL_ENDL; + } } void handle_dump_group_info(void *) { - gAgent.dumpGroupInfo(); + gAgent.dumpGroupInfo(); } void handle_dump_capabilities_info(void *) { - LLViewerRegion* regionp = gAgent.getRegion(); - if (regionp) - { - regionp->logActiveCapabilities(); - } + LLViewerRegion* regionp = gAgent.getRegion(); + if (regionp) + { + regionp->logActiveCapabilities(); + } } void handle_dump_region_object_cache(void*) { - LLViewerRegion* regionp = gAgent.getRegion(); - if (regionp) - { - regionp->dumpCache(); - } + LLViewerRegion* regionp = gAgent.getRegion(); + if (regionp) + { + regionp->dumpCache(); + } } void handle_reset_interest_lists(void *) @@ -4029,18 +4029,18 @@ void handle_reset_interest_lists(void *) void handle_dump_focus() { - LLUICtrl *ctrl = dynamic_cast(gFocusMgr.getKeyboardFocus()); + LLUICtrl *ctrl = dynamic_cast(gFocusMgr.getKeyboardFocus()); - LL_INFOS() << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << LL_ENDL; + LL_INFOS() << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << LL_ENDL; } class LLSelfStandUp : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgent.standUp(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gAgent.standUp(); + return true; + } }; bool enable_standup_self() @@ -4061,202 +4061,202 @@ class LLSelfSitDown : public view_listener_t bool show_sitdown_self() { - return isAgentAvatarValid() && !gAgentAvatarp->isSitting(); + return isAgentAvatarValid() && !gAgentAvatarp->isSitting(); } bool enable_sitdown_self() { - return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying(); + return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying(); } class LLSelfToggleSitStand : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (isAgentAvatarValid()) - { - if (gAgentAvatarp->isSitting()) - { - gAgent.standUp(); - } - else - { - gAgent.sitDown(); - } - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (isAgentAvatarValid()) + { + if (gAgentAvatarp->isSitting()) + { + gAgent.standUp(); + } + else + { + gAgent.sitDown(); + } + } + return true; + } }; bool enable_sit_stand() { - return enable_sitdown_self() || enable_standup_self(); + return enable_sitdown_self() || enable_standup_self(); } bool enable_fly_land() { - return gAgent.getFlying() || LLAgent::enableFlying(); + return gAgent.getFlying() || LLAgent::enableFlying(); } class LLCheckPanelPeopleTab : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string panel_name = userdata.asString(); + bool handleEvent(const LLSD& userdata) + { + std::string panel_name = userdata.asString(); - LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); - if(panel && panel->isInVisibleChain()) - { - return true; - } - return false; - } + LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); + if(panel && panel->isInVisibleChain()) + { + return true; + } + return false; + } }; // Toggle one of "People" panel tabs in side tray. class LLTogglePanelPeopleTab : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string panel_name = userdata.asString(); - - LLSD param; - param["people_panel_tab_name"] = panel_name; - - if ( panel_name == "friends_panel" - || panel_name == "groups_panel" - || panel_name == "nearby_panel" - || panel_name == "blocked_panel") - { - return togglePeoplePanel(panel_name, param); - } - else - { - return false; - } - } - - static bool togglePeoplePanel(const std::string& panel_name, const LLSD& param) - { - LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); - if(!panel) - return false; - - if (panel->isInVisibleChain()) - { - LLFloaterReg::hideInstance("people"); - } - else - { - LLFloaterSidePanelContainer::showPanel("people", "panel_people", param) ; - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string panel_name = userdata.asString(); + + LLSD param; + param["people_panel_tab_name"] = panel_name; + + if ( panel_name == "friends_panel" + || panel_name == "groups_panel" + || panel_name == "nearby_panel" + || panel_name == "blocked_panel") + { + return togglePeoplePanel(panel_name, param); + } + else + { + return false; + } + } + + static bool togglePeoplePanel(const std::string& panel_name, const LLSD& param) + { + LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); + if(!panel) + return false; + + if (panel->isInVisibleChain()) + { + LLFloaterReg::hideInstance("people"); + } + else + { + LLFloaterSidePanelContainer::showPanel("people", "panel_people", param) ; + } + + return true; + } }; BOOL check_admin_override(void*) { - return gAgent.getAdminOverride(); + return gAgent.getAdminOverride(); } void handle_admin_override_toggle(void*) { - gAgent.setAdminOverride(!gAgent.getAdminOverride()); + gAgent.setAdminOverride(!gAgent.getAdminOverride()); - // The above may have affected which debug menus are visible - show_debug_menus(); + // The above may have affected which debug menus are visible + show_debug_menus(); } void handle_visual_leak_detector_toggle(void*) { - static bool vld_enabled = false; + static bool vld_enabled = false; - if ( vld_enabled ) - { + if ( vld_enabled ) + { #ifdef INCLUDE_VLD - // only works for debug builds (hard coded into vld.h) + // only works for debug builds (hard coded into vld.h) #ifdef _DEBUG - // start with Visual Leak Detector turned off - VLDDisable(); + // start with Visual Leak Detector turned off + VLDDisable(); #endif // _DEBUG #endif // INCLUDE_VLD - vld_enabled = false; - } - else - { + vld_enabled = false; + } + else + { #ifdef INCLUDE_VLD - // only works for debug builds (hard coded into vld.h) - #ifdef _DEBUG - // start with Visual Leak Detector turned off - VLDEnable(); - #endif // _DEBUG + // only works for debug builds (hard coded into vld.h) + #ifdef _DEBUG + // start with Visual Leak Detector turned off + VLDEnable(); + #endif // _DEBUG #endif // INCLUDE_VLD - vld_enabled = true; - }; + vld_enabled = true; + }; } void handle_god_mode(void*) { - gAgent.requestEnterGodMode(); + gAgent.requestEnterGodMode(); } void handle_leave_god_mode(void*) { - gAgent.requestLeaveGodMode(); + gAgent.requestLeaveGodMode(); } void set_god_level(U8 god_level) { - U8 old_god_level = gAgent.getGodLevel(); - gAgent.setGodLevel( god_level ); - LLViewerParcelMgr::getInstance()->notifyObservers(); + U8 old_god_level = gAgent.getGodLevel(); + gAgent.setGodLevel( god_level ); + LLViewerParcelMgr::getInstance()->notifyObservers(); - // God mode changes region visibility - LLWorldMap::getInstance()->reloadItems(true); + // God mode changes region visibility + LLWorldMap::getInstance()->reloadItems(true); - // inventory in items may change in god mode - gObjectList.dirtyAllObjectInventory(); + // inventory in items may change in god mode + gObjectList.dirtyAllObjectInventory(); if(gViewerWindow) { gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT, LLGridManager::getInstance()->isInProductionGrid()); } - + LLSD args; - if(god_level > GOD_NOT) - { - args["LEVEL"] = llformat("%d",(S32)god_level); - LLNotificationsUtil::add("EnteringGodMode", args); - } - else - { - args["LEVEL"] = llformat("%d",(S32)old_god_level); - LLNotificationsUtil::add("LeavingGodMode", args); - } - - // changing god-level can affect which menus we see - show_debug_menus(); - - // changing god-level can invalidate search results - LLFloaterSearch *search = dynamic_cast(LLFloaterReg::getInstance("search")); - if (search) - { - search->godLevelChanged(god_level); - } + if(god_level > GOD_NOT) + { + args["LEVEL"] = llformat("%d",(S32)god_level); + LLNotificationsUtil::add("EnteringGodMode", args); + } + else + { + args["LEVEL"] = llformat("%d",(S32)old_god_level); + LLNotificationsUtil::add("LeavingGodMode", args); + } + + // changing god-level can affect which menus we see + show_debug_menus(); + + // changing god-level can invalidate search results + LLFloaterSearch *search = dynamic_cast(LLFloaterReg::getInstance("search")); + if (search) + { + search->godLevelChanged(god_level); + } } #ifdef TOGGLE_HACKED_GODLIKE_VIEWER void handle_toggle_hacked_godmode(void*) { - gHackGodmode = !gHackGodmode; - set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT); + gHackGodmode = !gHackGodmode; + set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT); } BOOL check_toggle_hacked_godmode(void*) { - return gHackGodmode; + return gHackGodmode; } bool enable_toggle_hacked_godmode(void*) @@ -4267,174 +4267,174 @@ bool enable_toggle_hacked_godmode(void*) void process_grant_godlike_powers(LLMessageSystem* msg, void**) { - LLUUID agent_id; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); - LLUUID session_id; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id); - if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID())) - { - U8 god_level; - msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level); - set_god_level(god_level); - } - else - { - LL_WARNS() << "Grant godlike for wrong agent " << agent_id << LL_ENDL; - } + LLUUID agent_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + LLUUID session_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id); + if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID())) + { + U8 god_level; + msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level); + set_god_level(god_level); + } + else + { + LL_WARNS() << "Grant godlike for wrong agent " << agent_id << LL_ENDL; + } } /* class LLHaveCallingcard : public LLInventoryCollectFunctor { public: - LLHaveCallingcard(const LLUUID& agent_id); - virtual ~LLHaveCallingcard() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item); - BOOL isThere() const { return mIsThere;} + LLHaveCallingcard(const LLUUID& agent_id); + virtual ~LLHaveCallingcard() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); + BOOL isThere() const { return mIsThere;} protected: - LLUUID mID; - BOOL mIsThere; + LLUUID mID; + BOOL mIsThere; }; LLHaveCallingcard::LLHaveCallingcard(const LLUUID& agent_id) : - mID(agent_id), - mIsThere(FALSE) + mID(agent_id), + mIsThere(FALSE) { } bool LLHaveCallingcard::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - if(item) - { - if((item->getType() == LLAssetType::AT_CALLINGCARD) - && (item->getCreatorUUID() == mID)) - { - mIsThere = TRUE; - } - } - return FALSE; + LLInventoryItem* item) +{ + if(item) + { + if((item->getType() == LLAssetType::AT_CALLINGCARD) + && (item->getCreatorUUID() == mID)) + { + mIsThere = TRUE; + } + } + return FALSE; } */ BOOL is_agent_mappable(const LLUUID& agent_id) { - const LLRelationship* buddy_info = NULL; - bool is_friend = LLAvatarActions::isFriend(agent_id); + const LLRelationship* buddy_info = NULL; + bool is_friend = LLAvatarActions::isFriend(agent_id); - if (is_friend) - buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id); + if (is_friend) + buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id); - return (buddy_info && - buddy_info->isOnline() && - buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) - ); + return (buddy_info && + buddy_info->isOnline() && + buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) + ); } // Enable a menu item when you don't have someone's card. class LLAvatarEnableAddFriend : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()); + return new_value; + } }; void request_friendship(const LLUUID& dest_id) { - LLViewerObject* dest = gObjectList.findObject(dest_id); - if(dest && dest->isAvatar()) - { - std::string full_name; - LLNameValue* nvfirst = dest->getNVPair("FirstName"); - LLNameValue* nvlast = dest->getNVPair("LastName"); - if(nvfirst && nvlast) - { - full_name = LLCacheName::buildFullName( - nvfirst->getString(), nvlast->getString()); - } - if (!full_name.empty()) - { - LLAvatarActions::requestFriendshipDialog(dest_id, full_name); - } - else - { - LLNotificationsUtil::add("CantOfferFriendship"); - } - } + LLViewerObject* dest = gObjectList.findObject(dest_id); + if(dest && dest->isAvatar()) + { + std::string full_name; + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + full_name = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + } + if (!full_name.empty()) + { + LLAvatarActions::requestFriendshipDialog(dest_id, full_name); + } + else + { + LLNotificationsUtil::add("CantOfferFriendship"); + } + } } class LLEditEnableCustomizeAvatar : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gAgentWearables.areWearablesLoaded(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gAgentWearables.areWearablesLoaded(); + return new_value; + } }; class LLEnableEditShape : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0); - } + bool handleEvent(const LLSD& userdata) + { + return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0); + } }; class LLEnableHoverHeight : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled(); - } + bool handleEvent(const LLSD& userdata) + { + return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled(); + } }; class LLEnableEditPhysics : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - //return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0); - return TRUE; - } + bool handleEvent(const LLSD& userdata) + { + //return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0); + return TRUE; + } }; bool is_object_sittable() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (object && object->getPCode() == LL_PCODE_VOLUME) - { - return true; - } - else - { - return false; - } + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + return true; + } + else + { + return false; + } } // only works on pie menu void handle_object_sit(LLViewerObject *object, const LLVector3 &offset) { - // get object selection offset + // get object selection offset - if (object && object->getPCode() == LL_PCODE_VOLUME) - { + if (object && object->getPCode() == LL_PCODE_VOLUME) + { - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, offset); + gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_TargetObject); + gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); + gMessageSystem->addVector3Fast(_PREHASH_Offset, offset); - object->getRegion()->sendReliableMessage(); - } + object->getRegion()->sendReliableMessage(); + } } void handle_object_sit_or_stand() @@ -4469,12 +4469,12 @@ void handle_object_sit(const LLUUID& object_id) void near_sit_down_point(BOOL success, void *) { - if (success) - { - gAgent.setFlying(FALSE); - gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot - gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - } + if (success) + { + gAgent.setFlying(FALSE); + gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + } } class LLLandSit : public view_listener_t @@ -4521,120 +4521,120 @@ void reset_view_final( BOOL proceed ); void handle_reset_view() { - if (gAgentCamera.cameraCustomizeAvatar()) - { - // switching to outfit selector should automagically save any currently edited wearable - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); - } - gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE); - reset_view_final( TRUE ); - LLFloaterCamera::resetCameraMode(); + if (gAgentCamera.cameraCustomizeAvatar()) + { + // switching to outfit selector should automagically save any currently edited wearable + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); + } + gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE); + reset_view_final( TRUE ); + LLFloaterCamera::resetCameraMode(); } class LLViewResetView : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - handle_reset_view(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + handle_reset_view(); + return true; + } }; // Note: extra parameters allow this function to be called from dialog. -void reset_view_final( BOOL proceed ) +void reset_view_final( BOOL proceed ) { - if( !proceed ) - { - return; - } + if( !proceed ) + { + return; + } - gAgentCamera.resetView(TRUE, TRUE); - gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + gAgentCamera.resetView(TRUE, TRUE); + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); } class LLViewLookAtLastChatter : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgentCamera.lookAtLastChat(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gAgentCamera.lookAtLastChat(); + return true; + } }; class LLViewMouselook : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (!gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToMouselook(); - } - else - { - gAgentCamera.changeCameraToDefault(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (!gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToMouselook(); + } + else + { + gAgentCamera.changeCameraToDefault(); + } + return true; + } }; class LLViewDefaultUISize : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gSavedSettings.setF32("UIScaleFactor", 1.0f); - gSavedSettings.setBOOL("UIAutoScale", FALSE); - gViewerWindow->reshape(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gSavedSettings.setF32("UIScaleFactor", 1.0f); + gSavedSettings.setBOOL("UIAutoScale", FALSE); + gViewerWindow->reshape(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); + return true; + } }; class LLViewToggleUI : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) - { - LLNotification::Params params("ConfirmHideUI"); - params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); - LLSD substitutions; + bool handleEvent(const LLSD& userdata) + { + if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + { + LLNotification::Params params("ConfirmHideUI"); + params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); + LLSD substitutions; #if LL_DARWIN - substitutions["SHORTCUT"] = "Cmd+Shift+U"; + substitutions["SHORTCUT"] = "Cmd+Shift+U"; #else - substitutions["SHORTCUT"] = "Ctrl+Shift+U"; + substitutions["SHORTCUT"] = "Ctrl+Shift+U"; #endif - params.substitutions = substitutions; - if (!gSavedSettings.getBOOL("HideUIControls")) - { - // hiding, so show notification - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } - } - return true; - } - - void confirm(const LLSD& notification, const LLSD& response) - { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - - if (option == 0) // OK - { - gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls")); - LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls")); - gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls")); - } - } + params.substitutions = substitutions; + if (!gSavedSettings.getBOOL("HideUIControls")) + { + // hiding, so show notification + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } + } + return true; + } + + void confirm(const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (option == 0) // OK + { + gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls")); + LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls")); + gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls")); + } + } }; void handle_duplicate_in_place(void*) { - LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL; + LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL; - LLVector3 offset(0.f, 0.f, 0.f); - LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE); + LLVector3 offset(0.f, 0.f, 0.f); + LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE); } @@ -4643,121 +4643,121 @@ void handle_duplicate_in_place(void*) * No longer able to support viewer side manipulations in this way * void god_force_inv_owner_permissive(LLViewerObject* object, - LLInventoryObject::object_list_t* inventory, - S32 serial_num, - void*) -{ - typedef std::vector > item_array_t; - item_array_t items; - - LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin(); - LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end(); - for ( ; inv_it != inv_end; ++inv_it) - { - if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)) - { - LLInventoryObject* obj = *inv_it; - LLPointer new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); - LLPermissions perm(new_item->getPermissions()); - perm.setMaskBase(PERM_ALL); - perm.setMaskOwner(PERM_ALL); - new_item->setPermissions(perm); - items.push_back(new_item); - } - } - item_array_t::iterator end = items.end(); - item_array_t::iterator it; - for(it = items.begin(); it != end; ++it) - { - // since we have the inventory item in the callback, it should not - // invalidate iteration through the selection manager. - object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); - } + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void*) +{ + typedef std::vector > item_array_t; + item_array_t items; + + LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin(); + LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end(); + for ( ; inv_it != inv_end; ++inv_it) + { + if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)) + { + LLInventoryObject* obj = *inv_it; + LLPointer new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); + LLPermissions perm(new_item->getPermissions()); + perm.setMaskBase(PERM_ALL); + perm.setMaskOwner(PERM_ALL); + new_item->setPermissions(perm); + items.push_back(new_item); + } + } + item_array_t::iterator end = items.end(); + item_array_t::iterator it; + for(it = items.begin(); it != end; ++it) + { + // since we have the inventory item in the callback, it should not + // invalidate iteration through the selection manager. + object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); + } } */ void handle_object_owner_permissive(void*) { - // only send this if they're a god. - if(gAgent.isGodlike()) - { - // do the objects. - LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE); - LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE); - } + // only send this if they're a god. + if(gAgent.isGodlike()) + { + // do the objects. + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE); + } } void handle_object_owner_self(void*) { - // only send this if they're a god. - if(gAgent.isGodlike()) - { - LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE); - } + // only send this if they're a god. + if(gAgent.isGodlike()) + { + LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE); + } } // Shortcut to set owner permissions to not editable. void handle_object_lock(void*) { - LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY); } void handle_object_asset_ids(void*) { - // only send this if they're a god. - if (gAgent.isGodlike()) - { - LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids"); - } + // only send this if they're a god. + if (gAgent.isGodlike()) + { + LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids"); + } } void handle_force_parcel_owner_to_me(void*) { - LLViewerParcelMgr::getInstance()->sendParcelGodForceOwner( gAgent.getID() ); + LLViewerParcelMgr::getInstance()->sendParcelGodForceOwner( gAgent.getID() ); } void handle_force_parcel_to_content(void*) { - LLViewerParcelMgr::getInstance()->sendParcelGodForceToContent(); + LLViewerParcelMgr::getInstance()->sendParcelGodForceToContent(); } void handle_claim_public_land(void*) { - if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion()) - { - LLNotificationsUtil::add("ClaimPublicLand"); - return; - } - - LLVector3d west_south_global; - LLVector3d east_north_global; - LLViewerParcelMgr::getInstance()->getSelection(west_south_global, east_north_global); - LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global); - LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("GodlikeMessage"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", "claimpublicland"); - msg->addUUID("Invoice", LLUUID::null); - std::string buffer; - buffer = llformat( "%f", west_south.mV[VX]); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - buffer = llformat( "%f", west_south.mV[VY]); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - buffer = llformat( "%f", east_north.mV[VX]); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - buffer = llformat( "%f", east_north.mV[VY]); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - gAgent.sendReliableMessage(); + if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion()) + { + LLNotificationsUtil::add("ClaimPublicLand"); + return; + } + + LLVector3d west_south_global; + LLVector3d east_north_global; + LLViewerParcelMgr::getInstance()->getSelection(west_south_global, east_north_global); + LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global); + LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("GodlikeMessage"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", "claimpublicland"); + msg->addUUID("Invoice", LLUUID::null); + std::string buffer; + buffer = llformat( "%f", west_south.mV[VX]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + buffer = llformat( "%f", west_south.mV[VY]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + buffer = llformat( "%f", east_north.mV[VX]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + buffer = llformat( "%f", east_north.mV[VY]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + gAgent.sendReliableMessage(); } @@ -4765,286 +4765,286 @@ void handle_claim_public_land(void*) // HACK for easily testing new avatar geometry void handle_god_request_avatar_geometry(void *) { - if (gAgent.isGodlike()) - { - LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", ""); - } + if (gAgent.isGodlike()) + { + LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", ""); + } } static bool get_derezzable_objects( - EDeRezDestination dest, - std::string& error, - LLViewerRegion*& first_region, - std::vector* derez_objectsp, - bool only_check = false) -{ - bool found = false; - - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - if (derez_objectsp) - derez_objectsp->reserve(selection->getRootObjectCount()); - - // Check conditions that we can't deal with, building a list of - // everything that we'll actually be derezzing. - for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin(); - iter != selection->valid_root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - LLViewerRegion* region = object->getRegion(); - if (!first_region) - { - first_region = region; - } - else - { - if(region != first_region) - { - // Derez doesn't work at all if the some of the objects - // are in regions besides the first object selected. - - // ...crosses region boundaries - error = "AcquireErrorObjectSpan"; - break; - } - } - if (object->isAvatar()) - { - // ...don't acquire avatars - continue; - } - - // If AssetContainers are being sent back, they will appear as - // boxes in the owner's inventory. - if (object->getNVPair("AssetContainer") - && dest != DRD_RETURN_TO_OWNER) - { - // this object is an asset container, derez its contents, not it - LL_WARNS() << "Attempt to derez deprecated AssetContainer object type not supported." << LL_ENDL; - /* - object->requestInventory(container_inventory_arrived, - (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest)); - */ - continue; - } - BOOL can_derez_current = FALSE; - switch(dest) - { - case DRD_TAKE_INTO_AGENT_INVENTORY: - case DRD_TRASH: - if (!object->isPermanentEnforced() && - ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) - || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)))) - { - can_derez_current = TRUE; - } - break; - - case DRD_RETURN_TO_OWNER: - if(!object->isAttachment()) - { - can_derez_current = TRUE; - } - break; - - default: - if((node->mPermissions->allowTransferTo(gAgent.getID()) - && object->permCopy()) - || gAgent.isGodlike()) - { - can_derez_current = TRUE; - } - break; - } - if(can_derez_current) - { - found = true; - - if (only_check) - // one found, no need to traverse to the end - break; - - if (derez_objectsp) - derez_objectsp->push_back(object); - - } - } - - return found; + EDeRezDestination dest, + std::string& error, + LLViewerRegion*& first_region, + std::vector* derez_objectsp, + bool only_check = false) +{ + bool found = false; + + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + if (derez_objectsp) + derez_objectsp->reserve(selection->getRootObjectCount()); + + // Check conditions that we can't deal with, building a list of + // everything that we'll actually be derezzing. + for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin(); + iter != selection->valid_root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + LLViewerRegion* region = object->getRegion(); + if (!first_region) + { + first_region = region; + } + else + { + if(region != first_region) + { + // Derez doesn't work at all if the some of the objects + // are in regions besides the first object selected. + + // ...crosses region boundaries + error = "AcquireErrorObjectSpan"; + break; + } + } + if (object->isAvatar()) + { + // ...don't acquire avatars + continue; + } + + // If AssetContainers are being sent back, they will appear as + // boxes in the owner's inventory. + if (object->getNVPair("AssetContainer") + && dest != DRD_RETURN_TO_OWNER) + { + // this object is an asset container, derez its contents, not it + LL_WARNS() << "Attempt to derez deprecated AssetContainer object type not supported." << LL_ENDL; + /* + object->requestInventory(container_inventory_arrived, + (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest)); + */ + continue; + } + BOOL can_derez_current = FALSE; + switch(dest) + { + case DRD_TAKE_INTO_AGENT_INVENTORY: + case DRD_TRASH: + if (!object->isPermanentEnforced() && + ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) + || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)))) + { + can_derez_current = TRUE; + } + break; + + case DRD_RETURN_TO_OWNER: + if(!object->isAttachment()) + { + can_derez_current = TRUE; + } + break; + + default: + if((node->mPermissions->allowTransferTo(gAgent.getID()) + && object->permCopy()) + || gAgent.isGodlike()) + { + can_derez_current = TRUE; + } + break; + } + if(can_derez_current) + { + found = true; + + if (only_check) + // one found, no need to traverse to the end + break; + + if (derez_objectsp) + derez_objectsp->push_back(object); + + } + } + + return found; } static bool can_derez(EDeRezDestination dest) { - LLViewerRegion* first_region = NULL; - std::string error; - return get_derezzable_objects(dest, error, first_region, NULL, true); + LLViewerRegion* first_region = NULL; + std::string error; + return get_derezzable_objects(dest, error, first_region, NULL, true); } static void derez_objects( - EDeRezDestination dest, - const LLUUID& dest_id, - LLViewerRegion*& first_region, - std::string& error, - std::vector* objectsp) -{ - std::vector derez_objects; - - if (!objectsp) // if objects to derez not specified - { - // get them from selection - if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false)) - { - LL_WARNS() << "No objects to derez" << LL_ENDL; - return; - } - - objectsp = &derez_objects; - } - - - if(gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToDefault(); - } - - // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per - // root. I lopped off a few (33) to provide a bit - // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs. - // This gives us a maximum of 63500 root objects - which should - // satisfy anybody. - const S32 MAX_ROOTS_PER_PACKET = 250; - const S32 MAX_PACKET_COUNT = 254; - F32 packets = ceil((F32)objectsp->size() / (F32)MAX_ROOTS_PER_PACKET); - if(packets > (F32)MAX_PACKET_COUNT) - { - error = "AcquireErrorTooManyObjects"; - } - - if(error.empty() && objectsp->size() > 0) - { - U8 d = (U8)dest; - LLUUID tid; - tid.generate(); - U8 packet_count = (U8)packets; - S32 object_index = 0; - S32 objects_in_packet = 0; - LLMessageSystem* msg = gMessageSystem; - for(U8 packet_number = 0; - packet_number < packet_count; - ++packet_number) - { - msg->newMessageFast(_PREHASH_DeRezObject); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_AgentBlock); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - msg->addU8Fast(_PREHASH_Destination, d); - msg->addUUIDFast(_PREHASH_DestinationID, dest_id); - msg->addUUIDFast(_PREHASH_TransactionID, tid); - msg->addU8Fast(_PREHASH_PacketCount, packet_count); - msg->addU8Fast(_PREHASH_PacketNumber, packet_number); - objects_in_packet = 0; - while((object_index < objectsp->size()) - && (objects_in_packet++ < MAX_ROOTS_PER_PACKET)) - - { - LLViewerObject* object = objectsp->at(object_index++); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - // VEFFECT: DerezObject - LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); - effectp->setPositionGlobal(object->getPositionGlobal()); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - } - msg->sendReliable(first_region->getHost()); - } - make_ui_sound("UISndObjectRezOut"); - - // Busy count decremented by inventory update, so only increment - // if will be causing an update. - if (dest != DRD_RETURN_TO_OWNER) - { - gViewerWindow->getWindow()->incBusyCount(); - } - } - else if(!error.empty()) - { - LLNotificationsUtil::add(error); - } + EDeRezDestination dest, + const LLUUID& dest_id, + LLViewerRegion*& first_region, + std::string& error, + std::vector* objectsp) +{ + std::vector derez_objects; + + if (!objectsp) // if objects to derez not specified + { + // get them from selection + if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false)) + { + LL_WARNS() << "No objects to derez" << LL_ENDL; + return; + } + + objectsp = &derez_objects; + } + + + if(gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToDefault(); + } + + // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per + // root. I lopped off a few (33) to provide a bit + // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs. + // This gives us a maximum of 63500 root objects - which should + // satisfy anybody. + const S32 MAX_ROOTS_PER_PACKET = 250; + const S32 MAX_PACKET_COUNT = 254; + F32 packets = ceil((F32)objectsp->size() / (F32)MAX_ROOTS_PER_PACKET); + if(packets > (F32)MAX_PACKET_COUNT) + { + error = "AcquireErrorTooManyObjects"; + } + + if(error.empty() && objectsp->size() > 0) + { + U8 d = (U8)dest; + LLUUID tid; + tid.generate(); + U8 packet_count = (U8)packets; + S32 object_index = 0; + S32 objects_in_packet = 0; + LLMessageSystem* msg = gMessageSystem; + for(U8 packet_number = 0; + packet_number < packet_count; + ++packet_number) + { + msg->newMessageFast(_PREHASH_DeRezObject); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_AgentBlock); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + msg->addU8Fast(_PREHASH_Destination, d); + msg->addUUIDFast(_PREHASH_DestinationID, dest_id); + msg->addUUIDFast(_PREHASH_TransactionID, tid); + msg->addU8Fast(_PREHASH_PacketCount, packet_count); + msg->addU8Fast(_PREHASH_PacketNumber, packet_number); + objects_in_packet = 0; + while((object_index < objectsp->size()) + && (objects_in_packet++ < MAX_ROOTS_PER_PACKET)) + + { + LLViewerObject* object = objectsp->at(object_index++); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); + // VEFFECT: DerezObject + LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); + effectp->setPositionGlobal(object->getPositionGlobal()); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } + msg->sendReliable(first_region->getHost()); + } + make_ui_sound("UISndObjectRezOut"); + + // Busy count decremented by inventory update, so only increment + // if will be causing an update. + if (dest != DRD_RETURN_TO_OWNER) + { + gViewerWindow->getWindow()->incBusyCount(); + } + } + else if(!error.empty()) + { + LLNotificationsUtil::add(error); + } } static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id) { - LLViewerRegion* first_region = NULL; - std::string error; - derez_objects(dest, dest_id, first_region, error, NULL); + LLViewerRegion* first_region = NULL; + std::string error; + derez_objects(dest, dest_id, first_region, error, NULL); } void handle_take_copy() { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; - const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); - derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id); + const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id); } void handle_link_objects() { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - LLFloaterReg::toggleInstanceOrBringToFront("places"); - } - else - { - LLSelectMgr::getInstance()->linkObjects(); - } + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + LLFloaterReg::toggleInstanceOrBringToFront("places"); + } + else + { + LLSelectMgr::getInstance()->linkObjects(); + } } // You can return an object to its owner if it is on your land. class LLObjectReturn : public view_listener_t { public: - LLObjectReturn() : mFirstRegion(NULL) {} + LLObjectReturn() : mFirstRegion(NULL) {} private: - bool handleEvent(const LLSD& userdata) - { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; - - mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + bool handleEvent(const LLSD& userdata) + { + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; + + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); - // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. - get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects); + // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. + get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects); - LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2)); - return true; - } + LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2)); + return true; + } - bool onReturnToOwner(const LLSD& notification, const LLSD& response) - { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - // Ignore category ID for this derez destination. - derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects); - } + bool onReturnToOwner(const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + // Ignore category ID for this derez destination. + derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects); + } - mReturnableObjects.clear(); - mError.clear(); - mFirstRegion = NULL; + mReturnableObjects.clear(); + mError.clear(); + mFirstRegion = NULL; - // drop reference to current selection - mObjectSelection = NULL; - return false; - } + // drop reference to current selection + mObjectSelection = NULL; + return false; + } - LLObjectSelectionHandle mObjectSelection; + LLObjectSelectionHandle mObjectSelection; - std::vector mReturnableObjects; - std::string mError; - LLViewerRegion* mFirstRegion; + std::vector mReturnableObjects; + std::string mError; + LLViewerRegion* mFirstRegion; }; @@ -5052,187 +5052,187 @@ private: // over land you own. class LLObjectEnableReturn : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - // Do not enable if nothing selected - return false; - } + bool handleEvent(const LLSD& userdata) + { + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + // Do not enable if nothing selected + return false; + } #ifdef HACKED_GODLIKE_VIEWER - bool new_value = true; + bool new_value = true; #else - bool new_value = false; - if (gAgent.isGodlike()) - { - new_value = true; - } - else - { - new_value = can_derez(DRD_RETURN_TO_OWNER); - } + bool new_value = false; + if (gAgent.isGodlike()) + { + new_value = true; + } + else + { + new_value = can_derez(DRD_RETURN_TO_OWNER); + } #endif - return new_value; - } + return new_value; + } }; void force_take_copy(void*) { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; - const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); - derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id); + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; + const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id); } void handle_take() { - // we want to use the folder this was derezzed from if it's - // available. Otherwise, derez to the normal place. - if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - return; - } - - BOOL you_own_everything = TRUE; - BOOL locked_but_takeable_object = FALSE; - LLUUID category_id; - - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if(object) - { - if(!object->permYouOwner()) - { - you_own_everything = FALSE; - } - - if(!object->permMove()) - { - locked_but_takeable_object = TRUE; - } - } - if(node->mFolderID.notNull()) - { - if(category_id.isNull()) - { - category_id = node->mFolderID; - } - else if(category_id != node->mFolderID) - { - // we have found two potential destinations. break out - // now and send to the default location. - category_id.setNull(); - break; - } - } - } - if(category_id.notNull()) - { - // there is an unambiguous destination. See if this agent has - // such a location and it is not in the trash or library - if(!gInventory.getCategory(category_id)) - { - // nope, set to NULL. - category_id.setNull(); - } - if(category_id.notNull()) - { - // check trash - const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash)) - { - category_id.setNull(); - } - - // check library - if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID())) - { - category_id.setNull(); - } - - // check inbox - const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); - if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id)) - { - category_id.setNull(); - } - } - } - if(category_id.isNull()) - { - category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); - } - LLSD payload; - payload["folder_id"] = category_id; - - LLNotification::Params params("ConfirmObjectTakeLock"); - params.payload(payload); - // MAINT-290 - // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez. - // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened - params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection())); - - if(locked_but_takeable_object || - !you_own_everything) - { - if(locked_but_takeable_object && you_own_everything) - { - params.name("ConfirmObjectTakeLock"); - } - else if(!locked_but_takeable_object && !you_own_everything) - { - params.name("ConfirmObjectTakeNoOwn"); - } - else - { - params.name("ConfirmObjectTakeLockNoOwn"); - } - - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } + // we want to use the folder this was derezzed from if it's + // available. Otherwise, derez to the normal place. + if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + return; + } + + BOOL you_own_everything = TRUE; + BOOL locked_but_takeable_object = FALSE; + LLUUID category_id; + + for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if(object) + { + if(!object->permYouOwner()) + { + you_own_everything = FALSE; + } + + if(!object->permMove()) + { + locked_but_takeable_object = TRUE; + } + } + if(node->mFolderID.notNull()) + { + if(category_id.isNull()) + { + category_id = node->mFolderID; + } + else if(category_id != node->mFolderID) + { + // we have found two potential destinations. break out + // now and send to the default location. + category_id.setNull(); + break; + } + } + } + if(category_id.notNull()) + { + // there is an unambiguous destination. See if this agent has + // such a location and it is not in the trash or library + if(!gInventory.getCategory(category_id)) + { + // nope, set to NULL. + category_id.setNull(); + } + if(category_id.notNull()) + { + // check trash + const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash)) + { + category_id.setNull(); + } + + // check library + if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID())) + { + category_id.setNull(); + } + + // check inbox + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); + if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id)) + { + category_id.setNull(); + } + } + } + if(category_id.isNull()) + { + category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + } + LLSD payload; + payload["folder_id"] = category_id; + + LLNotification::Params params("ConfirmObjectTakeLock"); + params.payload(payload); + // MAINT-290 + // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez. + // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened + params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection())); + + if(locked_but_takeable_object || + !you_own_everything) + { + if(locked_but_takeable_object && you_own_everything) + { + params.name("ConfirmObjectTakeLock"); + } + else if(!locked_but_takeable_object && !you_own_everything) + { + params.name("ConfirmObjectTakeNoOwn"); + } + else + { + params.name("ConfirmObjectTakeLockNoOwn"); + } + + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } } void handle_object_show_inspector() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - LLViewerObject* objectp = selection->getFirstRootObject(TRUE); - if (!objectp) - { - return; - } + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* objectp = selection->getFirstRootObject(TRUE); + if (!objectp) + { + return; + } - LLSD params; - params["object_id"] = objectp->getID(); - LLFloaterReg::showInstance("inspect_object", params); + LLSD params; + params["object_id"] = objectp->getID(); + LLFloaterReg::showInstance("inspect_object", params); } void handle_avatar_show_inspector() { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - LLSD params; - params["avatar_id"] = avatar->getID(); - LLFloaterReg::showInstance("inspect_avatar", params); - } + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLSD params; + params["avatar_id"] = avatar->getID(); + LLFloaterReg::showInstance("inspect_avatar", params); + } } bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if(enable_take() && (option == 0)) - { - derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID()); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if(enable_take() && (option == 0)) + { + derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID()); + } + return false; } // You can take an item when it is public and transferrable, or when @@ -5240,101 +5240,101 @@ bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelect // one item selected can be copied to inventory. BOOL enable_take() { - if (sitting_on_selection()) - { - return FALSE; - } - - for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - if (object->isAvatar()) - { - // ...don't acquire avatars - continue; - } + if (sitting_on_selection()) + { + return FALSE; + } + + for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (object->isAvatar()) + { + // ...don't acquire avatars + continue; + } #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && gAgent.isGodlike()) - { - return TRUE; - } + { + return TRUE; + } # endif - if(!object->isPermanentEnforced() && - ((node->mPermissions->allowTransferTo(gAgent.getID()) - && object->permModify()) - || (node->mPermissions->getOwner() == gAgent.getID()))) - { - return !object->isAttachment(); - } + if(!object->isPermanentEnforced() && + ((node->mPermissions->allowTransferTo(gAgent.getID()) + && object->permModify()) + || (node->mPermissions->getOwner() == gAgent.getID()))) + { + return !object->isAttachment(); + } #endif - } - return FALSE; + } + return FALSE; } void handle_buy_or_take() { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - return; - } - - if (is_selection_buy_not_take()) - { - S32 total_price = selection_price(); - - if (total_price <= gStatusBar->getBalance() || total_price == 0) - { - handle_buy(); - } - else - { - LLStringUtil::format_map_t args; - args["AMOUNT"] = llformat("%d", total_price); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price ); - } - } - else - { - handle_take(); - } + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + return; + } + + if (is_selection_buy_not_take()) + { + S32 total_price = selection_price(); + + if (total_price <= gStatusBar->getBalance() || total_price == 0) + { + handle_buy(); + } + else + { + LLStringUtil::format_map_t args; + args["AMOUNT"] = llformat("%d", total_price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price ); + } + } + else + { + handle_take(); + } } bool visible_buy_object() { - return is_selection_buy_not_take() && enable_buy_object(); + return is_selection_buy_not_take() && enable_buy_object(); } bool visible_take_object() { - return !is_selection_buy_not_take() && enable_take(); + return !is_selection_buy_not_take() && enable_take(); } bool tools_visible_buy_object() { - return is_selection_buy_not_take(); + return is_selection_buy_not_take(); } bool tools_visible_take_object() { - return !is_selection_buy_not_take(); + return !is_selection_buy_not_take(); } class LLToolsEnableBuyOrTake : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool is_buy = is_selection_buy_not_take(); - bool new_value = is_buy ? enable_buy_object() : enable_take(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool is_buy = is_selection_buy_not_take(); + bool new_value = is_buy ? enable_buy_object() : enable_take(); + return new_value; + } }; // This is a small helper function to determine if we have a buy or a @@ -5355,255 +5355,255 @@ class LLToolsEnableBuyOrTake : public view_listener_t // FALSE if selection is a 'take' BOOL is_selection_buy_not_take() { - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* obj = node->getObject(); - if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) - { - // you do not own the object and it is for sale, thus, - // it's a buy - return TRUE; - } - } - return FALSE; + for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* obj = node->getObject(); + if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) + { + // you do not own the object and it is for sale, thus, + // it's a buy + return TRUE; + } + } + return FALSE; } S32 selection_price() { - S32 total_price = 0; - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* obj = node->getObject(); - if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) - { - // you do not own the object and it is for sale. - // Add its price. - total_price += node->mSaleInfo.getSalePrice(); - } - } - - return total_price; + S32 total_price = 0; + for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* obj = node->getObject(); + if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) + { + // you do not own the object and it is for sale. + // Add its price. + total_price += node->mSaleInfo.getSalePrice(); + } + } + + return total_price; } /* bool callback_show_buy_currency(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - LL_INFOS() << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << LL_ENDL; - LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LL_INFOS() << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << LL_ENDL; + LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")); + } + return false; } */ void show_buy_currency(const char* extra) { - // Don't show currency web page for branded clients. + // Don't show currency web page for branded clients. /* - std::ostringstream mesg; - if (extra != NULL) - { - mesg << extra << "\n \n"; - } - mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?"; + std::ostringstream mesg; + if (extra != NULL) + { + mesg << extra << "\n \n"; + } + mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?"; */ - LLSD args; - if (extra != NULL) - { - args["EXTRA"] = extra; - } - LLNotificationsUtil::add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency); + LLSD args; + if (extra != NULL) + { + args["EXTRA"] = extra; + } + LLNotificationsUtil::add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency); } void handle_buy() { - if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; - LLSaleInfo sale_info; - BOOL valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); - if (!valid) return; + LLSaleInfo sale_info; + BOOL valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); + if (!valid) return; - S32 price = sale_info.getSalePrice(); - - if (price > 0 && price > gStatusBar->getBalance()) - { - LLStringUtil::format_map_t args; - args["AMOUNT"] = llformat("%d", price); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price ); - return; - } + S32 price = sale_info.getSalePrice(); - if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS) - { - handle_buy_contents(sale_info); - } - else - { - handle_buy_object(sale_info); - } + if (price > 0 && price > gStatusBar->getBalance()) + { + LLStringUtil::format_map_t args; + args["AMOUNT"] = llformat("%d", price); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price ); + return; + } + + if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS) + { + handle_buy_contents(sale_info); + } + else + { + handle_buy_object(sale_info); + } } bool anyone_copy_selection(LLSelectNode* nodep) { - bool perm_copy = (bool)(nodep->getObject()->permCopy()); - bool all_copy = (bool)(nodep->mPermissions->getMaskEveryone() & PERM_COPY); - return perm_copy && all_copy; + bool perm_copy = (bool)(nodep->getObject()->permCopy()); + bool all_copy = (bool)(nodep->mPermissions->getMaskEveryone() & PERM_COPY); + return perm_copy && all_copy; } bool for_sale_selection(LLSelectNode* nodep) { - return nodep->mSaleInfo.isForSale() - && nodep->mPermissions->getMaskOwner() & PERM_TRANSFER - && (nodep->mPermissions->getMaskOwner() & PERM_COPY - || nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY); + return nodep->mSaleInfo.isForSale() + && nodep->mPermissions->getMaskOwner() & PERM_TRANSFER + && (nodep->mPermissions->getMaskOwner() & PERM_COPY + || nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY); } BOOL sitting_on_selection() { - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if (!node) - { - return FALSE; - } + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (!node) + { + return FALSE; + } - if (!node->mValid) - { - return FALSE; - } + if (!node->mValid) + { + return FALSE; + } - LLViewerObject* root_object = node->getObject(); - if (!root_object) - { - return FALSE; - } + LLViewerObject* root_object = node->getObject(); + if (!root_object) + { + return FALSE; + } - // Need to determine if avatar is sitting on this object - if (!isAgentAvatarValid()) return FALSE; + // Need to determine if avatar is sitting on this object + if (!isAgentAvatarValid()) return FALSE; - return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object); + return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object); } class LLToolsSaveToObjectInventory : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if(node && (node->mValid) && (!node->mFromTaskID.isNull())) - { - // *TODO: check to see if the fromtaskid object exists. - derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if(node && (node->mValid) && (!node->mFromTaskID.isNull())) + { + // *TODO: check to see if the fromtaskid object exists. + derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID); + } + return true; + } }; class LLToolsEnablePathfinding : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion(); - } + bool handleEvent(const LLSD& userdata) + { + return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion(); + } }; class LLToolsEnablePathfindingView : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled(); - } + bool handleEvent(const LLSD& userdata) + { + return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled(); + } }; class LLToolsDoPathfindingRebakeRegion : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); + bool handleEvent(const LLSD& userdata) + { + bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); - if (hasPathfinding) - { - LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); - } + if (hasPathfinding) + { + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); + } - return hasPathfinding; - } + return hasPathfinding; + } }; class LLToolsEnablePathfindingRebakeRegion : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool returnValue = false; + bool handleEvent(const LLSD& userdata) + { + bool returnValue = false; if (LLNavigationBar::instanceExists()) { returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable(); } - return returnValue; - } + return returnValue; + } }; // Round the position of all root objects to the grid class LLToolsSnapObjectXY : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - F64 snap_size = (F64)gSavedSettings.getF32("GridResolution"); - - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* obj = node->getObject(); - if (obj->permModify()) - { - LLVector3d pos_global = obj->getPositionGlobal(); - F64 round_x = fmod(pos_global.mdV[VX], snap_size); - if (round_x < snap_size * 0.5) - { - // closer to round down - pos_global.mdV[VX] -= round_x; - } - else - { - // closer to round up - pos_global.mdV[VX] -= round_x; - pos_global.mdV[VX] += snap_size; - } - - F64 round_y = fmod(pos_global.mdV[VY], snap_size); - if (round_y < snap_size * 0.5) - { - pos_global.mdV[VY] -= round_y; - } - else - { - pos_global.mdV[VY] -= round_y; - pos_global.mdV[VY] += snap_size; - } - - obj->setPositionGlobal(pos_global, FALSE); - } - } - LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); - return true; - } -}; + bool handleEvent(const LLSD& userdata) + { + F64 snap_size = (F64)gSavedSettings.getF32("GridResolution"); + + for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* obj = node->getObject(); + if (obj->permModify()) + { + LLVector3d pos_global = obj->getPositionGlobal(); + F64 round_x = fmod(pos_global.mdV[VX], snap_size); + if (round_x < snap_size * 0.5) + { + // closer to round down + pos_global.mdV[VX] -= round_x; + } + else + { + // closer to round up + pos_global.mdV[VX] -= round_x; + pos_global.mdV[VX] += snap_size; + } + + F64 round_y = fmod(pos_global.mdV[VY], snap_size); + if (round_y < snap_size * 0.5) + { + pos_global.mdV[VY] -= round_y; + } + else + { + pos_global.mdV[VY] -= round_y; + pos_global.mdV[VY] += snap_size; + } + + obj->setPositionGlobal(pos_global, FALSE); + } + } + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); + return true; + } +}; // Determine if the option to cycle between linked prims is shown class LLToolsEnableSelectNextPart : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { bool new_value = (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && (gSavedSettings.getBOOL("EditLinkedParts") || LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool())); - return new_value; - } + return new_value; + } }; // Cycle selection through linked children or/and faces in selected object. @@ -5678,61 +5678,61 @@ class LLToolsSelectNextPartFace : public view_listener_t } } - S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - if (cycle_linked && object_count && restart_face_on_part) - { - LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (selected && selected->getRootEdit()) - { - LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); - children.push_front(selected->getRootEdit()); // need root in the list too - - for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter) - { - if ((*iter)->isSelected()) - { - if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include - { - to_select = *iter; - if (fwd) - { - // stop searching if going forward; repeat to get last hit if backward - break; - } - } - else if ((object_count == 1) || (ifwd || iprev)) // single selection or include - { - if (fwd || ifwd) - { - ++iter; - while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected()))) - { - ++iter; // skip sitting avatars and selected if include - } - } - else // backward - { - iter = (iter == children.begin() ? children.end() : iter); - --iter; - while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected()))) - { - --iter; // skip sitting avatars and selected if include - } - } - iter = (iter == children.end() ? children.begin() : iter); - to_select = *iter; - break; - } - } - } - } - } + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (cycle_linked && object_count && restart_face_on_part) + { + LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (selected && selected->getRootEdit()) + { + LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); + children.push_front(selected->getRootEdit()); // need root in the list too + + for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter) + { + if ((*iter)->isSelected()) + { + if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include + { + to_select = *iter; + if (fwd) + { + // stop searching if going forward; repeat to get last hit if backward + break; + } + } + else if ((object_count == 1) || (ifwd || iprev)) // single selection or include + { + if (fwd || ifwd) + { + ++iter; + while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected()))) + { + ++iter; // skip sitting avatars and selected if include + } + } + else // backward + { + iter = (iter == children.begin() ? children.end() : iter); + --iter; + while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected()))) + { + --iter; // skip sitting avatars and selected if include + } + } + iter = (iter == children.end() ? children.begin() : iter); + to_select = *iter; + break; + } + } + } + } + } if (to_select) { if (gFocusMgr.childHasKeyboardFocus(gFloaterTools)) { - gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes + gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes } if (fwd || prev) { @@ -5760,455 +5760,455 @@ class LLToolsSelectNextPartFace : public view_listener_t } return true; } - return true; - } + return true; + } }; class LLToolsStopAllAnimations : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgent.stopCurrentAnimations(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gAgent.stopCurrentAnimations(); + return true; + } }; class LLToolsReleaseKeys : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgent.forceReleaseControls(); + bool handleEvent(const LLSD& userdata) + { + gAgent.forceReleaseControls(); - return true; - } + return true; + } }; class LLToolsEnableReleaseKeys : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gAgent.anyControlGrabbed(); - } + bool handleEvent(const LLSD& userdata) + { + return gAgent.anyControlGrabbed(); + } }; class LLEditEnableCut : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut(); + return new_value; + } }; class LLEditCut : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler ) - { - LLEditMenuHandler::gEditMenuHandler->cut(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler ) + { + LLEditMenuHandler::gEditMenuHandler->cut(); + } + return true; + } }; class LLEditEnableCopy : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy(); + return new_value; + } }; class LLEditCopy : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler ) - { - LLEditMenuHandler::gEditMenuHandler->copy(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler ) + { + LLEditMenuHandler::gEditMenuHandler->copy(); + } + return true; + } }; class LLEditEnablePaste : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste(); + return new_value; + } }; class LLEditPaste : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler ) - { - LLEditMenuHandler::gEditMenuHandler->paste(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler ) + { + LLEditMenuHandler::gEditMenuHandler->paste(); + } + return true; + } }; class LLEditEnableDelete : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete(); + return new_value; + } }; class LLEditDelete : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // If a text field can do a deletion, it gets precedence over deleting - // an object in the world. - if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete()) - { - LLEditMenuHandler::gEditMenuHandler->doDelete(); - } + bool handleEvent(const LLSD& userdata) + { + // If a text field can do a deletion, it gets precedence over deleting + // an object in the world. + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete()) + { + LLEditMenuHandler::gEditMenuHandler->doDelete(); + } - // and close any pie/context menus when done - gMenuHolder->hideMenus(); + // and close any pie/context menus when done + gMenuHolder->hideMenus(); - // When deleting an object we may not actually be done - // Keep selection so we know what to delete when confirmation is needed about the delete - gMenuObject->hide(); - return true; - } + // When deleting an object we may not actually be done + // Keep selection so we know what to delete when confirmation is needed about the delete + gMenuObject->hide(); + return true; + } }; void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param) { - const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); - LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) - { - return; - } + const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) + { + return; + } - U32 index = 0; - if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) - { - return; - } + U32 index = 0; + if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) + { + return; + } - spellcheck_handler->replaceWithSuggestion(index); + spellcheck_handler->replaceWithSuggestion(index); } bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param) { - LLMenuItemGL* item = dynamic_cast(ctrl); - const LLContextMenu* menu = (item) ? dynamic_cast(item->getParent()) : NULL; - const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) - { - return false; - } + LLMenuItemGL* item = dynamic_cast(ctrl); + const LLContextMenu* menu = (item) ? dynamic_cast(item->getParent()) : NULL; + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) ) + { + return false; + } - U32 index = 0; - if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) - { - return false; - } + U32 index = 0; + if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) ) + { + return false; + } - item->setLabel(spellcheck_handler->getSuggestion(index)); - return true; + item->setLabel(spellcheck_handler->getSuggestion(index)); + return true; } void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl) { - const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); - LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) ) - { - spellcheck_handler->addToDictionary(); - } + const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) ) + { + spellcheck_handler->addToDictionary(); + } } bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl) { - const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); - const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()); + const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()); } void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl) { - const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); - LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) ) - { - spellcheck_handler->addToIgnore(); - } + const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); + LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) ) + { + spellcheck_handler->addToIgnore(); + } } bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl) { - const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); - const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; - return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()); + const LLContextMenu* menu = dynamic_cast(ctrl->getParent()); + const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast(menu->getSpawningView()) : NULL; + return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()); } bool enable_object_return() { - return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && - (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER))); + return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && + (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER))); } bool enable_object_delete() { - bool new_value = + bool new_value = #ifdef HACKED_GODLIKE_VIEWER - TRUE; + TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - (!LLGridManager::getInstance()->isInProductionGrid() + (!LLGridManager::getInstance()->isInProductionGrid() && gAgent.isGodlike()) || # endif - LLSelectMgr::getInstance()->canDoDelete(); + LLSelectMgr::getInstance()->canDoDelete(); #endif - return new_value; + return new_value; } class LLObjectsReturnPackage { public: - LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {}; - ~LLObjectsReturnPackage() - { - mObjectSelection.clear(); - mReturnableObjects.clear(); - mError.clear(); - mFirstRegion = NULL; - }; + LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {}; + ~LLObjectsReturnPackage() + { + mObjectSelection.clear(); + mReturnableObjects.clear(); + mError.clear(); + mFirstRegion = NULL; + }; - LLObjectSelectionHandle mObjectSelection; - std::vector mReturnableObjects; - std::string mError; - LLViewerRegion *mFirstRegion; + LLObjectSelectionHandle mObjectSelection; + std::vector mReturnableObjects; + std::string mError; + LLViewerRegion *mFirstRegion; }; static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response) { - if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) - { - // Ignore category ID for this derez destination. - derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects); - } + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) + { + // Ignore category ID for this derez destination. + derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects); + } - delete objectsReturnPackage; + delete objectsReturnPackage; } void handle_object_return() { - if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage(); - objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage(); + objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); - // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. - get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects); + // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. + get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects); - LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2)); - } + LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2)); + } } void handle_object_delete() { - if (LLSelectMgr::getInstance()) - { - LLSelectMgr::getInstance()->doDelete(); - } + if (LLSelectMgr::getInstance()) + { + LLSelectMgr::getInstance()->doDelete(); + } - // and close any pie/context menus when done - gMenuHolder->hideMenus(); + // and close any pie/context menus when done + gMenuHolder->hideMenus(); - // When deleting an object we may not actually be done - // Keep selection so we know what to delete when confirmation is needed about the delete - gMenuObject->hide(); - return; + // When deleting an object we may not actually be done + // Keep selection so we know what to delete when confirmation is needed about the delete + gMenuObject->hide(); + return; } void handle_force_delete(void*) { - LLSelectMgr::getInstance()->selectForceDelete(); + LLSelectMgr::getInstance()->selectForceDelete(); } class LLViewEnableJoystickFlycam : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled")); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled")); + return new_value; + } }; class LLViewEnableLastChatter : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // *TODO: add check that last chatter is in range - bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull()); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + // *TODO: add check that last chatter is in range + bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull()); + return new_value; + } }; class LLEditEnableDeselect : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect(); + return new_value; + } }; class LLEditDeselect : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler ) - { - LLEditMenuHandler::gEditMenuHandler->deselect(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler ) + { + LLEditMenuHandler::gEditMenuHandler->deselect(); + } + return true; + } }; class LLEditEnableSelectAll : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll(); + return new_value; + } }; class LLEditSelectAll : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler ) - { - LLEditMenuHandler::gEditMenuHandler->selectAll(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler ) + { + LLEditMenuHandler::gEditMenuHandler->selectAll(); + } + return true; + } }; class LLEditEnableUndo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo(); + return new_value; + } }; class LLEditUndo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() ) - { - LLEditMenuHandler::gEditMenuHandler->undo(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() ) + { + LLEditMenuHandler::gEditMenuHandler->undo(); + } + return true; + } }; class LLEditEnableRedo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo(); + return new_value; + } }; class LLEditRedo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() ) - { - LLEditMenuHandler::gEditMenuHandler->redo(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() ) + { + LLEditMenuHandler::gEditMenuHandler->redo(); + } + return true; + } }; void print_object_info(void*) { - LLSelectMgr::getInstance()->selectionDump(); + LLSelectMgr::getInstance()->selectionDump(); } void print_agent_nvpairs(void*) { - LLViewerObject *objectp; + LLViewerObject *objectp; - LL_INFOS() << "Agent Name Value Pairs" << LL_ENDL; + LL_INFOS() << "Agent Name Value Pairs" << LL_ENDL; - objectp = gObjectList.findObject(gAgentID); - if (objectp) - { - objectp->printNameValuePairs(); - } - else - { - LL_INFOS() << "Can't find agent object" << LL_ENDL; - } + objectp = gObjectList.findObject(gAgentID); + if (objectp) + { + objectp->printNameValuePairs(); + } + else + { + LL_INFOS() << "Can't find agent object" << LL_ENDL; + } - LL_INFOS() << "Camera at " << gAgentCamera.getCameraPositionGlobal() << LL_ENDL; + LL_INFOS() << "Camera at " << gAgentCamera.getCameraPositionGlobal() << LL_ENDL; } void show_debug_menus() { - // this might get called at login screen where there is no menu so only toggle it if one exists - if ( gMenuBarView ) - { - BOOL debug = gSavedSettings.getBOOL("UseDebugMenus"); - BOOL qamode = gSavedSettings.getBOOL("QAMode"); - - gMenuBarView->setItemVisible("Advanced", debug); -// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden - - gMenuBarView->setItemVisible("Debug", qamode); - gMenuBarView->setItemEnabled("Debug", qamode); - - gMenuBarView->setItemVisible("Develop", qamode); - gMenuBarView->setItemEnabled("Develop", qamode); - - // Server ('Admin') menu hidden when not in godmode. - const bool show_server_menu = (gAgent.getGodLevel() > GOD_NOT || (debug && gAgent.getAdminOverride())); - gMenuBarView->setItemVisible("Admin", show_server_menu); - gMenuBarView->setItemEnabled("Admin", show_server_menu); - } - if (gLoginMenuBarView) - { - BOOL debug = gSavedSettings.getBOOL("UseDebugMenus"); - gLoginMenuBarView->setItemVisible("Debug", debug); - gLoginMenuBarView->setItemEnabled("Debug", debug); - } + // this might get called at login screen where there is no menu so only toggle it if one exists + if ( gMenuBarView ) + { + BOOL debug = gSavedSettings.getBOOL("UseDebugMenus"); + BOOL qamode = gSavedSettings.getBOOL("QAMode"); + + gMenuBarView->setItemVisible("Advanced", debug); +// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden + + gMenuBarView->setItemVisible("Debug", qamode); + gMenuBarView->setItemEnabled("Debug", qamode); + + gMenuBarView->setItemVisible("Develop", qamode); + gMenuBarView->setItemEnabled("Develop", qamode); + + // Server ('Admin') menu hidden when not in godmode. + const bool show_server_menu = (gAgent.getGodLevel() > GOD_NOT || (debug && gAgent.getAdminOverride())); + gMenuBarView->setItemVisible("Admin", show_server_menu); + gMenuBarView->setItemEnabled("Admin", show_server_menu); + } + if (gLoginMenuBarView) + { + BOOL debug = gSavedSettings.getBOOL("UseDebugMenus"); + gLoginMenuBarView->setItemVisible("Debug", debug); + gLoginMenuBarView->setItemEnabled("Debug", debug); + } } void toggle_debug_menus(void*) { - BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus"); - gSavedSettings.setBOOL("UseDebugMenus", visible); - show_debug_menus(); + BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus"); + gSavedSettings.setBOOL("UseDebugMenus", visible); + show_debug_menus(); } @@ -6219,299 +6219,299 @@ void toggle_debug_menus(void*) // void handle_export_selected( void * ) // { -// LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); -// if (selection->isEmpty()) -// { -// return; -// } -// LL_INFOS() << "Exporting selected objects:" << LL_ENDL; - -// gExporterRequestID.generate(); -// gExportDirectory = ""; - -// LLMessageSystem* msg = gMessageSystem; -// msg->newMessageFast(_PREHASH_ObjectExportSelected); -// msg->nextBlockFast(_PREHASH_AgentData); -// msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -// msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID); -// msg->addS16Fast(_PREHASH_VolumeDetail, 4); - -// for (LLObjectSelection::root_iterator iter = selection->root_begin(); -// iter != selection->root_end(); iter++) -// { -// LLSelectNode* node = *iter; -// LLViewerObject* object = node->getObject(); -// msg->nextBlockFast(_PREHASH_ObjectData); -// msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); -// LL_INFOS() << "Object: " << object->getID() << LL_ENDL; -// } -// msg->sendReliable(gAgent.getRegion()->getHost()); - -// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects..."); +// LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); +// if (selection->isEmpty()) +// { +// return; +// } +// LL_INFOS() << "Exporting selected objects:" << LL_ENDL; + +// gExporterRequestID.generate(); +// gExportDirectory = ""; + +// LLMessageSystem* msg = gMessageSystem; +// msg->newMessageFast(_PREHASH_ObjectExportSelected); +// msg->nextBlockFast(_PREHASH_AgentData); +// msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +// msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID); +// msg->addS16Fast(_PREHASH_VolumeDetail, 4); + +// for (LLObjectSelection::root_iterator iter = selection->root_begin(); +// iter != selection->root_end(); iter++) +// { +// LLSelectNode* node = *iter; +// LLViewerObject* object = node->getObject(); +// msg->nextBlockFast(_PREHASH_ObjectData); +// msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); +// LL_INFOS() << "Object: " << object->getID() << LL_ENDL; +// } +// msg->sendReliable(gAgent.getRegion()->getHost()); + +// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects..."); // } // class LLCommunicateNearbyChat : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance(); + bool handleEvent(const LLSD& userdata) + { + LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance(); LLFloaterIMNearbyChat* floater_nearby = LLFloaterReg::getTypedInstance("nearby_chat"); - if (floater_nearby->isInVisibleChain() && !floater_nearby->isTornOff() + if (floater_nearby->isInVisibleChain() && !floater_nearby->isTornOff() && im_box->getSelectedSession() == LLUUID() && im_box->getConversationListItemSize() > 1) - { - im_box->selectNextorPreviousConversation(false); - } - else - { - LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat"); - } - return true; - } + { + im_box->selectNextorPreviousConversation(false); + } + else + { + LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat"); + } + return true; + } }; class LLWorldSetHomeLocation : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // we just send the message and let the server check for failure cases - // server will echo back a "Home position set." alert if it succeeds - // and the home location screencapture happens when that alert is recieved - gAgent.setStartPosition(START_LOCATION_ID_HOME); - return true; - } + bool handleEvent(const LLSD& userdata) + { + // we just send the message and let the server check for failure cases + // server will echo back a "Home position set." alert if it succeeds + // and the home location screencapture happens when that alert is recieved + gAgent.setStartPosition(START_LOCATION_ID_HOME); + return true; + } }; class LLWorldLindenHome : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url"); - LLWeb::loadURL(url); - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url"); + LLWeb::loadURL(url); + return true; + } }; class LLWorldTeleportHome : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gAgent.teleportHome(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gAgent.teleportHome(); + return true; + } }; class LLWorldAlwaysRun : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // as well as altering the default walk-vs-run state, - // we also change the *current* walk-vs-run state. - if (gAgent.getAlwaysRun()) - { - gAgent.clearAlwaysRun(); - gAgent.clearRunning(); - } - else - { - gAgent.setAlwaysRun(); - gAgent.setRunning(); - } + bool handleEvent(const LLSD& userdata) + { + // as well as altering the default walk-vs-run state, + // we also change the *current* walk-vs-run state. + if (gAgent.getAlwaysRun()) + { + gAgent.clearAlwaysRun(); + gAgent.clearRunning(); + } + else + { + gAgent.setAlwaysRun(); + gAgent.setRunning(); + } - // tell the simulator. - gAgent.sendWalkRun(gAgent.getAlwaysRun()); + // tell the simulator. + gAgent.sendWalkRun(gAgent.getAlwaysRun()); - // Update Movement Controls according to AlwaysRun mode - LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun()); + // Update Movement Controls according to AlwaysRun mode + LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun()); - return true; - } + return true; + } }; class LLWorldCheckAlwaysRun : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gAgent.getAlwaysRun(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gAgent.getAlwaysRun(); + return new_value; + } }; class LLWorldSetAway : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgent.getAFK()) - { - gAgent.clearAFK(); - } - else - { - gAgent.setAFK(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgent.getAFK()) + { + gAgent.clearAFK(); + } + else + { + gAgent.setAFK(); + } + return true; + } }; class LLWorldSetDoNotDisturb : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgent.isDoNotDisturb()) - { - gAgent.setDoNotDisturb(false); - } - else - { - gAgent.setDoNotDisturb(true); - LLNotificationsUtil::add("DoNotDisturbModeSet"); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgent.isDoNotDisturb()) + { + gAgent.setDoNotDisturb(false); + } + else + { + gAgent.setDoNotDisturb(true); + LLNotificationsUtil::add("DoNotDisturbModeSet"); + } + return true; + } }; class LLWorldCreateLandmark : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::showInstance("add_landmark"); + bool handleEvent(const LLSD& userdata) + { + LLFloaterReg::showInstance("add_landmark"); - return true; - } + return true; + } }; class LLWorldPlaceProfile : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent")); + bool handleEvent(const LLSD& userdata) + { + LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent")); - return true; - } + return true; + } }; void handle_look_at_selection(const LLSD& param) { - const F32 PADDING_FACTOR = 1.75f; - BOOL zoom = (param.asString() == "zoom"); - if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - - LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); - F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); - - LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent(); - obj_to_cam.normVec(); - - LLUUID object_id; - if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) - { - object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; - } - if (zoom) - { - // Make sure we are not increasing the distance between the camera and object - LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal(); - distance = llmin(distance, (F32) orig_distance.length()); - - gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), - LLSelectMgr::getInstance()->getSelectionCenterGlobal(), - object_id ); - - } - else - { - gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); - } - } + const F32 PADDING_FACTOR = 1.75f; + BOOL zoom = (param.asString() == "zoom"); + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + + LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); + F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); + + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent(); + obj_to_cam.normVec(); + + LLUUID object_id; + if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) + { + object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; + } + if (zoom) + { + // Make sure we are not increasing the distance between the camera and object + LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal(); + distance = llmin(distance, (F32) orig_distance.length()); + + gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), + LLSelectMgr::getInstance()->getSelectionCenterGlobal(), + object_id ); + + } + else + { + gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); + } + } } void handle_zoom_to_object(LLUUID object_id) { - const F32 PADDING_FACTOR = 2.f; + const F32 PADDING_FACTOR = 2.f; - LLViewerObject* object = gObjectList.findObject(object_id); + LLViewerObject* object = gObjectList.findObject(object_id); - if (object) - { - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + if (object) + { + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - LLBBox bbox = object->getBoundingBoxAgent() ; - F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); - F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); + LLBBox bbox = object->getBoundingBoxAgent() ; + F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); + F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); - LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent(); - obj_to_cam.normVec(); + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent(); + obj_to_cam.normVec(); - LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); + LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); - gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), - object_center_global, - object_id ); - } + gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), + object_center_global, + object_id ); + } } class LLAvatarInviteToGroup : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - LLAvatarActions::inviteToGroup(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLAvatarActions::inviteToGroup(avatar->getID()); + } + return true; + } }; class LLAvatarAddFriend : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar && !LLAvatarActions::isFriend(avatar->getID())) - { - request_friendship(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar && !LLAvatarActions::isFriend(avatar->getID())) + { + request_friendship(avatar->getID()); + } + return true; + } }; class LLAvatarToggleMyProfile : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID()); - if (LLFloater::isMinimized(instance)) - { - instance->setMinimized(FALSE); - instance->setFocus(TRUE); - } - else if (!LLFloater::isShown(instance)) - { - LLAvatarActions::showProfile(gAgent.getID()); - } - else if (!instance->hasFocus() && !instance->getIsChrome()) - { - instance->setFocus(TRUE); - } - else - { - instance->closeFloater(); - } - return true; - } -}; - -class LLAvatarTogglePicks : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID()); + LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID()); + if (LLFloater::isMinimized(instance)) + { + instance->setMinimized(FALSE); + instance->setFocus(TRUE); + } + else if (!LLFloater::isShown(instance)) + { + LLAvatarActions::showProfile(gAgent.getID()); + } + else if (!instance->hasFocus() && !instance->getIsChrome()) + { + instance->setFocus(TRUE); + } + else + { + instance->closeFloater(); + } + return true; + } +}; + +class LLAvatarTogglePicks : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID()); if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome())) { instance->setMinimized(FALSE); @@ -6532,41 +6532,41 @@ class LLAvatarTogglePicks : public view_listener_t class LLAvatarToggleSearch : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloater* instance = LLFloaterReg::findInstance("search"); - if (LLFloater::isMinimized(instance)) - { - instance->setMinimized(FALSE); - instance->setFocus(TRUE); - } - else if (!LLFloater::isShown(instance)) - { - LLFloaterReg::showInstance("search"); - } - else if (!instance->hasFocus() && !instance->getIsChrome()) - { - instance->setFocus(TRUE); - } - else - { - instance->closeFloater(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloater* instance = LLFloaterReg::findInstance("search"); + if (LLFloater::isMinimized(instance)) + { + instance->setMinimized(FALSE); + instance->setFocus(TRUE); + } + else if (!LLFloater::isShown(instance)) + { + LLFloaterReg::showInstance("search"); + } + else if (!instance->hasFocus() && !instance->getIsChrome()) + { + instance->setFocus(TRUE); + } + else + { + instance->closeFloater(); + } + return true; + } }; class LLAvatarResetSkeleton: public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = NULL; + LLVOAvatar* avatar = NULL; LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (obj) { avatar = obj->getAvatar(); } - if(avatar) + if(avatar) { avatar->resetSkeleton(false); } @@ -6590,184 +6590,184 @@ class LLAvatarEnableResetSkeleton: public view_listener_t class LLAvatarResetSkeletonAndAnimations : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - if (avatar) - { - avatar->resetSkeleton(true); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + if (avatar) + { + avatar->resetSkeleton(true); + } + return true; + } }; class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - if (avatar) - { - avatar->resetSkeleton(true); - } - else - { - gAgentAvatarp->resetSkeleton(true); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + if (avatar) + { + avatar->resetSkeleton(true); + } + else + { + gAgentAvatarp->resetSkeleton(true); + } + return true; + } }; class LLAvatarAddContact : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - create_inventory_callingcard(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + create_inventory_callingcard(avatar->getID()); + } + return true; + } }; bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - gAgent.setDoNotDisturb(false); - } - - LLViewerObject* objectp = selection->getPrimaryObject(); - - // Show avatar's name if paying attachment - if (objectp && objectp->isAttachment()) - { - while (objectp && !objectp->isAvatar()) - { - objectp = (LLViewerObject*)objectp->getParent(); - } - } - - if (objectp) - { - if (objectp->isAvatar()) - { - const bool is_group = false; - LLFloaterPayUtil::payDirectly(&give_money, - objectp->getID(), - is_group); - } - else - { - LLFloaterPayUtil::payViaObject(&give_money, selection); - } - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + gAgent.setDoNotDisturb(false); + } + + LLViewerObject* objectp = selection->getPrimaryObject(); + + // Show avatar's name if paying attachment + if (objectp && objectp->isAttachment()) + { + while (objectp && !objectp->isAvatar()) + { + objectp = (LLViewerObject*)objectp->getParent(); + } + } + + if (objectp) + { + if (objectp->isAvatar()) + { + const bool is_group = false; + LLFloaterPayUtil::payDirectly(&give_money, + objectp->getID(), + is_group); + } + else + { + LLFloaterPayUtil::payViaObject(&give_money, selection); + } + } + return false; } void handle_give_money_dialog() { - LLNotification::Params params("DoNotDisturbModePay"); - params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection())); + LLNotification::Params params("DoNotDisturbModePay"); + params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection())); - if (gAgent.isDoNotDisturb()) - { - // warn users of being in do not disturb mode during a transaction - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 1); - } + if (gAgent.isDoNotDisturb()) + { + // warn users of being in do not disturb mode during a transaction + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 1); + } } bool enable_pay_avatar() { - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - LLVOAvatar* avatar = find_avatar_from_object(obj); - return (avatar != NULL); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLVOAvatar* avatar = find_avatar_from_object(obj); + return (avatar != NULL); } bool enable_pay_object() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if( object ) - { - LLViewerObject *parent = (LLViewerObject *)object->getParent(); - if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney())) - { - return true; - } - } - return false; + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if( object ) + { + LLViewerObject *parent = (LLViewerObject *)object->getParent(); + if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney())) + { + return true; + } + } + return false; } bool enable_object_stand_up() { - // 'Object Stand Up' menu item is enabled when agent is sitting on selection - return sitting_on_selection(); + // 'Object Stand Up' menu item is enabled when agent is sitting on selection + return sitting_on_selection(); } bool enable_object_sit(LLUICtrl* ctrl) { - // 'Object Sit' menu item is enabled when agent is not sitting on selection - bool sitting_on_sel = sitting_on_selection(); - if (!sitting_on_sel) - { - // init default labels - init_default_item_label(ctrl); - - // Update label - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if (node && node->mValid && !node->mSitName.empty()) - { - ctrl->setValue(node->mSitName); - } - else - { - ctrl->setValue(get_default_item_label(ctrl->getName())); - } - } - return !sitting_on_sel && is_object_sittable(); + // 'Object Sit' menu item is enabled when agent is not sitting on selection + bool sitting_on_sel = sitting_on_selection(); + if (!sitting_on_sel) + { + // init default labels + init_default_item_label(ctrl); + + // Update label + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (node && node->mValid && !node->mSitName.empty()) + { + ctrl->setValue(node->mSitName); + } + else + { + ctrl->setValue(get_default_item_label(ctrl->getName())); + } + } + return !sitting_on_sel && is_object_sittable(); } void dump_select_mgr(void*) { - LLSelectMgr::getInstance()->dump(); + LLSelectMgr::getInstance()->dump(); } void dump_inventory(void*) { - gInventory.dumpInventory(); + gInventory.dumpInventory(); } void handle_dump_followcam(void*) { - LLFollowCamMgr::getInstance()->dump(); + LLFollowCamMgr::getInstance()->dump(); } void handle_viewer_enable_message_log(void*) { - gMessageSystem->startLogging(); + gMessageSystem->startLogging(); } void handle_viewer_disable_message_log(void*) { - gMessageSystem->stopLogging(); + gMessageSystem->stopLogging(); } void handle_customize_avatar() { - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); } void handle_edit_outfit() { - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); } void handle_now_wearing() @@ -6784,225 +6784,225 @@ void handle_now_wearing() void handle_edit_shape() { - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape")); + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape")); } void handle_hover_height() { - LLFloaterReg::showInstance("edit_hover_height"); + LLFloaterReg::showInstance("edit_hover_height"); } void handle_edit_physics() { - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics")); + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics")); } void handle_report_abuse() { - // Prevent menu from appearing in screen shot. - gMenuHolder->hideMenus(); - LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); + // Prevent menu from appearing in screen shot. + gMenuHolder->hideMenus(); + LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); } void handle_buy_currency() { - LLBuyCurrencyHTML::openCurrencyFloater(); + LLBuyCurrencyHTML::openCurrencyFloater(); } class LLFloaterVisible : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string floater_name = userdata.asString(); - bool new_value = false; - { - new_value = LLFloaterReg::instanceVisible(floater_name); - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + std::string floater_name = userdata.asString(); + bool new_value = false; + { + new_value = LLFloaterReg::instanceVisible(floater_name); + } + return new_value; + } }; class LLShowHelp : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string help_topic = userdata.asString(); - LLViewerHelp* vhelp = LLViewerHelp::getInstance(); - vhelp->showTopic(help_topic); - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string help_topic = userdata.asString(); + LLViewerHelp* vhelp = LLViewerHelp::getInstance(); + vhelp->showTopic(help_topic); + return true; + } }; class LLToggleHelp : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloater* help_browser = (LLFloaterReg::findInstance("help_browser")); - if (help_browser && help_browser->isInVisibleChain()) - { - help_browser->closeFloater(); - } - else - { - std::string help_topic = userdata.asString(); - LLViewerHelp* vhelp = LLViewerHelp::getInstance(); - vhelp->showTopic(help_topic); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloater* help_browser = (LLFloaterReg::findInstance("help_browser")); + if (help_browser && help_browser->isInVisibleChain()) + { + help_browser->closeFloater(); + } + else + { + std::string help_topic = userdata.asString(); + LLViewerHelp* vhelp = LLViewerHelp::getInstance(); + vhelp->showTopic(help_topic); + } + return true; + } }; class LLToggleSpeak : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVoiceClient::getInstance()->toggleUserPTTState(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVoiceClient::getInstance()->toggleUserPTTState(); + return true; + } }; class LLShowSidetrayPanel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string floater_name = userdata.asString(); - - LLPanel* panel = LLFloaterSidePanelContainer::getPanel(floater_name); - if (panel) - { - if (panel->isInVisibleChain()) - { - LLFloaterReg::getInstance(floater_name)->closeFloater(); - } - else - { - LLFloaterReg::getInstance(floater_name)->openFloater(); - } - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string floater_name = userdata.asString(); + + LLPanel* panel = LLFloaterSidePanelContainer::getPanel(floater_name); + if (panel) + { + if (panel->isInVisibleChain()) + { + LLFloaterReg::getInstance(floater_name)->closeFloater(); + } + else + { + LLFloaterReg::getInstance(floater_name)->openFloater(); + } + } + return true; + } }; class LLSidetrayPanelVisible : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string floater_name = userdata.asString(); - // Toggle the panel - if (LLFloaterReg::getInstance(floater_name)->isInVisibleChain()) - { - return true; - } - else - { - return false; - } - - } + bool handleEvent(const LLSD& userdata) + { + std::string floater_name = userdata.asString(); + // Toggle the panel + if (LLFloaterReg::getInstance(floater_name)->isInVisibleChain()) + { + return true; + } + else + { + return false; + } + + } }; bool callback_show_url(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - LLWeb::loadURL(notification["payload"]["url"].asString()); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LLWeb::loadURL(notification["payload"]["url"].asString()); + } + return false; } class LLPromptShowURL : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string param = userdata.asString(); - std::string::size_type offset = param.find(","); - if (offset != param.npos) - { - std::string alert = param.substr(0, offset); - std::string url = param.substr(offset+1); - - if (LLWeb::useExternalBrowser(url)) - { - LLSD payload; - payload["url"] = url; - LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url); - } - else - { - LLWeb::loadURL(url); - } - } - else - { - LL_INFOS() << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << LL_ENDL; - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string param = userdata.asString(); + std::string::size_type offset = param.find(","); + if (offset != param.npos) + { + std::string alert = param.substr(0, offset); + std::string url = param.substr(offset+1); + + if (LLWeb::useExternalBrowser(url)) + { + LLSD payload; + payload["url"] = url; + LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url); + } + else + { + LLWeb::loadURL(url); + } + } + else + { + LL_INFOS() << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << LL_ENDL; + } + return true; + } }; bool callback_show_file(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - LLWeb::loadURL(notification["payload"]["url"]); - } - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LLWeb::loadURL(notification["payload"]["url"]); + } + return false; } class LLPromptShowFile : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string param = userdata.asString(); - std::string::size_type offset = param.find(","); - if (offset != param.npos) - { - std::string alert = param.substr(0, offset); - std::string file = param.substr(offset+1); - - LLSD payload; - payload["url"] = file; - LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_file); - } - else - { - LL_INFOS() << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << LL_ENDL; - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string param = userdata.asString(); + std::string::size_type offset = param.find(","); + if (offset != param.npos) + { + std::string alert = param.substr(0, offset); + std::string file = param.substr(offset+1); + + LLSD payload; + payload["url"] = file; + LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_file); + } + else + { + LL_INFOS() << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << LL_ENDL; + } + return true; + } }; class LLShowAgentProfile : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLUUID agent_id; - if (userdata.asString() == "agent") - { - agent_id = gAgent.getID(); - } - else if (userdata.asString() == "hit object") - { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (objectp) - { - agent_id = objectp->getID(); - } - } - else - { - agent_id = userdata.asUUID(); - } - - LLVOAvatar* avatar = find_avatar_from_object(agent_id); - if (avatar) - { - LLAvatarActions::showProfile(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLUUID agent_id; + if (userdata.asString() == "agent") + { + agent_id = gAgent.getID(); + } + else if (userdata.asString() == "hit object") + { + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (objectp) + { + agent_id = objectp->getID(); + } + } + else + { + agent_id = userdata.asUUID(); + } + + LLVOAvatar* avatar = find_avatar_from_object(agent_id); + if (avatar) + { + LLAvatarActions::showProfile(avatar->getID()); + } + return true; + } }; class LLShowAgentProfilePicks : public view_listener_t @@ -7016,164 +7016,164 @@ class LLShowAgentProfilePicks : public view_listener_t class LLToggleAgentProfile : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLUUID agent_id; - if (userdata.asString() == "agent") - { - agent_id = gAgent.getID(); - } - else if (userdata.asString() == "hit object") - { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (objectp) - { - agent_id = objectp->getID(); - } - } - else - { - agent_id = userdata.asUUID(); - } - - LLVOAvatar* avatar = find_avatar_from_object(agent_id); - if (avatar) - { - if (!LLAvatarActions::profileVisible(avatar->getID())) - { - LLAvatarActions::showProfile(avatar->getID()); - } - else - { - LLAvatarActions::hideProfile(avatar->getID()); - } - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLUUID agent_id; + if (userdata.asString() == "agent") + { + agent_id = gAgent.getID(); + } + else if (userdata.asString() == "hit object") + { + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (objectp) + { + agent_id = objectp->getID(); + } + } + else + { + agent_id = userdata.asUUID(); + } + + LLVOAvatar* avatar = find_avatar_from_object(agent_id); + if (avatar) + { + if (!LLAvatarActions::profileVisible(avatar->getID())) + { + LLAvatarActions::showProfile(avatar->getID()); + } + else + { + LLAvatarActions::hideProfile(avatar->getID()); + } + } + return true; + } }; class LLLandEdit : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) - { - // zoom in if we're looking at the avatar - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gAgentCamera.cameraOrbitOver( F_PI * 0.25f ); - gViewerWindow->moveCursorToCenter(); - } - else if ( gSavedSettings.getBOOL("EditCameraMovement") ) - { - gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gViewerWindow->moveCursorToCenter(); - } + gAgentCamera.cameraOrbitOver( F_PI * 0.25f ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gViewerWindow->moveCursorToCenter(); + } - LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal ); + LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal ); - LLFloaterReg::showInstance("build"); + LLFloaterReg::showInstance("build"); - // Switch to land edit toolset - LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() ); - return true; - } + // Switch to land edit toolset + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() ); + return true; + } }; class LLMuteParticle : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID; - - if (id.notNull()) - { - LLAvatarName av_name; - LLAvatarNameCache::get(id, &av_name); - - LLMute mute(id, av_name.getUserName(), LLMute::AGENT); - if (LLMuteList::getInstance()->isMuted(mute.mID)) - { - LLMuteList::getInstance()->remove(mute); - } - else - { - LLMuteList::getInstance()->add(mute); - LLPanelBlockedList::showPanelAndSelect(mute.mID); - } - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID; + + if (id.notNull()) + { + LLAvatarName av_name; + LLAvatarNameCache::get(id, &av_name); + + LLMute mute(id, av_name.getUserName(), LLMute::AGENT); + if (LLMuteList::getInstance()->isMuted(mute.mID)) + { + LLMuteList::getInstance()->remove(mute); + } + else + { + LLMuteList::getInstance()->add(mute); + LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + } + + return true; + } }; class LLWorldEnableBuyLand : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel( - LLViewerParcelMgr::getInstance()->selectionEmpty() - ? LLViewerParcelMgr::getInstance()->getAgentParcel() - : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), - false); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel( + LLViewerParcelMgr::getInstance()->selectionEmpty() + ? LLViewerParcelMgr::getInstance()->getAgentParcel() + : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), + false); + return new_value; + } }; BOOL enable_buy_land(void*) { - return LLViewerParcelMgr::getInstance()->canAgentBuyParcel( - LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false); + return LLViewerParcelMgr::getInstance()->canAgentBuyParcel( + LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false); } void handle_buy_land() { - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); - if (vpm->selectionEmpty()) - { - vpm->selectParcelAt(gAgent.getPositionGlobal()); - } - vpm->startBuyLand(); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); + if (vpm->selectionEmpty()) + { + vpm->selectParcelAt(gAgent.getPositionGlobal()); + } + vpm->startBuyLand(); } class LLObjectAttachToAvatar : public view_listener_t { public: - LLObjectAttachToAvatar(bool replace) : mReplace(replace) {} - static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; } + LLObjectAttachToAvatar(bool replace) : mReplace(replace) {} + static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; } private: - bool handleEvent(const LLSD& userdata) - { - setObjectSelection(LLSelectMgr::getInstance()->getSelection()); - LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject(); - if (selectedObject) - { - S32 index = userdata.asInteger(); - LLViewerJointAttachment* attachment_point = NULL; - if (index > 0) - attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); - confirmReplaceAttachment(0, attachment_point); - } - return true; - } - - static void onNearAttachObject(BOOL success, void *user_data); - void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point); - class CallbackData : public LLSelectionCallbackData - { - public: - CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {} - - LLViewerJointAttachment* mAttachmentPoint; - bool mReplace; - }; + bool handleEvent(const LLSD& userdata) + { + setObjectSelection(LLSelectMgr::getInstance()->getSelection()); + LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject(); + if (selectedObject) + { + S32 index = userdata.asInteger(); + LLViewerJointAttachment* attachment_point = NULL; + if (index > 0) + attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); + confirmReplaceAttachment(0, attachment_point); + } + return true; + } + + static void onNearAttachObject(BOOL success, void *user_data); + void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point); + class CallbackData : public LLSelectionCallbackData + { + public: + CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {} + + LLViewerJointAttachment* mAttachmentPoint; + bool mReplace; + }; protected: - static LLObjectSelectionHandle sObjectSelection; - bool mReplace; + static LLObjectSelectionHandle sObjectSelection; + bool mReplace; }; LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection; @@ -7181,238 +7181,238 @@ LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection; // static void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data) { - if (!user_data) return; - CallbackData* cb_data = static_cast(user_data); - - if (success) - { - const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint; - - U8 attachment_id = 0; - if (attachment) - { - for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) - { - if (iter->second == attachment) - { - attachment_id = iter->first; - break; - } - } - } - else - { - // interpret 0 as "default location" - attachment_id = 0; - } - LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace); - } - LLObjectAttachToAvatar::setObjectSelection(NULL); - - delete cb_data; + if (!user_data) return; + CallbackData* cb_data = static_cast(user_data); + + if (success) + { + const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint; + + U8 attachment_id = 0; + if (attachment) + { + for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) + { + if (iter->second == attachment) + { + attachment_id = iter->first; + break; + } + } + } + else + { + // interpret 0 as "default location" + attachment_id = 0; + } + LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace); + } + LLObjectAttachToAvatar::setObjectSelection(NULL); + + delete cb_data; } // static void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point) { - if (option == 0/*YES*/) - { - LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); - if (selectedObject) - { - const F32 MIN_STOP_DISTANCE = 1.f; // meters - const F32 ARM_LENGTH = 0.5f; // meters - const F32 SCALE_FUDGE = 1.5f; - - F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH; - if (stop_distance < MIN_STOP_DISTANCE) - { - stop_distance = MIN_STOP_DISTANCE; - } - - LLVector3 walkToSpot = selectedObject->getPositionAgent(); - - // make sure we stop in front of the object - LLVector3 delta = walkToSpot - gAgent.getPositionAgent(); - delta.normVec(); - delta = delta * 0.5f; - walkToSpot -= delta; - - // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak. - CallbackData* user_data = new CallbackData(attachment_point, mReplace); - gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance); - gAgentCamera.clearFocusObject(); - } - } + if (option == 0/*YES*/) + { + LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); + if (selectedObject) + { + const F32 MIN_STOP_DISTANCE = 1.f; // meters + const F32 ARM_LENGTH = 0.5f; // meters + const F32 SCALE_FUDGE = 1.5f; + + F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH; + if (stop_distance < MIN_STOP_DISTANCE) + { + stop_distance = MIN_STOP_DISTANCE; + } + + LLVector3 walkToSpot = selectedObject->getPositionAgent(); + + // make sure we stop in front of the object + LLVector3 delta = walkToSpot - gAgent.getPositionAgent(); + delta.normVec(); + delta = delta * 0.5f; + walkToSpot -= delta; + + // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak. + CallbackData* user_data = new CallbackData(attachment_point, mReplace); + gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance); + gAgentCamera.clearFocusObject(); + } + } } void callback_attachment_drop(const LLSD& notification, const LLSD& response) { - // Ensure user confirmed the drop - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; - - // Called when the user clicked on an object attached to them - // and selected "Drop". - LLUUID object_id = notification["payload"]["object_id"].asUUID(); - LLViewerObject *object = gObjectList.findObject(object_id); - - if (!object) - { - LL_WARNS() << "handle_drop_attachment() - no object to drop" << LL_ENDL; - return; - } - - LLViewerObject *parent = (LLViewerObject*)object->getParent(); - while (parent) - { - if(parent->isAvatar()) - { - break; - } - object = parent; - parent = (LLViewerObject*)parent->getParent(); - } - - if (!object) - { - LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; - return; - } - - if (object->isAvatar()) - { - LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; - return; - } - - // reselect the object - LLSelectMgr::getInstance()->selectObjectAndFamily(object); - - LLSelectMgr::getInstance()->sendDropAttachment(); - - return; + // Ensure user confirmed the drop + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; + + // Called when the user clicked on an object attached to them + // and selected "Drop". + LLUUID object_id = notification["payload"]["object_id"].asUUID(); + LLViewerObject *object = gObjectList.findObject(object_id); + + if (!object) + { + LL_WARNS() << "handle_drop_attachment() - no object to drop" << LL_ENDL; + return; + } + + LLViewerObject *parent = (LLViewerObject*)object->getParent(); + while (parent) + { + if(parent->isAvatar()) + { + break; + } + object = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + if (!object) + { + LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; + return; + } + + if (object->isAvatar()) + { + LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; + return; + } + + // reselect the object + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + + LLSelectMgr::getInstance()->sendDropAttachment(); + + return; } class LLAttachmentDrop : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLSD payload; - LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + bool handleEvent(const LLSD& userdata) + { + LLSD payload; + LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (object) - { - payload["object_id"] = object->getID(); - } - else - { - LL_WARNS() << "Drop object not found" << LL_ENDL; - return true; - } + if (object) + { + payload["object_id"] = object->getID(); + } + else + { + LL_WARNS() << "Drop object not found" << LL_ENDL; + return true; + } - LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop); - return true; - } + LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop); + return true; + } }; // called from avatar pie menu class LLAttachmentDetachFromPoint : public view_listener_t { - bool handleEvent(const LLSD& user_data) - { - uuid_vec_t ids_to_remove; - const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL); - if (attachment->getNumObjects() > 0) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin(); - iter != attachment->mAttachedObjects.end(); - iter++) - { - LLViewerObject *attached_object = iter->get(); - ids_to_remove.push_back(attached_object->getAttachmentItemID()); - } - } - if (!ids_to_remove.empty()) - { - LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove); - } - return true; - } + bool handleEvent(const LLSD& user_data) + { + uuid_vec_t ids_to_remove; + const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL); + if (attachment->getNumObjects() > 0) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin(); + iter != attachment->mAttachedObjects.end(); + iter++) + { + LLViewerObject *attached_object = iter->get(); + ids_to_remove.push_back(attached_object->getAttachmentItemID()); + } + } + if (!ids_to_remove.empty()) + { + LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove); + } + return true; + } }; static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data) { - std::string label; - LLMenuItemGL* menu = dynamic_cast(ctrl); - if (menu) - { - const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL); - if (attachment) - { - label = data["label"].asString(); - for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = attachment_iter->get(); - if (attached_object) - { - LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); - if (itemp) - { - label += std::string(" (") + itemp->getName() + std::string(")"); - break; - } - } - } - } - menu->setLabel(label); - } - return true; + std::string label; + LLMenuItemGL* menu = dynamic_cast(ctrl); + if (menu) + { + const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL); + if (attachment) + { + label = data["label"].asString(); + for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object) + { + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); + if (itemp) + { + label += std::string(" (") + itemp->getName() + std::string(")"); + break; + } + } + } + } + menu->setLabel(label); + } + return true; } class LLAttachmentDetach : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // Called when the user clicked on an object attached to them - // and selected "Detach". - LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) - { - LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; - return true; - } - - LLViewerObject *parent = (LLViewerObject*)object->getParent(); - while (parent) - { - if(parent->isAvatar()) - { - break; - } - object = parent; - parent = (LLViewerObject*)parent->getParent(); - } - - if (!object) - { - LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; - return true; - } - - if (object->isAvatar()) - { - LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; - return true; - } - - LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID()); - - return true; - } + bool handleEvent(const LLSD& userdata) + { + // Called when the user clicked on an object attached to them + // and selected "Detach". + LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) + { + LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; + return true; + } + + LLViewerObject *parent = (LLViewerObject*)object->getParent(); + while (parent) + { + if(parent->isAvatar()) + { + break; + } + object = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + if (!object) + { + LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; + return true; + } + + if (object->isAvatar()) + { + LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; + return true; + } + + LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID()); + + return true; + } }; //Adding an observer for a Jira 2422 and needs to be a fetch observer @@ -7420,468 +7420,468 @@ class LLAttachmentDetach : public view_listener_t class LLWornItemFetchedObserver : public LLInventoryFetchItemsObserver { public: - LLWornItemFetchedObserver(const LLUUID& worn_item_id) : - LLInventoryFetchItemsObserver(worn_item_id) - {} - virtual ~LLWornItemFetchedObserver() {} + LLWornItemFetchedObserver(const LLUUID& worn_item_id) : + LLInventoryFetchItemsObserver(worn_item_id) + {} + virtual ~LLWornItemFetchedObserver() {} protected: - virtual void done() - { - gMenuAttachmentSelf->buildDrawLabels(); - gInventory.removeObserver(this); - delete this; - } + virtual void done() + { + gMenuAttachmentSelf->buildDrawLabels(); + gInventory.removeObserver(this); + delete this; + } }; // You can only drop items on parcels where you can build. class LLAttachmentEnableDrop : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - BOOL can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->allowAgentBuild()); - - //Add an inventory observer to only allow dropping the newly attached item - //once it exists in your inventory. Look at Jira 2422. - //-jwolk - - // A bug occurs when you wear/drop an item before it actively is added to your inventory - // if this is the case (you're on a slow sim, etc.) a copy of the object, - // well, a newly created object with the same properties, is placed - // in your inventory. Therefore, we disable the drop option until the - // item is in your inventory - - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - LLViewerJointAttachment* attachment = NULL; - LLInventoryItem* item = NULL; - - // Do not enable drop if all faces of object are not enabled - if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) - { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState()); - attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); - - if (attachment) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - // make sure item is in your inventory (it could be a delayed attach message being sent from the sim) - // so check to see if the item is in the inventory already - item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID()); - if (!item) - { - // Item does not exist, make an observer to enable the pie menu - // when the item finishes fetching worst case scenario - // if a fetch is already out there (being sent from a slow sim) - // we refetch and there are 2 fetches - LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID()); - worn_item_fetched->startFetch(); - gInventory.addObserver(worn_item_fetched); - } - } - } - } - - //now check to make sure that the item is actually in the inventory before we enable dropping it - bool new_value = enable_detach() && can_build && item; - - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + BOOL can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->allowAgentBuild()); + + //Add an inventory observer to only allow dropping the newly attached item + //once it exists in your inventory. Look at Jira 2422. + //-jwolk + + // A bug occurs when you wear/drop an item before it actively is added to your inventory + // if this is the case (you're on a slow sim, etc.) a copy of the object, + // well, a newly created object with the same properties, is placed + // in your inventory. Therefore, we disable the drop option until the + // item is in your inventory + + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLViewerJointAttachment* attachment = NULL; + LLInventoryItem* item = NULL; + + // Do not enable drop if all faces of object are not enabled + if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) + { + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState()); + attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); + + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + // make sure item is in your inventory (it could be a delayed attach message being sent from the sim) + // so check to see if the item is in the inventory already + item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID()); + if (!item) + { + // Item does not exist, make an observer to enable the pie menu + // when the item finishes fetching worst case scenario + // if a fetch is already out there (being sent from a slow sim) + // we refetch and there are 2 fetches + LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID()); + worn_item_fetched->startFetch(); + gInventory.addObserver(worn_item_fetched); + } + } + } + } + + //now check to make sure that the item is actually in the inventory before we enable dropping it + bool new_value = enable_detach() && can_build && item; + + return new_value; + } }; BOOL enable_detach(const LLSD&) { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - - // Only enable detach if all faces of object are selected - if (!object || - !object->isAttachment() || - !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) - { - return FALSE; - } + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + + // Only enable detach if all faces of object are selected + if (!object || + !object->isAttachment() || + !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) + { + return FALSE; + } - // Find the avatar who owns this attachment - LLViewerObject* avatar = object; - while (avatar) - { - // ...if it's you, good to detach - if (avatar->getID() == gAgent.getID()) - { - return TRUE; - } + // Find the avatar who owns this attachment + LLViewerObject* avatar = object; + while (avatar) + { + // ...if it's you, good to detach + if (avatar->getID() == gAgent.getID()) + { + return TRUE; + } - avatar = (LLViewerObject*)avatar->getParent(); - } + avatar = (LLViewerObject*)avatar->getParent(); + } - return FALSE; + return FALSE; } class LLAttachmentEnableDetach : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = enable_detach(); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = enable_detach(); + return new_value; + } }; // Used to tell if the selected object can be attached to your avatar. BOOL object_selected_and_point_valid() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - for (LLObjectSelection::root_iterator iter = selection->root_begin(); - iter != selection->root_end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - LLViewerObject::const_child_list_t& child_list = object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - if (child->isAvatar()) - { - return FALSE; - } - } - } - - return (selection->getRootObjectCount() == 1) && - (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) && - selection->getFirstRootObject()->permYouOwner() && - selection->getFirstRootObject()->flagObjectMove() && - !selection->getFirstRootObject()->flagObjectPermanent() && - !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() && - (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + for (LLObjectSelection::root_iterator iter = selection->root_begin(); + iter != selection->root_end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + LLViewerObject::const_child_list_t& child_list = object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if (child->isAvatar()) + { + return FALSE; + } + } + } + + return (selection->getRootObjectCount() == 1) && + (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) && + selection->getFirstRootObject()->permYouOwner() && + selection->getFirstRootObject()->flagObjectMove() && + !selection->getFirstRootObject()->flagObjectPermanent() && + !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() && + (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL); } BOOL object_is_wearable() { - if (!isAgentAvatarValid()) - { - return FALSE; - } - if (!object_selected_and_point_valid()) - { - return FALSE; - } - if (sitting_on_selection()) - { - return FALSE; - } + if (!isAgentAvatarValid()) + { + return FALSE; + } + if (!object_selected_and_point_valid()) + { + return FALSE; + } + if (sitting_on_selection()) + { + return FALSE; + } if (!gAgentAvatarp->canAttachMoreObjects()) { return FALSE; } - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) - { - LLSelectNode* node = *iter; - if (node->mPermissions->getOwner() == gAgent.getID()) - { - return TRUE; - } - } - return FALSE; + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) + { + LLSelectNode* node = *iter; + if (node->mPermissions->getOwner() == gAgent.getID()) + { + return TRUE; + } + } + return FALSE; } class LLAttachmentPointFilled : public view_listener_t { - bool handleEvent(const LLSD& user_data) - { - bool enable = false; - LLVOAvatar::attachment_map_t::iterator found_it = gAgentAvatarp->mAttachmentPoints.find(user_data.asInteger()); - if (found_it != gAgentAvatarp->mAttachmentPoints.end()) - { - enable = found_it->second->getNumObjects() > 0; - } - return enable; - } + bool handleEvent(const LLSD& user_data) + { + bool enable = false; + LLVOAvatar::attachment_map_t::iterator found_it = gAgentAvatarp->mAttachmentPoints.find(user_data.asInteger()); + if (found_it != gAgentAvatarp->mAttachmentPoints.end()) + { + enable = found_it->second->getNumObjects() > 0; + } + return enable; + } }; class LLAvatarSendIM : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - LLAvatarActions::startIM(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLAvatarActions::startIM(avatar->getID()); + } + return true; + } }; class LLAvatarCall : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - { - LLAvatarActions::startCall(avatar->getID()); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLAvatarActions::startCall(avatar->getID()); + } + return true; + } }; namespace { - struct QueueObjects : public LLSelectedNodeFunctor - { - BOOL scripted; - BOOL modifiable; - LLFloaterScriptQueue* mQueue; - QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {} - virtual bool apply(LLSelectNode* node) - { - LLViewerObject* obj = node->getObject(); - if (!obj) - { - return true; - } - scripted = obj->flagScripted(); - modifiable = obj->permModify(); - - if( scripted && modifiable ) - { - mQueue->addObject(obj->getID(), node->mName); - return false; - } - else - { - return true; // fail: stop applying - } - } - }; + struct QueueObjects : public LLSelectedNodeFunctor + { + BOOL scripted; + BOOL modifiable; + LLFloaterScriptQueue* mQueue; + QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {} + virtual bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + if (!obj) + { + return true; + } + scripted = obj->flagScripted(); + modifiable = obj->permModify(); + + if( scripted && modifiable ) + { + mQueue->addObject(obj->getID(), node->mName); + return false; + } + else + { + return true; // fail: stop applying + } + } + }; } bool queue_actions(LLFloaterScriptQueue* q, const std::string& msg) { - QueueObjects func(q); - LLSelectMgr *mgr = LLSelectMgr::getInstance(); - LLObjectSelectionHandle selectHandle = mgr->getSelection(); - bool fail = selectHandle->applyToNodes(&func); - if(fail) - { - if ( !func.scripted ) - { - std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts"; - LLNotificationsUtil::add(noscriptmsg); - } - else if ( !func.modifiable ) - { - std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission"; - LLNotificationsUtil::add(nomodmsg); - } - else - { - LL_ERRS() << "Bad logic." << LL_ENDL; - } - q->closeFloater(); - } - else - { - if (!q->start()) - { - LL_WARNS() << "Unexpected script compile failure." << LL_ENDL; - } - } - return !fail; + QueueObjects func(q); + LLSelectMgr *mgr = LLSelectMgr::getInstance(); + LLObjectSelectionHandle selectHandle = mgr->getSelection(); + bool fail = selectHandle->applyToNodes(&func); + if(fail) + { + if ( !func.scripted ) + { + std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts"; + LLNotificationsUtil::add(noscriptmsg); + } + else if ( !func.modifiable ) + { + std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission"; + LLNotificationsUtil::add(nomodmsg); + } + else + { + LL_ERRS() << "Bad logic." << LL_ENDL; + } + q->closeFloater(); + } + else + { + if (!q->start()) + { + LL_WARNS() << "Unexpected script compile failure." << LL_ENDL; + } + } + return !fail; } class LLToolsSelectedScriptAction : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string action = userdata.asString(); - bool mono = false; - std::string msg, name; - std::string title; - if (action == "compile mono") - { - name = "compile_queue"; - mono = true; - msg = "Recompile"; - title = LLTrans::getString("CompileQueueTitle"); - } - if (action == "compile lsl") - { - name = "compile_queue"; - msg = "Recompile"; - title = LLTrans::getString("CompileQueueTitle"); - } - else if (action == "reset") - { - name = "reset_queue"; - msg = "Reset"; - title = LLTrans::getString("ResetQueueTitle"); - } - else if (action == "start") - { - name = "start_queue"; - msg = "SetRunning"; - title = LLTrans::getString("RunQueueTitle"); - } - else if (action == "stop") - { - name = "stop_queue"; - msg = "SetRunningNot"; - title = LLTrans::getString("NotRunQueueTitle"); - } - LLUUID id; id.generate(); - - LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance(name, LLSD(id)); - if (queue) - { - queue->setMono(mono); - if (queue_actions(queue, msg)) - { - queue->setTitle(title); - } - } - else - { - LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL; - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string action = userdata.asString(); + bool mono = false; + std::string msg, name; + std::string title; + if (action == "compile mono") + { + name = "compile_queue"; + mono = true; + msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); + } + if (action == "compile lsl") + { + name = "compile_queue"; + msg = "Recompile"; + title = LLTrans::getString("CompileQueueTitle"); + } + else if (action == "reset") + { + name = "reset_queue"; + msg = "Reset"; + title = LLTrans::getString("ResetQueueTitle"); + } + else if (action == "start") + { + name = "start_queue"; + msg = "SetRunning"; + title = LLTrans::getString("RunQueueTitle"); + } + else if (action == "stop") + { + name = "stop_queue"; + msg = "SetRunningNot"; + title = LLTrans::getString("NotRunQueueTitle"); + } + LLUUID id; id.generate(); + + LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance(name, LLSD(id)); + if (queue) + { + queue->setMono(mono); + if (queue_actions(queue, msg)) + { + queue->setTitle(title); + } + } + else + { + LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL; + } + return true; + } }; void handle_selected_texture_info(void*) { - for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) - { - LLSelectNode* node = *iter; - - std::string msg; - msg.assign("Texture info for: "); - msg.append(node->mName); - - U8 te_count = node->getObject()->getNumTEs(); - // map from texture ID to list of faces using it - typedef std::map< LLUUID, std::vector > map_t; - map_t faces_per_texture; - for (U8 i = 0; i < te_count; i++) - { - if (!node->isTESelected(i)) continue; - - LLViewerTexture* img = node->getObject()->getTEImage(i); - LLUUID image_id = img->getID(); - faces_per_texture[image_id].push_back(i); - } - // Per-texture, dump which faces are using it. - map_t::iterator it; - for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it) - { - U8 te = it->second[0]; - LLViewerTexture* img = node->getObject()->getTEImage(te); - S32 height = img->getHeight(); - S32 width = img->getWidth(); - S32 components = img->getComponents(); - msg.append(llformat("\n%dx%d %s on face ", - width, - height, - (components == 4 ? "alpha" : "opaque"))); - for (U8 i = 0; i < it->second.size(); ++i) - { - msg.append( llformat("%d ", (S32)(it->second[i]))); - } - } - LLSD args; - args["MESSAGE"] = msg; - LLNotificationsUtil::add("SystemMessage", args); - } + for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) + { + LLSelectNode* node = *iter; + + std::string msg; + msg.assign("Texture info for: "); + msg.append(node->mName); + + U8 te_count = node->getObject()->getNumTEs(); + // map from texture ID to list of faces using it + typedef std::map< LLUUID, std::vector > map_t; + map_t faces_per_texture; + for (U8 i = 0; i < te_count; i++) + { + if (!node->isTESelected(i)) continue; + + LLViewerTexture* img = node->getObject()->getTEImage(i); + LLUUID image_id = img->getID(); + faces_per_texture[image_id].push_back(i); + } + // Per-texture, dump which faces are using it. + map_t::iterator it; + for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it) + { + U8 te = it->second[0]; + LLViewerTexture* img = node->getObject()->getTEImage(te); + S32 height = img->getHeight(); + S32 width = img->getWidth(); + S32 components = img->getComponents(); + msg.append(llformat("\n%dx%d %s on face ", + width, + height, + (components == 4 ? "alpha" : "opaque"))); + for (U8 i = 0; i < it->second.size(); ++i) + { + msg.append( llformat("%d ", (S32)(it->second[i]))); + } + } + LLSD args; + args["MESSAGE"] = msg; + LLNotificationsUtil::add("SystemMessage", args); + } } void handle_selected_material_info() { - for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) - { - LLSelectNode* node = *iter; - - std::string msg; - msg.assign("Material info for: \n"); - msg.append(node->mName); - - U8 te_count = node->getObject()->getNumTEs(); - // map from material ID to list of faces using it - typedef std::map > map_t; - map_t faces_per_material; - for (U8 i = 0; i < te_count; i++) - { - if (!node->isTESelected(i)) continue; - - const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID(); - faces_per_material[material_id].push_back(i); - } - // Per-material, dump which faces are using it. - map_t::iterator it; - for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it) - { - const LLMaterialID& material_id = it->first; - msg += llformat("%s on face ", material_id.asString().c_str()); - for (U8 i = 0; i < it->second.size(); ++i) - { - msg.append( llformat("%d ", (S32)(it->second[i]))); - } - msg.append("\n"); - } - - LLSD args; - args["MESSAGE"] = msg; - LLNotificationsUtil::add("SystemMessage", args); - } + for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) + { + LLSelectNode* node = *iter; + + std::string msg; + msg.assign("Material info for: \n"); + msg.append(node->mName); + + U8 te_count = node->getObject()->getNumTEs(); + // map from material ID to list of faces using it + typedef std::map > map_t; + map_t faces_per_material; + for (U8 i = 0; i < te_count; i++) + { + if (!node->isTESelected(i)) continue; + + const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID(); + faces_per_material[material_id].push_back(i); + } + // Per-material, dump which faces are using it. + map_t::iterator it; + for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it) + { + const LLMaterialID& material_id = it->first; + msg += llformat("%s on face ", material_id.asString().c_str()); + for (U8 i = 0; i < it->second.size(); ++i) + { + msg.append( llformat("%d ", (S32)(it->second[i]))); + } + msg.append("\n"); + } + + LLSD args; + args["MESSAGE"] = msg; + LLNotificationsUtil::add("SystemMessage", args); + } } void handle_test_male(void*) { - LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit"); - //gGestureList.requestResetFromServer( TRUE ); + LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit"); + //gGestureList.requestResetFromServer( TRUE ); } void handle_test_female(void*) { - LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit"); - //gGestureList.requestResetFromServer( FALSE ); + LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit"); + //gGestureList.requestResetFromServer( FALSE ); } void handle_dump_attachments(void*) { - if(!isAgentAvatarValid()) return; - - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - S32 key = curiter->first; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *attached_object = attachment_iter->get(); - BOOL visible = (attached_object != NULL && - attached_object->mDrawable.notNull() && - !attached_object->mDrawable->isRenderType(0)); - LLVector3 pos; - if (visible) pos = attached_object->mDrawable->getPosition(); - LL_INFOS() << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID() - << (attached_object ? " present " : " absent ") - << (visible ? "visible " : "invisible ") - << " at " << pos - << " and " << (visible ? attached_object->getPosition() : LLVector3::zero) - << LL_ENDL; - } - } + if(!isAgentAvatarValid()) return; + + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + S32 key = curiter->first; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = attachment_iter->get(); + BOOL visible = (attached_object != NULL && + attached_object->mDrawable.notNull() && + !attached_object->mDrawable->isRenderType(0)); + LLVector3 pos; + if (visible) pos = attached_object->mDrawable->getPosition(); + LL_INFOS() << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID() + << (attached_object ? " present " : " absent ") + << (visible ? "visible " : "invisible ") + << " at " << pos + << " and " << (visible ? attached_object->getPosition() : LLVector3::zero) + << LL_ENDL; + } + } } @@ -7890,80 +7890,80 @@ class LLToggleControl : public view_listener_t { protected: - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); - BOOL checked = gSavedSettings.getBOOL( control_name ); - gSavedSettings.setBOOL( control_name, !checked ); - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string control_name = userdata.asString(); + BOOL checked = gSavedSettings.getBOOL( control_name ); + gSavedSettings.setBOOL( control_name, !checked ); + return true; + } }; class LLCheckControl : public view_listener_t { - bool handleEvent( const LLSD& userdata) - { - std::string callback_data = userdata.asString(); - bool new_value = gSavedSettings.getBOOL(callback_data); - return new_value; - } + bool handleEvent( const LLSD& userdata) + { + std::string callback_data = userdata.asString(); + bool new_value = gSavedSettings.getBOOL(callback_data); + return new_value; + } }; // not so generic class LLAdvancedCheckRenderShadowOption: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); - S32 current_shadow_level = gSavedSettings.getS32(control_name); - if (current_shadow_level == 0) // is off - { - return false; - } - else // is on - { - return true; - } - } + bool handleEvent(const LLSD& userdata) + { + std::string control_name = userdata.asString(); + S32 current_shadow_level = gSavedSettings.getS32(control_name); + if (current_shadow_level == 0) // is off + { + return false; + } + else // is on + { + return true; + } + } }; class LLAdvancedClickRenderShadowOption: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); - S32 current_shadow_level = gSavedSettings.getS32(control_name); - if (current_shadow_level == 0) // upgrade to level 2 - { - gSavedSettings.setS32(control_name, 2); - } - else // downgrade to level 0 - { - gSavedSettings.setS32(control_name, 0); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string control_name = userdata.asString(); + S32 current_shadow_level = gSavedSettings.getS32(control_name); + if (current_shadow_level == 0) // upgrade to level 2 + { + gSavedSettings.setS32(control_name, 2); + } + else // downgrade to level 0 + { + gSavedSettings.setS32(control_name, 0); + } + return true; + } }; class LLAdvancedClickRenderProfile: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gShaderProfileFrame = TRUE; - return true; - } + bool handleEvent(const LLSD& userdata) + { + gShaderProfileFrame = TRUE; + return true; + } }; F32 gpu_benchmark(); class LLAdvancedClickRenderBenchmark: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gpu_benchmark(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gpu_benchmark(); + return true; + } }; void hdri_preview(); @@ -7993,290 +7993,290 @@ class LLAdvancedClickGLTFScenePreview : public view_listener_t // these are used in the gl menus to set control values that require shader recompilation class LLToggleShaderControl : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { std::string control_name = userdata.asString(); - BOOL checked = gSavedSettings.getBOOL( control_name ); - gSavedSettings.setBOOL( control_name, !checked ); + BOOL checked = gSavedSettings.getBOOL( control_name ); + gSavedSettings.setBOOL( control_name, !checked ); LLPipeline::refreshCachedSettings(); LLViewerShaderMgr::instance()->setShaders(); - return !checked; - } + return !checked; + } }; void menu_toggle_attached_lights(void* user_data) { - LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); + LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); } void menu_toggle_attached_particles(void* user_data) { - LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); + LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); } class LLAdvancedHandleAttachedLightParticles: public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); + bool handleEvent(const LLSD& userdata) + { + std::string control_name = userdata.asString(); - // toggle the control - gSavedSettings.setBOOL(control_name, - !gSavedSettings.getBOOL(control_name)); + // toggle the control + gSavedSettings.setBOOL(control_name, + !gSavedSettings.getBOOL(control_name)); - // update internal flags - if (control_name == "RenderAttachedLights") - { - menu_toggle_attached_lights(NULL); - } - else if (control_name == "RenderAttachedParticles") - { - menu_toggle_attached_particles(NULL); - } - return true; - } + // update internal flags + if (control_name == "RenderAttachedLights") + { + menu_toggle_attached_lights(NULL); + } + else if (control_name == "RenderAttachedParticles") + { + menu_toggle_attached_particles(NULL); + } + return true; + } }; class LLSomethingSelected : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty()); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty()); + return new_value; + } }; class LLSomethingSelectedNoHUD : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD); + return new_value; + } }; static bool is_editable_selected() { - return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL); + return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL); } class LLEditableSelected : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return is_editable_selected(); - } + bool handleEvent(const LLSD& userdata) + { + return is_editable_selected(); + } }; class LLEditableSelectedMono : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = false; - LLViewerRegion* region = gAgent.getRegion(); - if(region && gMenuHolder) - { - bool have_cap = (! region->getCapability("UpdateScriptTask").empty()); - new_value = is_editable_selected() && have_cap; - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = false; + LLViewerRegion* region = gAgent.getRegion(); + if(region && gMenuHolder) + { + bool have_cap = (! region->getCapability("UpdateScriptTask").empty()); + new_value = is_editable_selected() && have_cap; + } + return new_value; + } }; bool enable_object_take_copy() { - bool all_valid = false; - if (LLSelectMgr::getInstance()) - { - if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 0) - { - all_valid = true; + bool all_valid = false; + if (LLSelectMgr::getInstance()) + { + if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 0) + { + all_valid = true; #ifndef HACKED_GODLIKE_VIEWER # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstance()->isInProductionGrid() + if (LLGridManager::getInstance()->isInProductionGrid() || !gAgent.isGodlike()) # endif - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* obj) - { - return (!obj->permCopy() || obj->isAttachment()); - } - } func; - const bool firstonly = true; - bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); - all_valid = !any_invalid; - } + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* obj) + { + return (!obj->permCopy() || obj->isAttachment()); + } + } func; + const bool firstonly = true; + bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); + all_valid = !any_invalid; + } #endif // HACKED_GODLIKE_VIEWER - } - } + } + } - return all_valid; + return all_valid; } class LLHasAsset : public LLInventoryCollectFunctor { public: - LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {} - virtual ~LLHasAsset() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item); - BOOL hasAsset() const { return mHasAsset; } + LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {} + virtual ~LLHasAsset() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); + BOOL hasAsset() const { return mHasAsset; } protected: - LLUUID mAssetID; - BOOL mHasAsset; + LLUUID mAssetID; + BOOL mHasAsset; }; bool LLHasAsset::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) + LLInventoryItem* item) { - if(item && item->getAssetUUID() == mAssetID) - { - mHasAsset = TRUE; - } - return FALSE; + if(item && item->getAssetUUID() == mAssetID) + { + mHasAsset = TRUE; + } + return FALSE; } BOOL enable_save_into_task_inventory(void*) { - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if(node && (node->mValid) && (!node->mFromTaskID.isNull())) - { - // *TODO: check to see if the fromtaskid object exists. - LLViewerObject* obj = node->getObject(); - if( obj && !obj->isAttachment() ) - { - return TRUE; - } - } - return FALSE; + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if(node && (node->mValid) && (!node->mFromTaskID.isNull())) + { + // *TODO: check to see if the fromtaskid object exists. + LLViewerObject* obj = node->getObject(); + if( obj && !obj->isAttachment() ) + { + return TRUE; + } + } + return FALSE; } class LLToolsEnableSaveToObjectInventory : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = enable_save_into_task_inventory(NULL); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = enable_save_into_task_inventory(NULL); + return new_value; + } }; class LLToggleHowTo : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::toggleInstanceOrBringToFront("guidebook"); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloaterReg::toggleInstanceOrBringToFront("guidebook"); + return true; + } }; class LLViewEnableMouselook : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // You can't go directly from customize avatar to mouselook. - // TODO: write code with appropriate dialogs to handle this transition. - bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime")); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + // You can't go directly from customize avatar to mouselook. + // TODO: write code with appropriate dialogs to handle this transition. + bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime")); + return new_value; + } }; class LLToolsEnableToolNotPie : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() ); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() ); + return new_value; + } }; class LLWorldEnableCreateLandmark : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return !LLLandmarkActions::landmarkAlreadyExists(); - } + bool handleEvent(const LLSD& userdata) + { + return !LLLandmarkActions::landmarkAlreadyExists(); + } }; class LLWorldEnableSetHomeLocation : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gAgent.isGodlike() || - (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome()); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gAgent.isGodlike() || + (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome()); + return new_value; + } }; class LLWorldEnableTeleportHome : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLViewerRegion* regionp = gAgent.getRegion(); - bool agent_on_prelude = (regionp && regionp->isPrelude()); - bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude; - return enable_teleport_home; - } + bool handleEvent(const LLSD& userdata) + { + LLViewerRegion* regionp = gAgent.getRegion(); + bool agent_on_prelude = (regionp && regionp->isPrelude()); + bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude; + return enable_teleport_home; + } }; BOOL enable_god_full(void*) { - return gAgent.getGodLevel() >= GOD_FULL; + return gAgent.getGodLevel() >= GOD_FULL; } BOOL enable_god_liaison(void*) { - return gAgent.getGodLevel() >= GOD_LIAISON; + return gAgent.getGodLevel() >= GOD_LIAISON; } bool is_god_customer_service() { - return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE; + return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE; } BOOL enable_god_basic(void*) { - return gAgent.getGodLevel() > GOD_NOT; + return gAgent.getGodLevel() > GOD_NOT; } void toggle_show_xui_names(void *) { - gSavedSettings.setBOOL("DebugShowXUINames", !gSavedSettings.getBOOL("DebugShowXUINames")); + gSavedSettings.setBOOL("DebugShowXUINames", !gSavedSettings.getBOOL("DebugShowXUINames")); } BOOL check_show_xui_names(void *) { - return gSavedSettings.getBOOL("DebugShowXUINames"); + return gSavedSettings.getBOOL("DebugShowXUINames"); } class LLToolsSelectOnlyMyObjects : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly"); + bool handleEvent(const LLSD& userdata) + { + BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly"); - gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val ); + gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val ); - return true; - } + return true; + } }; class LLToolsSelectOnlyMovableObjects : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly"); + bool handleEvent(const LLSD& userdata) + { + BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly"); - gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val ); + gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val ); - return true; - } + return true; + } }; class LLToolsSelectInvisibleObjects : public view_listener_t @@ -8305,178 +8305,178 @@ class LLToolsSelectReflectionProbes: public view_listener_t class LLToolsSelectBySurrounding : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive; + bool handleEvent(const LLSD& userdata) + { + LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive; - gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive); - return true; - } + gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive); + return true; + } }; class LLToolsShowHiddenSelection : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // TomY TODO Merge these - LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections; + bool handleEvent(const LLSD& userdata) + { + // TomY TODO Merge these + LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections; - gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections); - return true; - } + gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections); + return true; + } }; class LLToolsShowSelectionLightRadius : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - // TomY TODO merge these - LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius; + bool handleEvent(const LLSD& userdata) + { + // TomY TODO merge these + LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius; - gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius); - return true; - } + gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius); + return true; + } }; class LLToolsEditLinkedParts : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - BOOL select_individuals = !gSavedSettings.getBOOL("EditLinkedParts"); - gSavedSettings.setBOOL( "EditLinkedParts", select_individuals ); - if (select_individuals) - { - LLSelectMgr::getInstance()->demoteSelectionToIndividuals(); - } - else - { - LLSelectMgr::getInstance()->promoteSelectionToRoot(); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + BOOL select_individuals = !gSavedSettings.getBOOL("EditLinkedParts"); + gSavedSettings.setBOOL( "EditLinkedParts", select_individuals ); + if (select_individuals) + { + LLSelectMgr::getInstance()->demoteSelectionToIndividuals(); + } + else + { + LLSelectMgr::getInstance()->promoteSelectionToRoot(); + } + return true; + } }; void reload_vertex_shader(void *) { - //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP + //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP } void handle_dump_avatar_local_textures(void*) { - gAgentAvatarp->dumpLocalTextures(); + gAgentAvatarp->dumpLocalTextures(); } void handle_dump_timers() { - LLTrace::BlockTimer::dumpCurTimes(); + LLTrace::BlockTimer::dumpCurTimes(); } void handle_debug_avatar_textures(void*) { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (objectp) - { - LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) ); - } + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (objectp) + { + LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) ); + } } void handle_grab_baked_texture(void* data) { - EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data); - if (!isAgentAvatarValid()) return; - - const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index); - LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << LL_ENDL; - LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; - LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; - const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type)); - if(folder_id.notNull()) - { - std::string name; - name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture"; - - LLUUID item_id; - item_id.generate(); - LLPermissions perm; - perm.init(gAgentID, - gAgentID, - LLUUID::null, - LLUUID::null); - U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER; - perm.initMasks(PERM_ALL, - PERM_ALL, - PERM_NONE, - PERM_NONE, - next_owner_perm); - time_t creation_date_now = time_corrected(); - LLPointer item - = new LLViewerInventoryItem(item_id, - folder_id, - perm, - asset_id, - asset_type, - inv_type, - name, - LLStringUtil::null, - LLSaleInfo::DEFAULT, - LLInventoryItemFlags::II_FLAGS_NONE, - creation_date_now); - - item->updateServer(TRUE); - gInventory.updateItem(item); - gInventory.notifyObservers(); - - // Show the preview panel for textures to let - // user know that the image is now in inventory. - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if(active_panel) - { - LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - - active_panel->setSelection(item_id, TAKE_FOCUS_NO); - active_panel->openSelected(); - //LLFloaterInventory::dumpSelectionInformation((void*)view); - // restore keyboard focus - gFocusMgr.setKeyboardFocus(focus_ctrl); - } - } - else - { - LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; - } + EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data); + if (!isAgentAvatarValid()) return; + + const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index); + LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << LL_ENDL; + LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; + LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; + const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type)); + if(folder_id.notNull()) + { + std::string name; + name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture"; + + LLUUID item_id; + item_id.generate(); + LLPermissions perm; + perm.init(gAgentID, + gAgentID, + LLUUID::null, + LLUUID::null); + U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER; + perm.initMasks(PERM_ALL, + PERM_ALL, + PERM_NONE, + PERM_NONE, + next_owner_perm); + time_t creation_date_now = time_corrected(); + LLPointer item + = new LLViewerInventoryItem(item_id, + folder_id, + perm, + asset_id, + asset_type, + inv_type, + name, + LLStringUtil::null, + LLSaleInfo::DEFAULT, + LLInventoryItemFlags::II_FLAGS_NONE, + creation_date_now); + + item->updateServer(TRUE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + + // Show the preview panel for textures to let + // user know that the image is now in inventory. + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if(active_panel) + { + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); + + active_panel->setSelection(item_id, TAKE_FOCUS_NO); + active_panel->openSelected(); + //LLFloaterInventory::dumpSelectionInformation((void*)view); + // restore keyboard focus + gFocusMgr.setKeyboardFocus(focus_ctrl); + } + } + else + { + LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; + } } BOOL enable_grab_baked_texture(void* data) { - EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data); - if (isAgentAvatarValid()) - { - return gAgentAvatarp->canGrabBakedTexture(index); - } - return FALSE; + EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data); + if (isAgentAvatarValid()) + { + return gAgentAvatarp->canGrabBakedTexture(index); + } + return FALSE; } // Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing. // Returns NULL on failure. LLVOAvatar* find_avatar_from_object( LLViewerObject* object ) { - if (object) - { - if( object->isAttachment() ) - { - do - { - object = (LLViewerObject*) object->getParent(); - } - while( object && !object->isAvatar() ); - } - else if( !object->isAvatar() ) - { - object = NULL; - } - } + if (object) + { + if( object->isAttachment() ) + { + do + { + object = (LLViewerObject*) object->getParent(); + } + while( object && !object->isAvatar() ); + } + else if( !object->isAvatar() ) + { + object = NULL; + } + } - return (LLVOAvatar*) object; + return (LLVOAvatar*) object; } @@ -8484,13 +8484,13 @@ LLVOAvatar* find_avatar_from_object( LLViewerObject* object ) // Returns NULL on failure. LLVOAvatar* find_avatar_from_object( const LLUUID& object_id ) { - return find_avatar_from_object( gObjectList.findObject(object_id) ); + return find_avatar_from_object( gObjectList.findObject(object_id) ); } void handle_disconnect_viewer(void *) { - LLAppViewer::instance()->forceDisconnect(LLTrans::getString("TestingDisconnect")); + LLAppViewer::instance()->forceDisconnect(LLTrans::getString("TestingDisconnect")); } void force_error_breakpoint(void *) @@ -8545,30 +8545,30 @@ void force_error_thread_crash(void *) class LLToolsUseSelectionForGrid : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLSelectMgr::getInstance()->clearGridObjects(); - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* objectp) - { - LLSelectMgr::getInstance()->addGridObject(objectp); - return true; - } - } func; - LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); - LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); - LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLSelectMgr::getInstance()->clearGridObjects(); + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* objectp) + { + LLSelectMgr::getInstance()->addGridObject(objectp); + return true; + } + } func; + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); + LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); + LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT); + return true; + } }; void handle_test_load_url(void*) { - LLWeb::loadURL(""); - LLWeb::loadURL("hacker://www.google.com/"); - LLWeb::loadURL("http"); - LLWeb::loadURL("http://www.google.com/"); + LLWeb::loadURL(""); + LLWeb::loadURL("hacker://www.google.com/"); + LLWeb::loadURL("http"); + LLWeb::loadURL("http://www.google.com/"); } // @@ -8582,86 +8582,86 @@ LLViewerMenuHolderGL::LLViewerMenuHolderGL(const LLViewerMenuHolderGL::Params& p BOOL LLViewerMenuHolderGL::hideMenus() { - BOOL handled = FALSE; - - if (LLMenuHolderGL::hideMenus()) - { - handled = TRUE; - } + BOOL handled = FALSE; + + if (LLMenuHolderGL::hideMenus()) + { + handled = TRUE; + } - // drop pie menu selection - mParcelSelection = NULL; - mObjectSelection = NULL; + // drop pie menu selection + mParcelSelection = NULL; + mObjectSelection = NULL; - if (gMenuBarView) - { - gMenuBarView->clearHoverItem(); - gMenuBarView->resetMenuTrigger(); - } + if (gMenuBarView) + { + gMenuBarView->clearHoverItem(); + gMenuBarView->resetMenuTrigger(); + } - return handled; + return handled; } -void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle selection) -{ - mParcelSelection = selection; +void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle selection) +{ + mParcelSelection = selection; } -void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle selection) -{ - mObjectSelection = selection; +void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle selection) +{ + mObjectSelection = selection; } const LLRect LLViewerMenuHolderGL::getMenuRect() const { - return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT); + return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT); } void handle_web_browser_test(const LLSD& param) { - std::string url = param.asString(); - if (url.empty()) - { - url = "about:blank"; - } - LLWeb::loadURLInternal(url); + std::string url = param.asString(); + if (url.empty()) + { + url = "about:blank"; + } + LLWeb::loadURLInternal(url); } bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if ( option == 0 ) // YES - { - //clear cache - LLAppViewer::instance()->purgeCacheImmediate(); - } + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) // YES + { + //clear cache + LLAppViewer::instance()->purgeCacheImmediate(); + } - return false; + return false; } void handle_cache_clear_immediately() { - LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); + LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); } void handle_web_content_test(const LLSD& param) { - std::string url = param.asString(); - LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true); + std::string url = param.asString(); + LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true); } void handle_show_url(const LLSD& param) { - std::string url = param.asString(); - if (LLWeb::useExternalBrowser(url)) - { - LLWeb::loadURLExternal(url); - } - else - { - LLWeb::loadURLInternal(url); - } + std::string url = param.asString(); + if (LLWeb::useExternalBrowser(url)) + { + LLWeb::loadURLExternal(url); + } + else + { + LLWeb::loadURLInternal(url); + } } @@ -8673,383 +8673,383 @@ void handle_report_bug(const LLSD& param) void handle_buy_currency_test(void*) { - std::string url = - "http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]"; + std::string url = + "http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]"; - LLStringUtil::format_map_t replace; - replace["[AGENT_ID]"] = gAgent.getID().asString(); - replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString(); - replace["[LANGUAGE]"] = LLUI::getLanguage(); - LLStringUtil::format(url, replace); + LLStringUtil::format_map_t replace; + replace["[AGENT_ID]"] = gAgent.getID().asString(); + replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString(); + replace["[LANGUAGE]"] = LLUI::getLanguage(); + LLStringUtil::format(url, replace); - LL_INFOS() << "buy currency url " << url << LL_ENDL; + LL_INFOS() << "buy currency url " << url << LL_ENDL; - LLFloaterReg::showInstance("buy_currency_html", LLSD(url)); + LLFloaterReg::showInstance("buy_currency_html", LLSD(url)); } // SUNSHINE CLEANUP - is only the request update at the end needed now? void handle_rebake_textures(void*) { - if (!isAgentAvatarValid()) return; + if (!isAgentAvatarValid()) return; - // Slam pending upload count to "unstick" things - bool slam_for_debug = true; - gAgentAvatarp->forceBakeAllTextures(slam_for_debug); - if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) - { - LLAppearanceMgr::instance().requestServerAppearanceUpdate(); - } + // Slam pending upload count to "unstick" things + bool slam_for_debug = true; + gAgentAvatarp->forceBakeAllTextures(slam_for_debug); + if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } } void toggle_visibility(void* user_data) { - LLView* viewp = (LLView*)user_data; - viewp->setVisible(!viewp->getVisible()); + LLView* viewp = (LLView*)user_data; + viewp->setVisible(!viewp->getVisible()); } BOOL get_visibility(void* user_data) { - LLView* viewp = (LLView*)user_data; - return viewp->getVisible(); + LLView* viewp = (LLView*)user_data; + return viewp->getVisible(); } class LLViewShowHoverTips : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - gSavedSettings.setBOOL("ShowHoverTips", !gSavedSettings.getBOOL("ShowHoverTips")); - return true; - } + bool handleEvent(const LLSD& userdata) + { + gSavedSettings.setBOOL("ShowHoverTips", !gSavedSettings.getBOOL("ShowHoverTips")); + return true; + } }; class LLViewCheckShowHoverTips : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gSavedSettings.getBOOL("ShowHoverTips"); - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = gSavedSettings.getBOOL("ShowHoverTips"); + return new_value; + } }; class LLViewHighlightTransparent : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; + bool handleEvent(const LLSD& userdata) + { + LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; // invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag - gPipeline.rebuildDrawInfo(); - return true; - } + gPipeline.rebuildDrawInfo(); + return true; + } }; class LLViewCheckHighlightTransparent : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLDrawPoolAlpha::sShowDebugAlpha; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLDrawPoolAlpha::sShowDebugAlpha; + return new_value; + } }; class LLViewBeaconWidth : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string width = userdata.asString(); - if(width == "1") - { - gSavedSettings.setS32("DebugBeaconLineWidth", 1); - } - else if(width == "4") - { - gSavedSettings.setS32("DebugBeaconLineWidth", 4); - } - else if(width == "16") - { - gSavedSettings.setS32("DebugBeaconLineWidth", 16); - } - else if(width == "32") - { - gSavedSettings.setS32("DebugBeaconLineWidth", 32); - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string width = userdata.asString(); + if(width == "1") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 1); + } + else if(width == "4") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 4); + } + else if(width == "16") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 16); + } + else if(width == "32") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 32); + } + + return true; + } }; class LLViewToggleBeacon : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string beacon = userdata.asString(); - if (beacon == "scriptsbeacon") - { - LLPipeline::toggleRenderScriptedBeacons(); - gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); - // toggle the other one off if it's on - if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) - { - LLPipeline::toggleRenderScriptedTouchBeacons(); - gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); - } - } - else if (beacon == "physicalbeacon") - { - LLPipeline::toggleRenderPhysicalBeacons(); - gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() ); - } - else if (beacon == "moapbeacon") - { - LLPipeline::toggleRenderMOAPBeacons(); - gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() ); - } - else if (beacon == "soundsbeacon") - { - LLPipeline::toggleRenderSoundBeacons(); - gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() ); - } - else if (beacon == "particlesbeacon") - { - LLPipeline::toggleRenderParticleBeacons(); - gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() ); - } - else if (beacon == "scripttouchbeacon") - { - LLPipeline::toggleRenderScriptedTouchBeacons(); - gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); - // toggle the other one off if it's on - if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) - { - LLPipeline::toggleRenderScriptedBeacons(); - gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); - } - } - else if (beacon == "sunbeacon") - { - gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon")); - } - else if (beacon == "moonbeacon") - { - gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon")); - } - else if (beacon == "renderbeacons") - { - LLPipeline::toggleRenderBeacons(); - gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); - // toggle the other one on if it's not - if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) - { - LLPipeline::toggleRenderHighlights(); - gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); - } - } - else if (beacon == "renderhighlights") - { - LLPipeline::toggleRenderHighlights(); - gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); - // toggle the other one on if it's not - if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) - { - LLPipeline::toggleRenderBeacons(); - gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); - } - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string beacon = userdata.asString(); + if (beacon == "scriptsbeacon") + { + LLPipeline::toggleRenderScriptedBeacons(); + gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); + // toggle the other one off if it's on + if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) + { + LLPipeline::toggleRenderScriptedTouchBeacons(); + gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); + } + } + else if (beacon == "physicalbeacon") + { + LLPipeline::toggleRenderPhysicalBeacons(); + gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() ); + } + else if (beacon == "moapbeacon") + { + LLPipeline::toggleRenderMOAPBeacons(); + gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() ); + } + else if (beacon == "soundsbeacon") + { + LLPipeline::toggleRenderSoundBeacons(); + gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() ); + } + else if (beacon == "particlesbeacon") + { + LLPipeline::toggleRenderParticleBeacons(); + gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() ); + } + else if (beacon == "scripttouchbeacon") + { + LLPipeline::toggleRenderScriptedTouchBeacons(); + gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); + // toggle the other one off if it's on + if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) + { + LLPipeline::toggleRenderScriptedBeacons(); + gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); + } + } + else if (beacon == "sunbeacon") + { + gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon")); + } + else if (beacon == "moonbeacon") + { + gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon")); + } + else if (beacon == "renderbeacons") + { + LLPipeline::toggleRenderBeacons(); + gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); + // toggle the other one on if it's not + if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) + { + LLPipeline::toggleRenderHighlights(); + gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); + } + } + else if (beacon == "renderhighlights") + { + LLPipeline::toggleRenderHighlights(); + gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); + // toggle the other one on if it's not + if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) + { + LLPipeline::toggleRenderBeacons(); + gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); + } + } + + return true; + } }; class LLViewCheckBeaconEnabled : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string beacon = userdata.asString(); - bool new_value = false; - if (beacon == "scriptsbeacon") - { - new_value = gSavedSettings.getBOOL( "scriptsbeacon"); - LLPipeline::setRenderScriptedBeacons(new_value); - } - else if (beacon == "moapbeacon") - { - new_value = gSavedSettings.getBOOL( "moapbeacon"); - LLPipeline::setRenderMOAPBeacons(new_value); - } - else if (beacon == "physicalbeacon") - { - new_value = gSavedSettings.getBOOL( "physicalbeacon"); - LLPipeline::setRenderPhysicalBeacons(new_value); - } - else if (beacon == "soundsbeacon") - { - new_value = gSavedSettings.getBOOL( "soundsbeacon"); - LLPipeline::setRenderSoundBeacons(new_value); - } - else if (beacon == "particlesbeacon") - { - new_value = gSavedSettings.getBOOL( "particlesbeacon"); - LLPipeline::setRenderParticleBeacons(new_value); - } - else if (beacon == "scripttouchbeacon") - { - new_value = gSavedSettings.getBOOL( "scripttouchbeacon"); - LLPipeline::setRenderScriptedTouchBeacons(new_value); - } - else if (beacon == "renderbeacons") - { - new_value = gSavedSettings.getBOOL( "renderbeacons"); - LLPipeline::setRenderBeacons(new_value); - } - else if (beacon == "renderhighlights") - { - new_value = gSavedSettings.getBOOL( "renderhighlights"); - LLPipeline::setRenderHighlights(new_value); - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + std::string beacon = userdata.asString(); + bool new_value = false; + if (beacon == "scriptsbeacon") + { + new_value = gSavedSettings.getBOOL( "scriptsbeacon"); + LLPipeline::setRenderScriptedBeacons(new_value); + } + else if (beacon == "moapbeacon") + { + new_value = gSavedSettings.getBOOL( "moapbeacon"); + LLPipeline::setRenderMOAPBeacons(new_value); + } + else if (beacon == "physicalbeacon") + { + new_value = gSavedSettings.getBOOL( "physicalbeacon"); + LLPipeline::setRenderPhysicalBeacons(new_value); + } + else if (beacon == "soundsbeacon") + { + new_value = gSavedSettings.getBOOL( "soundsbeacon"); + LLPipeline::setRenderSoundBeacons(new_value); + } + else if (beacon == "particlesbeacon") + { + new_value = gSavedSettings.getBOOL( "particlesbeacon"); + LLPipeline::setRenderParticleBeacons(new_value); + } + else if (beacon == "scripttouchbeacon") + { + new_value = gSavedSettings.getBOOL( "scripttouchbeacon"); + LLPipeline::setRenderScriptedTouchBeacons(new_value); + } + else if (beacon == "renderbeacons") + { + new_value = gSavedSettings.getBOOL( "renderbeacons"); + LLPipeline::setRenderBeacons(new_value); + } + else if (beacon == "renderhighlights") + { + new_value = gSavedSettings.getBOOL( "renderhighlights"); + LLPipeline::setRenderHighlights(new_value); + } + return new_value; + } }; class LLViewToggleRenderType : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string type = userdata.asString(); - if (type == "hideparticles") - { - LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string type = userdata.asString(); + if (type == "hideparticles") + { + LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); + } + return true; + } }; class LLViewCheckRenderType : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string type = userdata.asString(); - bool new_value = false; - if (type == "hideparticles") - { - new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES); - } - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + std::string type = userdata.asString(); + bool new_value = false; + if (type == "hideparticles") + { + new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES); + } + return new_value; + } }; class LLViewStatusAway : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return (gAgent.isInitialized() && gAgent.getAFK()); - } + bool handleEvent(const LLSD& userdata) + { + return (gAgent.isInitialized() && gAgent.getAFK()); + } }; class LLViewStatusDoNotDisturb : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return (gAgent.isInitialized() && gAgent.isDoNotDisturb()); - } + bool handleEvent(const LLSD& userdata) + { + return (gAgent.isInitialized() && gAgent.isDoNotDisturb()); + } }; class LLViewShowHUDAttachments : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments; - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments; + return true; + } }; class LLViewCheckHUDAttachments : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool new_value = LLPipeline::sShowHUDAttachments; - return new_value; - } + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLPipeline::sShowHUDAttachments; + return new_value; + } }; class LLEditEnableTakeOff : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string clothing = userdata.asString(); - LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); - if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) - return LLAgentWearables::selfHasWearable(type); - return false; - } + bool handleEvent(const LLSD& userdata) + { + std::string clothing = userdata.asString(); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); + if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) + return LLAgentWearables::selfHasWearable(type); + return false; + } }; class LLEditTakeOff : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string clothing = userdata.asString(); - if (clothing == "all") - LLAppearanceMgr::instance().removeAllClothesFromAvatar(); - else - { - LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); - if (type >= LLWearableType::WT_SHAPE - && type < LLWearableType::WT_COUNT - && (gAgentWearables.getWearableCount(type) > 0)) - { - // MULTI-WEARABLES: assuming user wanted to remove top shirt. - U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; - LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index); - LLAppearanceMgr::instance().removeItemFromAvatar(item_id); - } - - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string clothing = userdata.asString(); + if (clothing == "all") + LLAppearanceMgr::instance().removeAllClothesFromAvatar(); + else + { + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); + if (type >= LLWearableType::WT_SHAPE + && type < LLWearableType::WT_COUNT + && (gAgentWearables.getWearableCount(type) > 0)) + { + // MULTI-WEARABLES: assuming user wanted to remove top shirt. + U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; + LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index); + LLAppearanceMgr::instance().removeItemFromAvatar(item_id); + } + + } + return true; + } }; class LLToolsSelectTool : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string tool_name = userdata.asString(); - if (tool_name == "focus") - { - LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1); - } - else if (tool_name == "move") - { - LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2); - } - else if (tool_name == "edit") - { - LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3); - } - else if (tool_name == "create") - { - LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4); - } - else if (tool_name == "land") - { - LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5); - } - - // Note: if floater is not visible LLViewerWindow::updateLayout() will - // attempt to open it, but it won't bring it to front or de-minimize. - if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost())) - { - gFloaterTools->setMinimized(FALSE); - gFloaterTools->openFloater(); - gFloaterTools->setVisibleAndFrontmost(TRUE); - } - return true; - } + bool handleEvent(const LLSD& userdata) + { + std::string tool_name = userdata.asString(); + if (tool_name == "focus") + { + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1); + } + else if (tool_name == "move") + { + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2); + } + else if (tool_name == "edit") + { + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3); + } + else if (tool_name == "create") + { + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4); + } + else if (tool_name == "land") + { + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5); + } + + // Note: if floater is not visible LLViewerWindow::updateLayout() will + // attempt to open it, but it won't bring it to front or de-minimize. + if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost())) + { + gFloaterTools->setMinimized(FALSE); + gFloaterTools->openFloater(); + gFloaterTools->setVisibleAndFrontmost(TRUE); + } + return true; + } }; /// WINDLIGHT callbacks class LLWorldEnvSettings : public view_listener_t -{ +{ void defocusEnvFloaters() { //currently there is only one instance of each floater @@ -9064,180 +9064,180 @@ class LLWorldEnvSettings : public view_listener_t } } - bool handleEvent(const LLSD& userdata) - { - std::string event_name = userdata.asString(); - - if (event_name == "sunrise") - { + bool handleEvent(const LLSD& userdata) + { + std::string event_name = userdata.asString(); + + if (event_name == "sunrise") + { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); - } - else if (event_name == "noon") - { + } + else if (event_name == "noon") + { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); - } + } else if (event_name == "legacy noon") { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY, LLEnvironment::TRANSITION_INSTANT); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } - else if (event_name == "sunset") - { + else if (event_name == "sunset") + { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); - } - else if (event_name == "midnight") - { + } + else if (event_name == "midnight") + { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); - } + } else if (event_name == "region") - { + { // reset probe data when reverting back to region sky setting gPipeline.mReflectionMapManager.reset(); LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); - } + } else if (event_name == "pause_clouds") { if (LLEnvironment::instance().isCloudScrollPaused()) LLEnvironment::instance().resumeCloudScroll(); - else + else LLEnvironment::instance().pauseCloudScroll(); } else if (event_name == "adjust_tool") - { + { LLFloaterReg::showInstance("env_adjust_snapshot"); } else if (event_name == "my_environs") { LLFloaterReg::showInstance("my_environments"); - } + } - return true; - } + return true; + } }; class LLWorldEnableEnvSettings : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool result = false; - std::string event_name = userdata.asString(); + bool handleEvent(const LLSD& userdata) + { + bool result = false; + std::string event_name = userdata.asString(); if (event_name == "pause_clouds") - { + { return LLEnvironment::instance().isCloudScrollPaused(); - } + } LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL); - if (!sky) - { - return (event_name == "region"); - } + if (!sky) + { + return (event_name == "region"); + } std::string skyname = (sky) ? sky->getName() : ""; LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null; - if (event_name == "sunrise") - { + if (event_name == "sunrise") + { result = (skyid == LLEnvironment::KNOWN_SKY_SUNRISE); - } - else if (event_name == "noon") - { + } + else if (event_name == "noon") + { result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY); - } + } else if (event_name == "legacy noon") { result = (skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY); } - else if (event_name == "sunset") - { + else if (event_name == "sunset") + { result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET); - } - else if (event_name == "midnight") - { + } + else if (event_name == "midnight") + { result = (skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT); - } - else if (event_name == "region") - { - return false; - } - else - { - LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL; - } - return result; - } + } + else if (event_name == "region") + { + return false; + } + else + { + LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL; + } + return result; + } }; class LLWorldEnvPreset : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - std::string item = userdata.asString(); + bool handleEvent(const LLSD& userdata) + { + std::string item = userdata.asString(); - if (item == "new_water") - { + if (item == "new_water") + { LLFloaterReg::showInstance("env_fixed_environmentent_water", "new"); - } - else if (item == "edit_water") - { + } + else if (item == "edit_water") + { LLFloaterReg::showInstance("env_fixed_environmentent_water", "edit"); - } - else if (item == "new_sky") - { + } + else if (item == "new_sky") + { LLFloaterReg::showInstance("env_fixed_environmentent_sky", "new"); - } - else if (item == "edit_sky") - { + } + else if (item == "edit_sky") + { LLFloaterReg::showInstance("env_fixed_environmentent_sky", "edit"); - } - else if (item == "new_day_cycle") - { + } + else if (item == "new_day_cycle") + { + LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory")); + } + else if (item == "edit_day_cycle") + { LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory")); - } - else if (item == "edit_day_cycle") - { - LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory")); - } - else - { - LL_WARNS() << "Unknown item selected" << LL_ENDL; - } + } + else + { + LL_WARNS() << "Unknown item selected" << LL_ENDL; + } - return true; - } + return true; + } }; class LLWorldEnableEnvPreset : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { - return false; - } + return false; + } }; /// Post-Process callbacks class LLWorldPostProcess : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterReg::showInstance("env_post_process"); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloaterReg::showInstance("env_post_process"); + return true; + } }; class LLWorldCheckBanLines : public view_listener_t @@ -9261,689 +9261,689 @@ class LLWorldShowBanLines : public view_listener_t void handle_flush_name_caches() { - if (gCacheName) gCacheName->clear(); + if (gCacheName) gCacheName->clear(); } class LLUploadCostCalculator : public view_listener_t { - std::string mCostStr; - - bool handleEvent(const LLSD& userdata) - { - std::vector fields; - std::string str = userdata.asString(); - boost::split(fields, str, boost::is_any_of(",")); - if (fields.size()<1) - { - return false; - } - std::string menu_name = fields[0]; - std::string asset_type_str = "texture"; - if (fields.size()>1) - { - asset_type_str = fields[1]; - } - LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL; - calculateCost(asset_type_str); - gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr); - - return true; - } - - void calculateCost(const std::string& asset_type_str); + std::string mCostStr; + + bool handleEvent(const LLSD& userdata) + { + std::vector fields; + std::string str = userdata.asString(); + boost::split(fields, str, boost::is_any_of(",")); + if (fields.size()<1) + { + return false; + } + std::string menu_name = fields[0]; + std::string asset_type_str = "texture"; + if (fields.size()>1) + { + asset_type_str = fields[1]; + } + LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL; + calculateCost(asset_type_str); + gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr); + + return true; + } + + void calculateCost(const std::string& asset_type_str); public: - LLUploadCostCalculator() - { - } + LLUploadCostCalculator() + { + } }; class LLUpdateMembershipLabel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText"); - gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str); + bool handleEvent(const LLSD& userdata) + { + const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText"); + gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str); - return true; - } + return true; + } }; void handle_voice_morphing_subscribe() { - LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); + LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); } void handle_premium_voice_morphing_subscribe() { - LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url")); + LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url")); } class LLToggleUIHints : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints"); - // toggle - ui_hints_enabled = !ui_hints_enabled; - gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled); - return true; - } + bool handleEvent(const LLSD& userdata) + { + bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints"); + // toggle + ui_hints_enabled = !ui_hints_enabled; + gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled); + return true; + } }; void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str) { - S32 upload_cost = -1; + S32 upload_cost = -1; - if (asset_type_str == "texture") - { + if (asset_type_str == "texture") + { // This use minimal texture cost to allow bulk and // texture upload menu options to be visible - upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - } - else if (asset_type_str == "animation") - { - upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost(); - } - else if (asset_type_str == "sound") - { - upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost(); - } - if (upload_cost < 0) - { - LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL; - } - mCostStr = std::to_string(upload_cost); + upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + } + else if (asset_type_str == "animation") + { + upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost(); + } + else if (asset_type_str == "sound") + { + upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost(); + } + if (upload_cost < 0) + { + LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL; + } + mCostStr = std::to_string(upload_cost); } void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) { - static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_hide_navbar.xml", - gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(gMenuHolder->hasVisibleMenu()) - { - gMenuHolder->hideMenus(); - } - show_navbar_context_menu->buildDrawLabels(); - show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y); + static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_hide_navbar.xml", + gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if(gMenuHolder->hasVisibleMenu()) + { + gMenuHolder->hideMenus(); + } + show_navbar_context_menu->buildDrawLabels(); + show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y); } void show_topinfobar_context_menu(LLView* ctrl, S32 x, S32 y) { - static LLMenuGL* show_topbarinfo_context_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_topinfobar.xml", - gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + static LLMenuGL* show_topbarinfo_context_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_topinfobar.xml", + gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - LLMenuItemGL* landmark_item = show_topbarinfo_context_menu->getChild("Landmark"); - if (!LLLandmarkActions::landmarkAlreadyExists()) - { - landmark_item->setLabel(LLTrans::getString("AddLandmarkNavBarMenu")); - } - else - { - landmark_item->setLabel(LLTrans::getString("EditLandmarkNavBarMenu")); - } + LLMenuItemGL* landmark_item = show_topbarinfo_context_menu->getChild("Landmark"); + if (!LLLandmarkActions::landmarkAlreadyExists()) + { + landmark_item->setLabel(LLTrans::getString("AddLandmarkNavBarMenu")); + } + else + { + landmark_item->setLabel(LLTrans::getString("EditLandmarkNavBarMenu")); + } - if(gMenuHolder->hasVisibleMenu()) - { - gMenuHolder->hideMenus(); - } + if(gMenuHolder->hasVisibleMenu()) + { + gMenuHolder->hideMenus(); + } - show_topbarinfo_context_menu->buildDrawLabels(); - show_topbarinfo_context_menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(ctrl, show_topbarinfo_context_menu, x, y); + show_topbarinfo_context_menu->buildDrawLabels(); + show_topbarinfo_context_menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(ctrl, show_topbarinfo_context_menu, x, y); } void initialize_edit_menu() { - view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo"); - view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo"); - view_listener_t::addMenu(new LLEditCut(), "Edit.Cut"); - view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy"); - view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste"); - view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete"); - view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll"); - view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect"); - view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff"); - view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo"); - view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo"); - view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut"); - view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy"); - view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste"); - view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete"); - view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll"); - view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect"); + view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo"); + view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo"); + view_listener_t::addMenu(new LLEditCut(), "Edit.Cut"); + view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy"); + view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste"); + view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete"); + view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll"); + view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect"); + view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff"); + view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo"); + view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo"); + view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut"); + view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy"); + view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste"); + view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete"); + view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll"); + view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect"); } void initialize_spellcheck_menu() { - LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); - LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar(); + LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); + LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar(); - commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2)); - enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2)); - commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1)); - enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1)); - commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1)); - enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1)); + commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2)); + enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2)); + commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1)); + enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1)); + commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1)); + enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1)); } void initialize_menus() { - // A parameterized event handler used as ctrl-8/9/0 zoom controls below. - class LLZoomer : public view_listener_t - { - public: - // The "mult" parameter says whether "val" is a multiplier or used to set the value. - LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {} - bool handleEvent(const LLSD& userdata) - { - F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal; - LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad); - gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it. - return true; - } - private: - F32 mVal; - bool mMult; - }; - - LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar(); - LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); - - // Generic enable and visible - // Don't prepend MenuName.Foo because these can be used in any menu. - enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); - - enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance())); - - view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); - - view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel"); - - enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed)); - - // Agent - commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); - enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land)); - commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); - commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); - commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); - enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2)); - enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2)); - - // File menu - init_menu_file(); - - view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff"); - view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); - view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape"); - view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight"); - view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics"); - commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); + // A parameterized event handler used as ctrl-8/9/0 zoom controls below. + class LLZoomer : public view_listener_t + { + public: + // The "mult" parameter says whether "val" is a multiplier or used to set the value. + LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {} + bool handleEvent(const LLSD& userdata) + { + F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal; + LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad); + gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it. + return true; + } + private: + F32 mVal; + bool mMult; + }; + + LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar(); + LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar(); + + // Generic enable and visible + // Don't prepend MenuName.Foo because these can be used in any menu. + enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service)); + + enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance())); + + view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); + + view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel"); + + enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed)); + + // Agent + commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); + enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land)); + commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); + commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); + commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); + enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2)); + enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2)); + + // File menu + init_menu_file(); + + view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff"); + view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); + view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape"); + view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight"); + view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics"); + commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); commit.add("NowWearing", boost::bind(&handle_now_wearing)); - commit.add("EditOutfit", boost::bind(&handle_edit_outfit)); - commit.add("EditShape", boost::bind(&handle_edit_shape)); - commit.add("HoverHeight", boost::bind(&handle_hover_height)); - commit.add("EditPhysics", boost::bind(&handle_edit_physics)); - - // View menu - view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook"); - view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam"); - view_listener_t::addMenu(new LLViewResetView(), "View.ResetView"); - view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter"); - view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips"); - view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent"); - view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType"); - view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments"); - view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut"); - view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn"); - view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault"); - view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize"); - view_listener_t::addMenu(new LLViewToggleUI(), "View.ToggleUI"); - - view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook"); - view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam"); - view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter"); - - view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam"); - view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips"); - view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent"); - view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType"); - view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway"); - view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); - view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - - //Communicate Nearby chat - view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat"); - - // Communicate > Voice morphing > Subscribe... - commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe)); - // Communicate > Voice morphing > Premium perk... - commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe)); - LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); - enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check" - , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing")); - commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click" - , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); - - // World menu - view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); - view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); - view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile"); - view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation"); - view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome"); - view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway"); - view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb"); - view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome"); - - view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark"); - view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); - view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome"); - view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand"); - - view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); - - view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings"); - view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings"); - view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset"); - view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset"); - view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); + commit.add("EditOutfit", boost::bind(&handle_edit_outfit)); + commit.add("EditShape", boost::bind(&handle_edit_shape)); + commit.add("HoverHeight", boost::bind(&handle_hover_height)); + commit.add("EditPhysics", boost::bind(&handle_edit_physics)); + + // View menu + view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook"); + view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam"); + view_listener_t::addMenu(new LLViewResetView(), "View.ResetView"); + view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter"); + view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips"); + view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent"); + view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType"); + view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments"); + view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut"); + view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn"); + view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault"); + view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize"); + view_listener_t::addMenu(new LLViewToggleUI(), "View.ToggleUI"); + + view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook"); + view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam"); + view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter"); + + view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam"); + view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips"); + view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent"); + view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType"); + view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway"); + view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); + view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); + + //Communicate Nearby chat + view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat"); + + // Communicate > Voice morphing > Subscribe... + commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe)); + // Communicate > Voice morphing > Premium perk... + commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe)); + LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); + enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check" + , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing")); + commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click" + , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); + + // World menu + view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); + view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); + view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile"); + view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation"); + view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome"); + view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway"); + view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb"); + view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome"); + + view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark"); + view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); + view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome"); + view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand"); + + view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); + + view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings"); + view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings"); + view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset"); + view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset"); + view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); view_listener_t::addMenu(new LLWorldCheckBanLines() , "World.CheckBanLines"); view_listener_t::addMenu(new LLWorldShowBanLines() , "World.ShowBanLines"); - // Tools menu - view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); - view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); - view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects"); + // Tools menu + view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); + view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); + view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects"); view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects"); view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes"); - view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding"); - view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection"); - view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius"); - view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts"); - view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY"); - view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid"); - view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart"); - commit.add("Tools.Link", boost::bind(&handle_link_objects)); - commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); - view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations"); - view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys"); - view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys"); - commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2)); - commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take)); - commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy)); - view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); - view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); - - view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); - view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart"); - enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance())); - enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance())); - view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake"); - enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy)); - enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object)); - enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object)); - view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory"); - - view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); - view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); - view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); - view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); - - // Help menu - // most items use the ShowFloater method - view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo"); - - // Advanced menu - view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); - view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); - view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); - - // Advanced > HUD Info - view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo"); - view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo"); - - // Advanced Other Settings - view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache"); - - // Advanced > Render > Types - view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType"); - view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType"); - - //// Advanced > Render > Features - view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature"); - view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); - - view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); - view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); - - // Advanced > Render > Info Displays - view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay"); - view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay"); - view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo"); - commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info)); - view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); - view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); - // Develop > Render - view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); - view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); - view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); - view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame"); - view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); - view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption"); - view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); - view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); - view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); + view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding"); + view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection"); + view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius"); + view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts"); + view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY"); + view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid"); + view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart"); + commit.add("Tools.Link", boost::bind(&handle_link_objects)); + commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); + view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations"); + view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys"); + view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys"); + commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2)); + commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take)); + commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy)); + view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); + view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); + + view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); + view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart"); + enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance())); + enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance())); + view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake"); + enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy)); + enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object)); + enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object)); + view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory"); + + view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); + view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); + view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); + view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); + + // Help menu + // most items use the ShowFloater method + view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo"); + + // Advanced menu + view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); + view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); + view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); + + // Advanced > HUD Info + view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo"); + view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo"); + + // Advanced Other Settings + view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache"); + + // Advanced > Render > Types + view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType"); + view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType"); + + //// Advanced > Render > Features + view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature"); + view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); + + view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); + view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); + + // Advanced > Render > Info Displays + view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay"); + view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay"); + view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo"); + commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info)); + view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); + view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); + // Develop > Render + view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); + view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); + view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); + view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame"); + view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); + view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption"); + view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); + view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); + view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); view_listener_t::addMenu(new LLAdvancedClickHDRIPreview(), "Advanced.ClickHDRIPreview"); view_listener_t::addMenu(new LLAdvancedClickGLTFScenePreview(), "Advanced.ClickGLTFScenePreview"); - view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache"); + view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache"); view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); - #ifdef TOGGLE_HACKED_GODLIKE_VIEWER - view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); - view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode"); - view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode"); - #endif + #ifdef TOGGLE_HACKED_GODLIKE_VIEWER + view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); + view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode"); + view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode"); + #endif - // Advanced > World - view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera"); - view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache"); + // Advanced > World + view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera"); + view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache"); view_listener_t::addMenu(new LLAdvancedToggleStatsRecorder(), "Advanced.ToggleStatsRecorder"); view_listener_t::addMenu(new LLAdvancedCheckStatsRecorder(), "Advanced.CheckStatsRecorder"); view_listener_t::addMenu(new LLAdvancedToggleInterestList360Mode(), "Advanced.ToggleInterestList360Mode"); view_listener_t::addMenu(new LLAdvancedCheckInterestList360Mode(), "Advanced.CheckInterestList360Mode"); view_listener_t::addMenu(new LLAdvancedResetInterestLists(), "Advanced.ResetInterestLists"); - // Advanced > UI - commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser - commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater - commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2)); - commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2)); - view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); - view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); - view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); - commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) ); - commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) ); - view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo"); - view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo"); - view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks"); - view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks"); - view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews"); - view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews"); - view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode"); - view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode"); - view_listener_t::addMenu(new LLAdvancedCheckDebugCamera(), "Advanced.CheckDebugCamera"); - view_listener_t::addMenu(new LLAdvancedToggleDebugCamera(), "Advanced.ToggleDebugCamera"); - view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips"); - view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips"); - view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents"); - view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents"); - view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys"); - view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys"); - view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc"); - view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc"); - - // Advanced > XUI - commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance())); - view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames"); - view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames"); - view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs"); - commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches)); - - // Advanced > Character > Grab Baked Texture - view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture"); - view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture"); - - // Advanced > Character > Character Tests - view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML"); - view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML"); - view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry"); - - view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale"); - view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale"); - - // Advanced > Character > Animation Speed - view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster"); - view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower"); - view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll"); - - // Advanced > Character (toplevel) - view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault"); - view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader"); - view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo"); - view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo"); - view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt"); - view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt"); - view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt"); - view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt"); - view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates"); - view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates"); - view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD"); - view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD"); - view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis"); - view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); - view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); - view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures"); - view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); - view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); - // Advanced > Network - view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog"); - view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog"); - view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket"); + // Advanced > UI + commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser + commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater + commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2)); + commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2)); + view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); + view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); + view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); + commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) ); + commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) ); + view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo"); + view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo"); + view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks"); + view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks"); + view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews"); + view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews"); + view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode"); + view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode"); + view_listener_t::addMenu(new LLAdvancedCheckDebugCamera(), "Advanced.CheckDebugCamera"); + view_listener_t::addMenu(new LLAdvancedToggleDebugCamera(), "Advanced.ToggleDebugCamera"); + view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips"); + view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips"); + view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents"); + view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents"); + view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys"); + view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys"); + view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc"); + view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc"); + + // Advanced > XUI + commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance())); + view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames"); + view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames"); + view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs"); + commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches)); + + // Advanced > Character > Grab Baked Texture + view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture"); + view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture"); + + // Advanced > Character > Character Tests + view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML"); + view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML"); + view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry"); + + view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale"); + view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale"); + + // Advanced > Character > Animation Speed + view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster"); + view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower"); + view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll"); + + // Advanced > Character (toplevel) + view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault"); + view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader"); + view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo"); + view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo"); + view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt"); + view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt"); + view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt"); + view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt"); + view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates"); + view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates"); + view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD"); + view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD"); + view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis"); + view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); + view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); + view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures"); + view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); + view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); + // Advanced > Network + view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog"); + view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog"); + view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket"); // Advanced > Cache view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache"); - // Advanced > Recorder - view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot"); - view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop"); - view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop"); - view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder"); + // Advanced > Recorder + view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot"); + view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop"); + view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop"); + view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder"); - // Advanced > Debugging - view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); - view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); + // Advanced > Debugging + view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); + view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg"); - view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); - view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); - view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); - view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException"); + view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); + view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); + view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); + view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException"); view_listener_t::addMenu(new LLAdvancedForceOSException(), "Advanced.ForceErrorOSException"); - view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); - view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); + view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); + view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); - view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer"); + view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer"); - // Advanced (toplevel) - view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates"); - view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates"); - view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage"); + // Advanced (toplevel) + view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates"); + view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates"); + view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage"); view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest"); - view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings"); - view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions"); - view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions"); - view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions"); - view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector"); - - view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus"); - view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus"); - - // Develop >Set logging level - view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel"); - view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); - - //Develop (clear cache immediately) - commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); - - // Develop (Fonts debugging) - commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts)); - commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures)); - - // Admin >Object - view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); - view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf"); - view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive"); - view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete"); - view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock"); - view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs"); - - // Admin >Parcel - view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe"); - view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent"); - view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand"); - - // Admin >Region - view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData"); - // Admin top level - view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); - - // Self context menu - view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand"); - enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand)); - view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments"); - - view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); - - // we don't use boost::bind directly to delay side tray construction - view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab"); - view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab"); - - // Avatar pie menu - view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode"); - view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode"); - view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); - view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend"); - view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact"); - commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD())); - view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug"); - view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug"); - view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup"); - commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD())); - commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector)); - view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM"); - view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call"); - enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall)); - view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse"); - view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); - view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks"); - view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch"); - view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); - view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton"); - view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); - view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations"); - enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); + view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings"); + view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions"); + view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions"); + view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions"); + view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector"); + + view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus"); + view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus"); + + // Develop >Set logging level + view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel"); + view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); + + //Develop (clear cache immediately) + commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); + + // Develop (Fonts debugging) + commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts)); + commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures)); + + // Admin >Object + view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); + view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf"); + view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive"); + view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete"); + view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock"); + view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs"); + + // Admin >Parcel + view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe"); + view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent"); + view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand"); + + // Admin >Region + view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData"); + // Admin top level + view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); + + // Self context menu + view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand"); + enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand)); + view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments"); + + view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); + + // we don't use boost::bind directly to delay side tray construction + view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab"); + view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab"); + + // Avatar pie menu + view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode"); + view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode"); + view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); + view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend"); + view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact"); + commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD())); + view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug"); + view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug"); + view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup"); + commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD())); + commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector)); + view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM"); + view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call"); + enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall)); + view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse"); + view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); + view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks"); + view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch"); + view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); + view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton"); + view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); + view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations"); + enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible)); - commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); - - view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend"); - enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2)); - - // Object pie menu - view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); - commit.add("Object.Touch", boost::bind(&handle_object_touch)); - commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original)); - commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); - commit.add("Object.Delete", boost::bind(&handle_object_delete)); - view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar"); - view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar"); - view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); - commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance())); - view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); - view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); - - enable.add("Object.VisibleTake", boost::bind(&visible_take_object)); - enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object)); - - commit.add("Object.Buy", boost::bind(&handle_buy)); - commit.add("Object.Edit", boost::bind(&handle_object_edit)); + commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); + + view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend"); + enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2)); + + // Object pie menu + view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); + commit.add("Object.Touch", boost::bind(&handle_object_touch)); + commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original)); + commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); + commit.add("Object.Delete", boost::bind(&handle_object_delete)); + view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar"); + view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar"); + view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); + commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance())); + view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); + view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); + + enable.add("Object.VisibleTake", boost::bind(&visible_take_object)); + enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object)); + + commit.add("Object.Buy", boost::bind(&handle_buy)); + commit.add("Object.Edit", boost::bind(&handle_object_edit)); commit.add("Object.Edit", boost::bind(&handle_object_edit)); commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material)); - commit.add("Object.Inspect", boost::bind(&handle_object_inspect)); - commit.add("Object.Open", boost::bind(&handle_object_open)); - commit.add("Object.Take", boost::bind(&handle_take)); - commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector)); + commit.add("Object.Inspect", boost::bind(&handle_object_inspect)); + commit.add("Object.Open", boost::bind(&handle_object_open)); + commit.add("Object.Take", boost::bind(&handle_take)); + commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector)); enable.add("Object.EnableInspect", boost::bind(&enable_object_inspect)); enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material)); - enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); - enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1)); - enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); - enable.add("Object.EnableWear", boost::bind(&object_is_wearable)); - - enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); - enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); - - view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); - enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance())); - view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); - - enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute)); - enable.add("Object.EnableMute", boost::bind(&enable_object_mute)); - enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute)); - enable.add("Object.EnableBuy", boost::bind(&enable_buy_object)); - commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom")); - - // Attachment pie menu - enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2)); - view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop"); - view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint"); - view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach"); - view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled"); - view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop"); - view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach"); - - // Land pie menu - view_listener_t::addMenu(new LLLandBuild(), "Land.Build"); - view_listener_t::addMenu(new LLLandSit(), "Land.Sit"); + enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); + enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1)); + enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); + enable.add("Object.EnableWear", boost::bind(&object_is_wearable)); + + enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); + enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); + + view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); + enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance())); + view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); + + enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute)); + enable.add("Object.EnableMute", boost::bind(&enable_object_mute)); + enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute)); + enable.add("Object.EnableBuy", boost::bind(&enable_buy_object)); + commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom")); + + // Attachment pie menu + enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2)); + view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop"); + view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint"); + view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach"); + view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled"); + view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop"); + view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach"); + + // Land pie menu + view_listener_t::addMenu(new LLLandBuild(), "Land.Build"); + view_listener_t::addMenu(new LLLandSit(), "Land.Sit"); view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit"); - view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass"); - view_listener_t::addMenu(new LLLandEdit(), "Land.Edit"); - - // Particle muting - view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute"); - - view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass"); - commit.add("Land.Buy", boost::bind(&handle_buy_land)); - - // Generic actions - commit.add("ReportAbuse", boost::bind(&handle_report_abuse)); - commit.add("BuyCurrency", boost::bind(&handle_buy_currency)); - view_listener_t::addMenu(new LLShowHelp(), "ShowHelp"); - view_listener_t::addMenu(new LLToggleHelp(), "ToggleHelp"); - view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak"); - view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL"); - view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile"); + view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass"); + view_listener_t::addMenu(new LLLandEdit(), "Land.Edit"); + + // Particle muting + view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute"); + + view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass"); + commit.add("Land.Buy", boost::bind(&handle_buy_land)); + + // Generic actions + commit.add("ReportAbuse", boost::bind(&handle_report_abuse)); + commit.add("BuyCurrency", boost::bind(&handle_buy_currency)); + view_listener_t::addMenu(new LLShowHelp(), "ShowHelp"); + view_listener_t::addMenu(new LLToggleHelp(), "ToggleHelp"); + view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak"); + view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL"); + view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile"); view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks"); - view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile"); - view_listener_t::addMenu(new LLToggleControl(), "ToggleControl"); + view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile"); + view_listener_t::addMenu(new LLToggleControl(), "ToggleControl"); view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl"); - view_listener_t::addMenu(new LLCheckControl(), "CheckControl"); - view_listener_t::addMenu(new LLGoToObject(), "GoToObject"); - commit.add("PayObject", boost::bind(&handle_give_money_dialog)); - - commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow)); - - enable.add("EnablePayObject", boost::bind(&enable_pay_object)); - enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar)); - enable.add("EnableEdit", boost::bind(&enable_object_edit)); - enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle)); - enable.add("VisibleBuild", boost::bind(&enable_object_build)); - commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects)); - enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets)); - enable.add("VisibleSelectInPathfindingLinksets", boost::bind(&visible_object_select_in_pathfinding_linksets)); - commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects)); - enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters)); + view_listener_t::addMenu(new LLCheckControl(), "CheckControl"); + view_listener_t::addMenu(new LLGoToObject(), "GoToObject"); + commit.add("PayObject", boost::bind(&handle_give_money_dialog)); + + commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow)); + + enable.add("EnablePayObject", boost::bind(&enable_pay_object)); + enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar)); + enable.add("EnableEdit", boost::bind(&enable_object_edit)); + enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle)); + enable.add("VisibleBuild", boost::bind(&enable_object_build)); + commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects)); + enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets)); + enable.add("VisibleSelectInPathfindingLinksets", boost::bind(&visible_object_select_in_pathfinding_linksets)); + commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects)); + enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters)); enable.add("Advanced.EnableErrorOSException", boost::bind(&enable_os_exception)); - view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible"); - view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel"); - view_listener_t::addMenu(new LLSidetrayPanelVisible(), "SidetrayPanelVisible"); - view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected"); - view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD"); - view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected"); - view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono"); - view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints"); + view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible"); + view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel"); + view_listener_t::addMenu(new LLSidetrayPanelVisible(), "SidetrayPanelVisible"); + view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected"); + view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD"); + view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected"); + view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono"); + view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints"); } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 240c756411..6283a13148 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewermenufile.cpp * @brief "File" menu in the main menu bar. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,17 +47,17 @@ #include "llimagej2c.h" #include "llimagejpeg.h" #include "llimagetga.h" -#include "llinventorymodel.h" // gInventory +#include "llinventorymodel.h" // gInventory #include "llpluginclassmedia.h" #include "llresourcedata.h" #include "llstatusbar.h" #include "lltinygltfhelper.h" #include "lltoast.h" -#include "llviewercontrol.h" // gSavedSettings +#include "llviewercontrol.h" // gSavedSettings #include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerinventory.h" -#include "llviewermenu.h" // gMenuHolder +#include "llviewermenu.h" // gMenuHolder #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" @@ -83,24 +83,24 @@ class LLFileEnableUpload : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { return true; - } + } }; class LLFileEnableUploadModel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model"); - if (fmp && fmp->isModelLoading()) - { - return false; - } - - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model"); + if (fmp && fmp->isModelLoading()) + { + return false; + } + + return true; + } }; class LLFileEnableUploadMaterial : public view_listener_t @@ -118,18 +118,18 @@ class LLFileEnableUploadMaterial : public view_listener_t class LLMeshEnabled : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gSavedSettings.getBOOL("MeshEnabled"); - } + bool handleEvent(const LLSD& userdata) + { + return gSavedSettings.getBOOL("MeshEnabled"); + } }; class LLMeshUploadVisible : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - return gMeshRepo.meshUploadEnabled(); - } + bool handleEvent(const LLSD& userdata) + { + return gMeshRepo.meshUploadEnabled(); + } }; LLMutex* LLFilePickerThread::sMutex = NULL; @@ -139,51 +139,51 @@ void LLFilePickerThread::getFile() { #if LL_WINDOWS // Todo: get rid of LLFilePickerThread and make this modeless - start(); + start(); #elif LL_DARWIN runModeless(); #else - run(); + run(); #endif } -//virtual +//virtual void LLFilePickerThread::run() { #if LL_WINDOWS - bool blocking = false; + bool blocking = false; #else - bool blocking = true; // modal + bool blocking = true; // modal #endif - LLFilePicker picker; - - if (mIsSaveDialog) - { - if (picker.getSaveFile(mSaveFilter, mProposedName, blocking)) - { - mResponses.push_back(picker.getFirstFile()); - } - } - else - { - bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking); - if (result) - { - std::string filename = picker.getFirstFile(); // consider copying mFiles directly - do - { - mResponses.push_back(filename); - filename = picker.getNextFile(); - } - while (mIsGetMultiple && !filename.empty()); - } - } - - { - LLMutexLock lock(sMutex); - sDeadQ.push(this); - } + LLFilePicker picker; + + if (mIsSaveDialog) + { + if (picker.getSaveFile(mSaveFilter, mProposedName, blocking)) + { + mResponses.push_back(picker.getFirstFile()); + } + } + else + { + bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking); + if (result) + { + std::string filename = picker.getFirstFile(); // consider copying mFiles directly + do + { + mResponses.push_back(filename); + filename = picker.getNextFile(); + } + while (mIsGetMultiple && !filename.empty()); + } + } + + { + LLMutexLock lock(sMutex); + sDeadQ.push(this); + } } void LLFilePickerThread::runModeless() @@ -206,7 +206,7 @@ void LLFilePickerThread::runModeless() { result = picker.getOpenFileModeless(mLoadFilter, modelessVectorCallback, this); } - + if (!result) { LLMutexLock lock(sMutex); @@ -223,7 +223,7 @@ void LLFilePickerThread::modelessStringCallback(bool success, { picker->mResponses.push_back(response); } - + { LLMutexLock lock(sMutex); sDeadQ.push(picker); @@ -255,7 +255,7 @@ void LLFilePickerThread::modelessVectorCallback(bool success, } } } - + { LLMutexLock lock(sMutex); sDeadQ.push(picker); @@ -265,66 +265,66 @@ void LLFilePickerThread::modelessVectorCallback(bool success, //static void LLFilePickerThread::initClass() { - sMutex = new LLMutex(); + sMutex = new LLMutex(); } //static void LLFilePickerThread::cleanupClass() { - clearDead(); - - delete sMutex; - sMutex = NULL; + clearDead(); + + delete sMutex; + sMutex = NULL; } //static void LLFilePickerThread::clearDead() { - if (!sDeadQ.empty()) - { - LLMutexLock lock(sMutex); - while (!sDeadQ.empty()) - { - LLFilePickerThread* thread = sDeadQ.front(); - thread->notify(thread->mResponses); - delete thread; - sDeadQ.pop(); - } - } + if (!sDeadQ.empty()) + { + LLMutexLock lock(sMutex); + while (!sDeadQ.empty()) + { + LLFilePickerThread* thread = sDeadQ.front(); + thread->notify(thread->mResponses); + delete thread; + sDeadQ.pop(); + } + } } LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb) - : LLFilePickerThread(filter, get_multiple), - mLoadFilter(filter), - mSaveFilter(LLFilePicker::FFSAVE_ALL), - mFilePickedSignal(NULL), - mFailureSignal(NULL) + : LLFilePickerThread(filter, get_multiple), + mLoadFilter(filter), + mSaveFilter(LLFilePicker::FFSAVE_ALL), + mFilePickedSignal(NULL), + mFailureSignal(NULL) { - mFilePickedSignal = new file_picked_signal_t(); - mFilePickedSignal->connect(cb); + mFilePickedSignal = new file_picked_signal_t(); + mFilePickedSignal->connect(cb); - mFailureSignal = new file_picked_signal_t(); - mFailureSignal->connect(failure_cb); + mFailureSignal = new file_picked_signal_t(); + mFailureSignal->connect(failure_cb); } LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb) - : LLFilePickerThread(filter, proposed_name), - mLoadFilter(LLFilePicker::FFLOAD_ALL), - mSaveFilter(filter), - mFilePickedSignal(NULL), - mFailureSignal(NULL) + : LLFilePickerThread(filter, proposed_name), + mLoadFilter(LLFilePicker::FFLOAD_ALL), + mSaveFilter(filter), + mFilePickedSignal(NULL), + mFailureSignal(NULL) { - mFilePickedSignal = new file_picked_signal_t(); - mFilePickedSignal->connect(cb); + mFilePickedSignal = new file_picked_signal_t(); + mFilePickedSignal->connect(cb); - mFailureSignal = new file_picked_signal_t(); - mFailureSignal->connect(failure_cb); + mFailureSignal = new file_picked_signal_t(); + mFailureSignal->connect(failure_cb); } LLFilePickerReplyThread::~LLFilePickerReplyThread() { - delete mFilePickedSignal; - delete mFailureSignal; + delete mFilePickedSignal; + delete mFailureSignal; } void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type & failure_cb) @@ -339,20 +339,20 @@ void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type void LLFilePickerReplyThread::notify(const std::vector& filenames) { - if (filenames.empty()) - { - if (mFailureSignal) - { - (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter); - } - } - else - { - if (mFilePickedSignal) - { - (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter); - } - } + if (filenames.empty()) + { + if (mFailureSignal) + { + (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter); + } + } + else + { + if (mFilePickedSignal) + { + (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter); + } + } } @@ -389,164 +389,164 @@ static std::string MATERIAL_EXTENSIONS = "gltf glb"; std::string build_extensions_string(LLFilePicker::ELoadFilter filter) { - switch(filter) - { + switch(filter) + { #if LL_WINDOWS - case LLFilePicker::FFLOAD_IMAGE: - return IMAGE_EXTENSIONS; - case LLFilePicker::FFLOAD_WAV: - return SOUND_EXTENSIONS; - case LLFilePicker::FFLOAD_ANIM: - return ANIM_EXTENSIONS; - case LLFilePicker::FFLOAD_SLOBJECT: - return SLOBJECT_EXTENSIONS; - case LLFilePicker::FFLOAD_MODEL: - return MODEL_EXTENSIONS; + case LLFilePicker::FFLOAD_IMAGE: + return IMAGE_EXTENSIONS; + case LLFilePicker::FFLOAD_WAV: + return SOUND_EXTENSIONS; + case LLFilePicker::FFLOAD_ANIM: + return ANIM_EXTENSIONS; + case LLFilePicker::FFLOAD_SLOBJECT: + return SLOBJECT_EXTENSIONS; + case LLFilePicker::FFLOAD_MODEL: + return MODEL_EXTENSIONS; case LLFilePicker::FFLOAD_MATERIAL: return MATERIAL_EXTENSIONS; - case LLFilePicker::FFLOAD_XML: - return XML_EXTENSIONS; + case LLFilePicker::FFLOAD_XML: + return XML_EXTENSIONS; case LLFilePicker::FFLOAD_ALL: case LLFilePicker::FFLOAD_EXE: - return ALL_FILE_EXTENSIONS; + return ALL_FILE_EXTENSIONS; #endif default: - return ALL_FILE_EXTENSIONS; - } + return ALL_FILE_EXTENSIONS; + } } const bool check_file_extension(const std::string& filename, LLFilePicker::ELoadFilter type) { - std::string ext = gDirUtilp->getExtension(filename); - - //strincmp doesn't like NULL pointers - if (ext.empty()) - { - std::string short_name = gDirUtilp->getBaseFileName(filename); - - // No extension - LLSD args; - args["FILE"] = short_name; - LLNotificationsUtil::add("NoFileExtension", args); - return false; - } - else - { - //so there is an extension - //loop over the valid extensions and compare to see - //if the extension is valid - - //now grab the set of valid file extensions - std::string valid_extensions = build_extensions_string(type); - - BOOL ext_valid = FALSE; - - typedef boost::tokenizer > tokenizer; - boost::char_separator sep(" "); - tokenizer tokens(valid_extensions, sep); - tokenizer::iterator token_iter; - - //now loop over all valid file extensions - //and compare them to the extension of the file - //to be uploaded - for (token_iter = tokens.begin(); - token_iter != tokens.end() && ext_valid != TRUE; - ++token_iter) - { - const std::string& cur_token = *token_iter; - - if (cur_token == ext || cur_token == "*.*") - { - //valid extension - //or the acceptable extension is any - ext_valid = TRUE; - } - }//end for (loop over all tokens) - - if (ext_valid == FALSE) - { - //should only get here if the extension exists - //but is invalid - LLSD args; - args["EXTENSION"] = ext; - args["VALIDS"] = valid_extensions; - LLNotificationsUtil::add("InvalidFileExtension", args); - return false; - } - }//end else (non-null extension) - return true; + std::string ext = gDirUtilp->getExtension(filename); + + //strincmp doesn't like NULL pointers + if (ext.empty()) + { + std::string short_name = gDirUtilp->getBaseFileName(filename); + + // No extension + LLSD args; + args["FILE"] = short_name; + LLNotificationsUtil::add("NoFileExtension", args); + return false; + } + else + { + //so there is an extension + //loop over the valid extensions and compare to see + //if the extension is valid + + //now grab the set of valid file extensions + std::string valid_extensions = build_extensions_string(type); + + BOOL ext_valid = FALSE; + + typedef boost::tokenizer > tokenizer; + boost::char_separator sep(" "); + tokenizer tokens(valid_extensions, sep); + tokenizer::iterator token_iter; + + //now loop over all valid file extensions + //and compare them to the extension of the file + //to be uploaded + for (token_iter = tokens.begin(); + token_iter != tokens.end() && ext_valid != TRUE; + ++token_iter) + { + const std::string& cur_token = *token_iter; + + if (cur_token == ext || cur_token == "*.*") + { + //valid extension + //or the acceptable extension is any + ext_valid = TRUE; + } + }//end for (loop over all tokens) + + if (ext_valid == FALSE) + { + //should only get here if the extension exists + //but is invalid + LLSD args; + args["EXTENSION"] = ext; + args["VALIDS"] = valid_extensions; + LLNotificationsUtil::add("InvalidFileExtension", args); + return false; + } + }//end else (non-null extension) + return true; } const void upload_single_file(const std::vector& filenames, LLFilePicker::ELoadFilter type) { - std::string filename = filenames[0]; - if (!check_file_extension(filename, type)) return; - - if (!filename.empty()) - { - if (type == LLFilePicker::FFLOAD_WAV) - { - // pre-qualify wavs to make sure the format is acceptable - std::string error_msg; - if (check_for_invalid_wav_formats(filename, error_msg)) - { - LL_INFOS() << error_msg << ": " << filename << LL_ENDL; - LLSD args; - args["FILE"] = filename; - LLNotificationsUtil::add(error_msg, args); - return; - } - else - { - LLFloaterReg::showInstance("upload_sound", LLSD(filename)); - } - } - if (type == LLFilePicker::FFLOAD_IMAGE) - { - LLFloaterReg::showInstance("upload_image", LLSD(filename)); - } - if (type == LLFilePicker::FFLOAD_ANIM) - { - std::string filename_lc(filename); - LLStringUtil::toLower(filename_lc); - if (filename_lc.rfind(".anim") != std::string::npos) - { - LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); - } - else - { - LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); - } - } - } - return; + std::string filename = filenames[0]; + if (!check_file_extension(filename, type)) return; + + if (!filename.empty()) + { + if (type == LLFilePicker::FFLOAD_WAV) + { + // pre-qualify wavs to make sure the format is acceptable + std::string error_msg; + if (check_for_invalid_wav_formats(filename, error_msg)) + { + LL_INFOS() << error_msg << ": " << filename << LL_ENDL; + LLSD args; + args["FILE"] = filename; + LLNotificationsUtil::add(error_msg, args); + return; + } + else + { + LLFloaterReg::showInstance("upload_sound", LLSD(filename)); + } + } + if (type == LLFilePicker::FFLOAD_IMAGE) + { + LLFloaterReg::showInstance("upload_image", LLSD(filename)); + } + if (type == LLFilePicker::FFLOAD_ANIM) + { + std::string filename_lc(filename); + LLStringUtil::toLower(filename_lc); + if (filename_lc.rfind(".anim") != std::string::npos) + { + LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); + } + else + { + LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); + } + } + } + return; } void do_bulk_upload(std::vector filenames, const LLSD& notification, const LLSD& response) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // Cancel upload - return; - } - - for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) - { - std::string filename = (*in_iter); - - std::string name = gDirUtilp->getBaseFileName(filename, true); - std::string asset_name = name; - LLStringUtil::replaceNonstandardASCII(asset_name, '?'); - LLStringUtil::replaceChar(asset_name, '|', '?'); - LLStringUtil::stripNonprintable(asset_name); - LLStringUtil::trim(asset_name); - - std::string ext = gDirUtilp->getExtension(filename); - LLAssetType::EType asset_type; - U32 codec; - S32 expected_upload_cost = 0; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // Cancel upload + return; + } + + for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) + { + std::string filename = (*in_iter); + + std::string name = gDirUtilp->getBaseFileName(filename, true); + std::string asset_name = name; + LLStringUtil::replaceNonstandardASCII(asset_name, '?'); + LLStringUtil::replaceChar(asset_name, '|', '?'); + LLStringUtil::stripNonprintable(asset_name); + LLStringUtil::trim(asset_name); + + std::string ext = gDirUtilp->getExtension(filename); + LLAssetType::EType asset_type; + U32 codec; + S32 expected_upload_cost = 0; if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec)) { @@ -603,25 +603,25 @@ void do_bulk_upload(std::vector filenames, const LLSD& notification bool get_bulk_upload_expected_cost(const std::vector& filenames, S32& total_cost, S32& file_count, S32& bvh_count) { - total_cost = 0; - file_count = 0; - bvh_count = 0; - for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) - { - std::string filename = (*in_iter); - std::string ext = gDirUtilp->getExtension(filename); - - if (ext == "bvh") - { - bvh_count++; - } - - LLAssetType::EType asset_type; - U32 codec; - S32 cost; - - if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec)) - { + total_cost = 0; + file_count = 0; + bvh_count = 0; + for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) + { + std::string filename = (*in_iter); + std::string ext = gDirUtilp->getExtension(filename); + + if (ext == "bvh") + { + bvh_count++; + } + + LLAssetType::EType asset_type; + U32 codec; + S32 cost; + + if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec)) + { if (asset_type == LLAssetType::AT_TEXTURE) { LLPointer image_frmted = LLImageFormatted::createFromType(codec); @@ -677,87 +677,87 @@ bool get_bulk_upload_expected_cost(const std::vector& filenames, S3 } } } - } - + } + return file_count > 0; } const void upload_bulk(const std::vector& filenames, LLFilePicker::ELoadFilter type) { - // TODO: - // Check user balance for entire cost - // Charge user entire cost - // Loop, uploading - // If an upload fails, refund the user for that one - // - // Also fix single upload to charge first, then refund - - // FIXME PREMIUM what about known types that can't be bulk uploaded - // (bvh)? These will fail in the item by item upload but won't be - // mentioned in the notification. - std::vector filtered_filenames; - for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) - { - const std::string& filename = *in_iter; - if (check_file_extension(filename, type)) - { - filtered_filenames.push_back(filename); - } - } - - S32 expected_upload_cost; - S32 expected_upload_count; - S32 bvh_count; - if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count)) - { - LLSD args; - args["COST"] = expected_upload_cost; - args["COUNT"] = expected_upload_count; - LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2)); - - if (filtered_filenames.size() > expected_upload_count) - { - if (bvh_count == filtered_filenames.size() - expected_upload_count) - { - LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); - } - else - { - LLNotificationsUtil::add("BulkUploadIncompatibleFiles"); - } - } - } - else if (bvh_count == filtered_filenames.size()) - { - LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); - } - else - { - LLNotificationsUtil::add("BulkUploadNoCompatibleFiles"); - } + // TODO: + // Check user balance for entire cost + // Charge user entire cost + // Loop, uploading + // If an upload fails, refund the user for that one + // + // Also fix single upload to charge first, then refund + + // FIXME PREMIUM what about known types that can't be bulk uploaded + // (bvh)? These will fail in the item by item upload but won't be + // mentioned in the notification. + std::vector filtered_filenames; + for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) + { + const std::string& filename = *in_iter; + if (check_file_extension(filename, type)) + { + filtered_filenames.push_back(filename); + } + } + + S32 expected_upload_cost; + S32 expected_upload_count; + S32 bvh_count; + if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count)) + { + LLSD args; + args["COST"] = expected_upload_cost; + args["COUNT"] = expected_upload_count; + LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2)); + + if (filtered_filenames.size() > expected_upload_count) + { + if (bvh_count == filtered_filenames.size() - expected_upload_count) + { + LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); + } + else + { + LLNotificationsUtil::add("BulkUploadIncompatibleFiles"); + } + } + } + else if (bvh_count == filtered_filenames.size()) + { + LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload"); + } + else + { + LLNotificationsUtil::add("BulkUploadNoCompatibleFiles"); + } } class LLFileUploadImage : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToDefault(); - } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false); - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToDefault(); + } + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false); + return true; + } }; class LLFileUploadModel : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { LLFloaterModelPreview::showModelPreview(); return TRUE; - } + } }; class LLFileUploadMaterial : public view_listener_t @@ -771,213 +771,213 @@ class LLFileUploadMaterial : public view_listener_t class LLFileUploadSound : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToDefault(); - } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false); - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToDefault(); + } + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false); + return true; + } }; class LLFileUploadAnim : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToDefault(); - } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false); - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToDefault(); + } + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false); + return true; + } }; class LLFileUploadBulk : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - if (gAgentCamera.cameraMouselook()) - { - gAgentCamera.changeCameraToDefault(); - } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true); - return true; - } + bool handleEvent(const LLSD& userdata) + { + if (gAgentCamera.cameraMouselook()) + { + gAgentCamera.changeCameraToDefault(); + } + LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true); + return true; + } }; -void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args) +void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args) { - LL_WARNS() << error_message << LL_ENDL; - LLNotificationsUtil::add(label, args); - if(LLFile::remove(filename) == -1) - { - LL_DEBUGS() << "unable to remove temp file" << LL_ENDL; - } - LLFilePicker::instance().reset(); + LL_WARNS() << error_message << LL_ENDL; + LLNotificationsUtil::add(label, args); + if(LLFile::remove(filename) == -1) + { + LL_DEBUGS() << "unable to remove temp file" << LL_ENDL; + } + LLFilePicker::instance().reset(); } class LLFileEnableCloseWindow : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater()); - bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater()); + bool handleEvent(const LLSD& userdata) + { + bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater()); + bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater()); - return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists); - } + return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists); + } }; class LLFileCloseWindow : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater()); - LLFloater* snapshot_floater = gSnapshotFloaterView->getFrontmostClosableFloater(); - - if(snapshot_floater && (!frontmost_fl_exists || snapshot_floater->hasFocus())) - { - snapshot_floater->closeFloater(); - if (gFocusMgr.getKeyboardFocus() == NULL) - { - gFloaterView->focusFrontFloater(); - } - } - else - { - LLFloater::closeFrontmostFloater(); - } - if (gMenuHolder) gMenuHolder->hideMenus(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater()); + LLFloater* snapshot_floater = gSnapshotFloaterView->getFrontmostClosableFloater(); + + if(snapshot_floater && (!frontmost_fl_exists || snapshot_floater->hasFocus())) + { + snapshot_floater->closeFloater(); + if (gFocusMgr.getKeyboardFocus() == NULL) + { + gFloaterView->focusFrontFloater(); + } + } + else + { + LLFloater::closeFrontmostFloater(); + } + if (gMenuHolder) gMenuHolder->hideMenus(); + return true; + } }; class LLFileEnableCloseAllWindows : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()); - bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; - return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown(); - } + bool handleEvent(const LLSD& userdata) + { + LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); + bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()); + bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; + return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown(); + } }; class LLFileCloseAllWindows : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - bool app_quitting = false; - gFloaterView->closeAllChildren(app_quitting); - LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - if (floater_snapshot) - floater_snapshot->closeFloater(app_quitting); - if (gMenuHolder) gMenuHolder->hideMenus(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + bool app_quitting = false; + gFloaterView->closeAllChildren(app_quitting); + LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); + if (floater_snapshot) + floater_snapshot->closeFloater(app_quitting); + if (gMenuHolder) gMenuHolder->hideMenus(); + return true; + } }; class LLFileTakeSnapshotToDisk : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLPointer raw = new LLImageRaw; - - S32 width = gViewerWindow->getWindowWidthRaw(); - S32 height = gViewerWindow->getWindowHeightRaw(); - - BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot"); - BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot"); - BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost"); - - BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot"); - if (high_res) - { - width *= 2; - height *= 2; - // not compatible with UI/HUD - render_ui = false; - render_hud = false; - } - - if (gViewerWindow->rawSnapshot(raw, - width, - height, - TRUE, - FALSE, - render_ui, - render_hud, - FALSE, - render_no_post, - LLSnapshotModel::SNAPSHOT_TYPE_COLOR, - high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side - { - LLPointer formatted; + bool handleEvent(const LLSD& userdata) + { + LLPointer raw = new LLImageRaw; + + S32 width = gViewerWindow->getWindowWidthRaw(); + S32 height = gViewerWindow->getWindowHeightRaw(); + + BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot"); + BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot"); + BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost"); + + BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot"); + if (high_res) + { + width *= 2; + height *= 2; + // not compatible with UI/HUD + render_ui = false; + render_hud = false; + } + + if (gViewerWindow->rawSnapshot(raw, + width, + height, + TRUE, + FALSE, + render_ui, + render_hud, + FALSE, + render_no_post, + LLSnapshotModel::SNAPSHOT_TYPE_COLOR, + high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side + { + LLPointer formatted; LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); - switch (fmt) - { - case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG: - formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality")); - break; - default: - LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL; - case LLSnapshotModel::SNAPSHOT_FORMAT_PNG: - formatted = new LLImagePNG; - break; - case LLSnapshotModel::SNAPSHOT_FORMAT_BMP: - formatted = new LLImageBMP; - break; - } - formatted->enableOverSize() ; - formatted->encode(raw, 0); - formatted->disableOverSize() ; - LLSnapshotLivePreview::saveLocal(formatted); - } - return true; - } + switch (fmt) + { + case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG: + formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality")); + break; + default: + LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL; + case LLSnapshotModel::SNAPSHOT_FORMAT_PNG: + formatted = new LLImagePNG; + break; + case LLSnapshotModel::SNAPSHOT_FORMAT_BMP: + formatted = new LLImageBMP; + break; + } + formatted->enableOverSize() ; + formatted->encode(raw, 0); + formatted->disableOverSize() ; + LLSnapshotLivePreview::saveLocal(formatted); + } + return true; + } }; class LLFileQuit : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { - LLAppViewer::instance()->userQuit(); - return true; - } + bool handleEvent(const LLSD& userdata) + { + LLAppViewer::instance()->userQuit(); + return true; + } }; void handle_compress_image(void*) { - LLFilePicker& picker = LLFilePicker::instance(); - if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE)) - { - std::string infile = picker.getFirstFile(); - while (!infile.empty()) - { - std::string outfile = infile + ".j2c"; - - LL_INFOS() << "Input: " << infile << LL_ENDL; - LL_INFOS() << "Output: " << outfile << LL_ENDL; - - BOOL success; - - success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA); - - if (success) - { - LL_INFOS() << "Compression complete" << LL_ENDL; - } - else - { - LL_INFOS() << "Compression failed: " << LLImage::getLastError() << LL_ENDL; - } - - infile = picker.getNextFile(); - } - } + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE)) + { + std::string infile = picker.getFirstFile(); + while (!infile.empty()) + { + std::string outfile = infile + ".j2c"; + + LL_INFOS() << "Input: " << infile << LL_ENDL; + LL_INFOS() << "Output: " << outfile << LL_ENDL; + + BOOL success; + + success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA); + + if (success) + { + LL_INFOS() << "Compression complete" << LL_ENDL; + } + else + { + LL_INFOS() << "Compression failed: " << LLImage::getLastError() << LL_ENDL; + } + + infile = picker.getNextFile(); + } + } } // No convinient check in LLFile, and correct way would be something @@ -985,7 +985,7 @@ void handle_compress_image(void*) // so doing dirty, but OS independent fopen and fseek size_t get_file_size(std::string &filename) { - LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ + LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ if (!file) { LL_WARNS() << "Error opening " << filename << LL_ENDL; @@ -1070,21 +1070,21 @@ void handle_compress_file_test(void*) LLUUID upload_new_resource( - const std::string& src_filename, - std::string name, - std::string desc, - S32 compression_info, - LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perms, - U32 group_perms, - U32 everyone_perms, - const std::string& display_name, - LLAssetStorage::LLStoreAssetCallback callback, - S32 expected_upload_cost, - void *userdata, - bool show_inventory) -{ + const std::string& src_filename, + std::string name, + std::string desc, + S32 compression_info, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, + const std::string& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + S32 expected_upload_cost, + void *userdata, + bool show_inventory) +{ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( src_filename, @@ -1098,127 +1098,127 @@ LLUUID upload_new_resource( } void upload_done_callback( - const LLUUID& uuid, - void* user_data, - S32 result, - LLExtStat ext_status) // StoreAssetData callback (fixed) + const LLUUID& uuid, + void* user_data, + S32 result, + LLExtStat ext_status) // StoreAssetData callback (fixed) { - LLResourceData* data = (LLResourceData*)user_data; - S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0; - //LLAssetType::EType pref_loc = data->mPreferredLocation; - BOOL is_balance_sufficient = TRUE; - - if(data) - { - if (result >= 0) - { - LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation; - - if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || - LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || - LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) - { - // Charge the user for the upload. - LLViewerRegion* region = gAgent.getRegion(); - - if(!(can_afford_transaction(expected_upload_cost))) - { - LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost ); - is_balance_sufficient = FALSE; - } - else if(region) - { - // Charge user for upload - gStatusBar->debitBalance(expected_upload_cost); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MoneyTransferRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_MoneyData); - msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); - msg->addU8("Flags", 0); - // we tell the sim how much we were expecting to pay so it - // can respond to any discrepancy - msg->addS32Fast(_PREHASH_Amount, expected_upload_cost); - msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); - msg->addStringFast(_PREHASH_Description, NULL); - msg->sendReliable(region->getHost()); - } - } - - if(is_balance_sufficient) - { - // Actually add the upload to inventory - LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL; - const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc); - if(folder_id.notNull()) - { - U32 next_owner_perms = data->mNextOwnerPerm; - if(PERM_NONE == next_owner_perms) - { - next_owner_perms = PERM_MOVE | PERM_TRANSFER; - } - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), - data->mAssetInfo.getDescription(), data->mAssetInfo.mType, + LLResourceData* data = (LLResourceData*)user_data; + S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0; + //LLAssetType::EType pref_loc = data->mPreferredLocation; + BOOL is_balance_sufficient = TRUE; + + if(data) + { + if (result >= 0) + { + LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation; + + if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || + LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || + LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) + { + // Charge the user for the upload. + LLViewerRegion* region = gAgent.getRegion(); + + if(!(can_afford_transaction(expected_upload_cost))) + { + LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost ); + is_balance_sufficient = FALSE; + } + else if(region) + { + // Charge user for upload + gStatusBar->debitBalance(expected_upload_cost); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyTransferRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); + msg->addU8("Flags", 0); + // we tell the sim how much we were expecting to pay so it + // can respond to any discrepancy + msg->addS32Fast(_PREHASH_Amount, expected_upload_cost); + msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); + msg->addStringFast(_PREHASH_Description, NULL); + msg->sendReliable(region->getHost()); + } + } + + if(is_balance_sufficient) + { + // Actually add the upload to inventory + LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL; + const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc); + if(folder_id.notNull()) + { + U32 next_owner_perms = data->mNextOwnerPerm; + if(PERM_NONE == next_owner_perms) + { + next_owner_perms = PERM_MOVE | PERM_TRANSFER; + } + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), + data->mAssetInfo.getDescription(), data->mAssetInfo.mType, data->mInventoryType, NO_INV_SUBTYPE, next_owner_perms, - LLPointer(NULL)); - } - else - { - LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; - } - } - } - else // if(result >= 0) - { - LLSD args; - args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); - args["REASON"] = std::string(LLAssetStorage::getErrorString(result)); - LLNotificationsUtil::add("CannotUploadReason", args); - } - - delete data; - data = NULL; - } - - LLUploadDialog::modalUploadFinished(); - - // *NOTE: This is a pretty big hack. What this does is check the - // file picker if there are any more pending uploads. If so, - // upload that file. - const std::string& next_file = LLFilePicker::instance().getNextFile(); - if(is_balance_sufficient && !next_file.empty()) - { - std::string asset_name = gDirUtilp->getBaseFileName(next_file, true); - LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); - LLStringUtil::replaceChar(asset_name, '|', '?'); - LLStringUtil::stripNonprintable(asset_name); - LLStringUtil::trim(asset_name); - - std::string display_name = LLStringUtil::null; - LLAssetStorage::LLStoreAssetCallback callback; - void *userdata = NULL; - upload_new_resource( - next_file, - asset_name, - asset_name, // file - 0, - LLFolderType::FT_NONE, - LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - display_name, - callback, - expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost - userdata); - } + LLPointer(NULL)); + } + else + { + LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; + } + } + } + else // if(result >= 0) + { + LLSD args; + args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); + args["REASON"] = std::string(LLAssetStorage::getErrorString(result)); + LLNotificationsUtil::add("CannotUploadReason", args); + } + + delete data; + data = NULL; + } + + LLUploadDialog::modalUploadFinished(); + + // *NOTE: This is a pretty big hack. What this does is check the + // file picker if there are any more pending uploads. If so, + // upload that file. + const std::string& next_file = LLFilePicker::instance().getNextFile(); + if(is_balance_sufficient && !next_file.empty()) + { + std::string asset_name = gDirUtilp->getBaseFileName(next_file, true); + LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); + LLStringUtil::replaceChar(asset_name, '|', '?'); + LLStringUtil::stripNonprintable(asset_name); + LLStringUtil::trim(asset_name); + + std::string display_name = LLStringUtil::null; + LLAssetStorage::LLStoreAssetCallback callback; + void *userdata = NULL; + upload_new_resource( + next_file, + asset_name, + asset_name, // file + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + display_name, + callback, + expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost + userdata); + } } void upload_new_resource( @@ -1226,90 +1226,90 @@ void upload_new_resource( LLAssetStorage::LLStoreAssetCallback callback, void *userdata) { - if(gDisconnected) - { - return ; - } + if(gDisconnected) + { + return ; + } // uploadInfo->setAssetType(assetType); // uploadInfo->setTransactionId(tid); - std::string url = gAgent.getRegionCapability("NewFileAgentInventory"); + std::string url = gAgent.getRegionCapability("NewFileAgentInventory"); - if ( !url.empty() ) - { + if ( !url.empty() ) + { LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - } - else - { + } + else + { uploadInfo->prepareUpload(); uploadInfo->logPreparedUpload(); - LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL; - // check for adequate funds - // TODO: do this check on the sim - if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() || + LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL; + // check for adequate funds + // TODO: do this check on the sim + if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() || LLAssetType::AT_TEXTURE == uploadInfo->getAssetType() || LLAssetType::AT_ANIMATION == uploadInfo->getAssetType()) - { - S32 balance = gStatusBar->getBalance(); - if (balance < uploadInfo->getExpectedUploadCost()) - { - // insufficient funds, bail on this upload + { + S32 balance = gStatusBar->getBalance(); + if (balance < uploadInfo->getExpectedUploadCost()) + { + // insufficient funds, bail on this upload LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost()); - return; - } - } + return; + } + } - LLResourceData* data = new LLResourceData; - data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId(); - data->mAssetInfo.mUuid = uploadInfo->getAssetId(); + LLResourceData* data = new LLResourceData; + data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId(); + data->mAssetInfo.mUuid = uploadInfo->getAssetId(); data->mAssetInfo.mType = uploadInfo->getAssetType(); - data->mAssetInfo.mCreatorID = gAgentID; - data->mInventoryType = uploadInfo->getInventoryType(); - data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms(); - data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost(); - data->mUserData = userdata; - data->mAssetInfo.setName(uploadInfo->getName()); - data->mAssetInfo.setDescription(uploadInfo->getDescription()); - data->mPreferredLocation = uploadInfo->getDestinationFolderType(); - - LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback; - if (callback) - { - asset_callback = callback; - } - gAssetStorage->storeAssetData( - data->mAssetInfo.mTransactionID, - data->mAssetInfo.mType, - asset_callback, - (void*)data, - FALSE); - } + data->mAssetInfo.mCreatorID = gAgentID; + data->mInventoryType = uploadInfo->getInventoryType(); + data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms(); + data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost(); + data->mUserData = userdata; + data->mAssetInfo.setName(uploadInfo->getName()); + data->mAssetInfo.setDescription(uploadInfo->getDescription()); + data->mPreferredLocation = uploadInfo->getDestinationFolderType(); + + LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback; + if (callback) + { + asset_callback = callback; + } + gAssetStorage->storeAssetData( + data->mAssetInfo.mTransactionID, + data->mAssetInfo.mType, + asset_callback, + (void*)data, + FALSE); + } } void init_menu_file() { - view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage"); - view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound"); - view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim"); - view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel"); + view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage"); + view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound"); + view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim"); + view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel"); view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial"); - view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk"); - view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow"); - view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows"); - view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow"); - view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows"); - view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk"); - view_listener_t::addCommit(new LLFileQuit(), "File.Quit"); - - view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload"); - view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel"); + view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk"); + view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow"); + view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows"); + view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow"); + view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows"); + view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk"); + view_listener_t::addCommit(new LLFileQuit(), "File.Quit"); + + view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload"); + view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel"); view_listener_t::addEnable(new LLFileEnableUploadMaterial(), "File.EnableUploadMaterial"); - view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled"); - view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel"); + view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled"); + view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel"); - // "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled. + // "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled. } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b66d4b1dab..340a1de0d1 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewerobject.cpp * @brief Base class for viewer objects * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -110,24 +110,24 @@ //#define DEBUG_UPDATE_TYPE -BOOL LLViewerObject::sVelocityInterpolate = TRUE; -BOOL LLViewerObject::sPingInterpolate = TRUE; +BOOL LLViewerObject::sVelocityInterpolate = TRUE; +BOOL LLViewerObject::sPingInterpolate = TRUE; -U32 LLViewerObject::sNumZombieObjects = 0; -S32 LLViewerObject::sNumObjects = 0; -BOOL LLViewerObject::sMapDebug = TRUE; -LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK -LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit -S32 LLViewerObject::sAxisArrowLength(50); +U32 LLViewerObject::sNumZombieObjects = 0; +S32 LLViewerObject::sNumObjects = 0; +BOOL LLViewerObject::sMapDebug = TRUE; +LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK +LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit +S32 LLViewerObject::sAxisArrowLength(50); -BOOL LLViewerObject::sPulseEnabled(FALSE); -BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE +BOOL LLViewerObject::sPulseEnabled(FALSE); +BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE // sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime -F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion -F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction -F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing +F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion +F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction +F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing std::map LLViewerObject::sObjectDataMap; @@ -151,194 +151,194 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL; dumpStack("ObjectUpdateStack"); - - LLViewerObject *res = NULL; - - if (gNonInteractive - && pcode != LL_PCODE_LEGACY_AVATAR - && pcode != LL_VO_SURFACE_PATCH - && pcode != LL_VO_WATER - && pcode != LL_VO_VOID_WATER - && pcode != LL_VO_WL_SKY - && pcode != LL_VO_SKY - && pcode != LL_VO_PART_GROUP - ) - { - return res; - } - switch (pcode) - { - case LL_PCODE_VOLUME: - { - res = new LLVOVolume(id, pcode, regionp); break; - break; - } - case LL_PCODE_LEGACY_AVATAR: - { - if (id == gAgentID) - { - if (!gAgentAvatarp) - { - gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp); - gAgentAvatarp->initInstance(); - gAgentWearables.setAvatarObject(gAgentAvatarp); - } - else - { - if (isAgentAvatarValid()) - { - gAgentAvatarp->updateRegion(regionp); - } - } - res = gAgentAvatarp; - } - else if (flags & CO_FLAG_CONTROL_AVATAR) - { + + LLViewerObject *res = NULL; + + if (gNonInteractive + && pcode != LL_PCODE_LEGACY_AVATAR + && pcode != LL_VO_SURFACE_PATCH + && pcode != LL_VO_WATER + && pcode != LL_VO_VOID_WATER + && pcode != LL_VO_WL_SKY + && pcode != LL_VO_SKY + && pcode != LL_VO_PART_GROUP + ) + { + return res; + } + switch (pcode) + { + case LL_PCODE_VOLUME: + { + res = new LLVOVolume(id, pcode, regionp); break; + break; + } + case LL_PCODE_LEGACY_AVATAR: + { + if (id == gAgentID) + { + if (!gAgentAvatarp) + { + gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp); + gAgentAvatarp->initInstance(); + gAgentWearables.setAvatarObject(gAgentAvatarp); + } + else + { + if (isAgentAvatarValid()) + { + gAgentAvatarp->updateRegion(regionp); + } + } + res = gAgentAvatarp; + } + else if (flags & CO_FLAG_CONTROL_AVATAR) + { LLControlAvatar *control_avatar = new LLControlAvatar(id, pcode, regionp); - control_avatar->initInstance(); - res = control_avatar; - } + control_avatar->initInstance(); + res = control_avatar; + } else if (flags & CO_FLAG_UI_AVATAR) { LLUIAvatar *ui_avatar = new LLUIAvatar(id, pcode, regionp); ui_avatar->initInstance(); res = ui_avatar; } - else - { - LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp); - avatar->initInstance(); - res = avatar; - } - break; - } - case LL_PCODE_LEGACY_GRASS: - res = new LLVOGrass(id, pcode, regionp); break; - case LL_PCODE_LEGACY_PART_SYS: -// LL_WARNS() << "Creating old part sys!" << LL_ENDL; -// res = new LLVOPart(id, pcode, regionp); break; - res = NULL; break; - case LL_PCODE_LEGACY_TREE: - res = new LLVOTree(id, pcode, regionp); break; - case LL_PCODE_TREE_NEW: -// LL_WARNS() << "Creating new tree!" << LL_ENDL; -// res = new LLVOTree(id, pcode, regionp); break; - res = NULL; break; - case LL_VO_SURFACE_PATCH: - res = new LLVOSurfacePatch(id, pcode, regionp); break; - case LL_VO_SKY: - res = new LLVOSky(id, pcode, regionp); break; - case LL_VO_VOID_WATER: - res = new LLVOVoidWater(id, pcode, regionp); break; - case LL_VO_WATER: - res = new LLVOWater(id, pcode, regionp); break; - case LL_VO_PART_GROUP: - res = new LLVOPartGroup(id, pcode, regionp); break; - case LL_VO_HUD_PART_GROUP: - res = new LLVOHUDPartGroup(id, pcode, regionp); break; - case LL_VO_WL_SKY: - res = new LLVOWLSky(id, pcode, regionp); break; - default: - LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL; - res = NULL; break; - } - - return res; + else + { + LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp); + avatar->initInstance(); + res = avatar; + } + break; + } + case LL_PCODE_LEGACY_GRASS: + res = new LLVOGrass(id, pcode, regionp); break; + case LL_PCODE_LEGACY_PART_SYS: +// LL_WARNS() << "Creating old part sys!" << LL_ENDL; +// res = new LLVOPart(id, pcode, regionp); break; + res = NULL; break; + case LL_PCODE_LEGACY_TREE: + res = new LLVOTree(id, pcode, regionp); break; + case LL_PCODE_TREE_NEW: +// LL_WARNS() << "Creating new tree!" << LL_ENDL; +// res = new LLVOTree(id, pcode, regionp); break; + res = NULL; break; + case LL_VO_SURFACE_PATCH: + res = new LLVOSurfacePatch(id, pcode, regionp); break; + case LL_VO_SKY: + res = new LLVOSky(id, pcode, regionp); break; + case LL_VO_VOID_WATER: + res = new LLVOVoidWater(id, pcode, regionp); break; + case LL_VO_WATER: + res = new LLVOWater(id, pcode, regionp); break; + case LL_VO_PART_GROUP: + res = new LLVOPartGroup(id, pcode, regionp); break; + case LL_VO_HUD_PART_GROUP: + res = new LLVOHUDPartGroup(id, pcode, regionp); break; + case LL_VO_WL_SKY: + res = new LLVOWLSky(id, pcode, regionp); break; + default: + LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL; + res = NULL; break; + } + + return res; } LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global) -: LLPrimitive(), - mChildList(), - mID(id), - mLocalID(0), - mTotalCRC(0), - mListIndex(-1), - mTEImages(NULL), - mTENormalMaps(NULL), - mTESpecularMaps(NULL), - mbCanSelect(TRUE), - mFlags(0), - mPhysicsShapeType(0), - mPhysicsGravity(0), - mPhysicsFriction(0), - mPhysicsDensity(0), - mPhysicsRestitution(0), - mDrawable(), - mCreateSelected(FALSE), - mRenderMedia(FALSE), - mBestUpdatePrecision(0), - mText(), - mHudText(""), - mHudTextColor(LLColor4::white), +: LLPrimitive(), + mChildList(), + mID(id), + mLocalID(0), + mTotalCRC(0), + mListIndex(-1), + mTEImages(NULL), + mTENormalMaps(NULL), + mTESpecularMaps(NULL), + mbCanSelect(TRUE), + mFlags(0), + mPhysicsShapeType(0), + mPhysicsGravity(0), + mPhysicsFriction(0), + mPhysicsDensity(0), + mPhysicsRestitution(0), + mDrawable(), + mCreateSelected(FALSE), + mRenderMedia(FALSE), + mBestUpdatePrecision(0), + mText(), + mHudText(""), + mHudTextColor(LLColor4::white), mControlAvatar(NULL), - mLastInterpUpdateSecs(0.f), - mLastMessageUpdateSecs(0.f), - mLatestRecvPacketID(0), - mRegionCrossExpire(0), - mData(NULL), - mAudioSourcep(NULL), - mAudioGain(1.f), - mSoundCutOffRadius(0.f), - mAppAngle(0.f), - mPixelArea(1024.f), - mInventory(NULL), - mInventorySerialNum(0), - mExpectedInventorySerialNum(0), - mInvRequestState(INVENTORY_REQUEST_STOPPED), - mInvRequestXFerId(0), - mInventoryDirty(FALSE), - mRegionp(regionp), - mDead(FALSE), - mOrphaned(FALSE), - mUserSelected(FALSE), - mOnActiveList(FALSE), - mOnMap(FALSE), - mStatic(FALSE), - mSeatCount(0), - mNumFaces(0), - mRotTime(0.f), - mAngularVelocityRot(), - mPreviousRotation(), - mAttachmentState(0), - mMedia(NULL), - mClickAction(0), - mObjectCost(0), - mLinksetCost(0), - mPhysicsCost(0), - mLinksetPhysicsCost(0.f), - mCostStale(true), - mPhysicsShapeUnknown(true), - mAttachmentItemID(LLUUID::null), - mLastUpdateType(OUT_UNKNOWN), - mLastUpdateCached(FALSE), - mCachedMuteListUpdateTime(0), - mCachedOwnerInMuteList(false), - mRiggedAttachedWarned(false) -{ - if (!is_global) - { - llassert(mRegionp); - } - - LLPrimitive::init_primitive(pcode); - - // CP: added 12/2/2005 - this was being initialised to 0, not the current frame time - mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds(); - - mPositionRegion = LLVector3(0.f, 0.f, 0.f); - - if (!is_global && mRegionp) - { - mPositionAgent = mRegionp->getOriginAgent(); - } - resetRot(); - - LLViewerObject::sNumObjects++; + mLastInterpUpdateSecs(0.f), + mLastMessageUpdateSecs(0.f), + mLatestRecvPacketID(0), + mRegionCrossExpire(0), + mData(NULL), + mAudioSourcep(NULL), + mAudioGain(1.f), + mSoundCutOffRadius(0.f), + mAppAngle(0.f), + mPixelArea(1024.f), + mInventory(NULL), + mInventorySerialNum(0), + mExpectedInventorySerialNum(0), + mInvRequestState(INVENTORY_REQUEST_STOPPED), + mInvRequestXFerId(0), + mInventoryDirty(FALSE), + mRegionp(regionp), + mDead(FALSE), + mOrphaned(FALSE), + mUserSelected(FALSE), + mOnActiveList(FALSE), + mOnMap(FALSE), + mStatic(FALSE), + mSeatCount(0), + mNumFaces(0), + mRotTime(0.f), + mAngularVelocityRot(), + mPreviousRotation(), + mAttachmentState(0), + mMedia(NULL), + mClickAction(0), + mObjectCost(0), + mLinksetCost(0), + mPhysicsCost(0), + mLinksetPhysicsCost(0.f), + mCostStale(true), + mPhysicsShapeUnknown(true), + mAttachmentItemID(LLUUID::null), + mLastUpdateType(OUT_UNKNOWN), + mLastUpdateCached(FALSE), + mCachedMuteListUpdateTime(0), + mCachedOwnerInMuteList(false), + mRiggedAttachedWarned(false) +{ + if (!is_global) + { + llassert(mRegionp); + } + + LLPrimitive::init_primitive(pcode); + + // CP: added 12/2/2005 - this was being initialised to 0, not the current frame time + mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds(); + + mPositionRegion = LLVector3(0.f, 0.f, 0.f); + + if (!is_global && mRegionp) + { + mPositionAgent = mRegionp->getOriginAgent(); + } + resetRot(); + + LLViewerObject::sNumObjects++; } LLViewerObject::~LLViewerObject() { - deleteTEImages(); + deleteTEImages(); // unhook from reflection probe manager if (mReflectionProbe.notNull()) @@ -347,18 +347,18 @@ LLViewerObject::~LLViewerObject() mReflectionProbe = nullptr; } - if(mInventory) - { - mInventory->clear(); // will deref and delete entries - delete mInventory; - mInventory = NULL; - } + if(mInventory) + { + mInventory->clear(); // will deref and delete entries + delete mInventory; + mInventory = NULL; + } - if (mPartSourcep) - { - mPartSourcep->setDead(); - mPartSourcep = NULL; - } + if (mPartSourcep) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } if (mText) { @@ -367,30 +367,30 @@ LLViewerObject::~LLViewerObject() mText = NULL; } - // Delete memory associated with extra parameters. - std::unordered_map::iterator iter; - for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) - { - if(iter->second != NULL) - { - delete iter->second->data; - delete iter->second; - } - } - mExtraParameterList.clear(); - - for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ; - mNameValuePairs.clear(); - - delete[] mData; - mData = NULL; - - delete mMedia; - mMedia = NULL; - - sNumObjects--; - sNumZombieObjects--; - llassert(mChildList.size() == 0); + // Delete memory associated with extra parameters. + std::unordered_map::iterator iter; + for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) + { + if(iter->second != NULL) + { + delete iter->second->data; + delete iter->second; + } + } + mExtraParameterList.clear(); + + for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ; + mNameValuePairs.clear(); + + delete[] mData; + mData = NULL; + + delete mMedia; + mMedia = NULL; + + sNumObjects--; + sNumZombieObjects--; + llassert(mChildList.size() == 0); llassert(mControlAvatar.isNull()); // Should have been cleaned by now if (mControlAvatar.notNull()) { @@ -399,40 +399,40 @@ LLViewerObject::~LLViewerObject() LL_WARNS() << "Dead object owned a live control avatar" << LL_ENDL; } - clearInventoryListeners(); + clearInventoryListeners(); } void LLViewerObject::deleteTEImages() { - delete[] mTEImages; - mTEImages = NULL; - - if (mTENormalMaps != NULL) - { - delete[] mTENormalMaps; - mTENormalMaps = NULL; - } - - if (mTESpecularMaps != NULL) - { - delete[] mTESpecularMaps; - mTESpecularMaps = NULL; - } + delete[] mTEImages; + mTEImages = NULL; + + if (mTENormalMaps != NULL) + { + delete[] mTENormalMaps; + mTENormalMaps = NULL; + } + + if (mTESpecularMaps != NULL) + { + delete[] mTESpecularMaps; + mTESpecularMaps = NULL; + } } void LLViewerObject::markDead() { - if (!mDead) - { + if (!mDead) + { LL_PROFILE_ZONE_SCOPED; - //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL; - - // Root object of this hierarchy unlinks itself. - if (getParent()) - { - ((LLViewerObject *)getParent())->removeChild(this); - } - LLUUID mesh_id; + //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL; + + // Root object of this hierarchy unlinks itself. + if (getParent()) + { + ((LLViewerObject *)getParent())->removeChild(this); + } + LLUUID mesh_id; { LLVOAvatar *av = getAvatar(); if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) @@ -446,83 +446,83 @@ void LLViewerObject::markDead() unlinkControlAvatar(); } - // Mark itself as dead - mDead = TRUE; - if(mRegionp) - { - mRegionp->removeFromCreatedList(getLocalID()); - } - gObjectList.cleanupReferences(this); - - LLViewerObject *childp; - while (mChildList.size() > 0) - { - childp = mChildList.back(); - if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) - { - //LL_INFOS() << "Marking child " << childp->getLocalID() << " as dead." << LL_ENDL; - childp->setParent(NULL); // LLViewerObject::markDead 1 - childp->markDead(); - } - else - { - // make sure avatar is no longer parented, - // so we can properly set it's position - childp->setDrawableParent(NULL); - ((LLVOAvatar*)childp)->getOffObject(); - childp->setParent(NULL); // LLViewerObject::markDead 2 - } - mChildList.pop_back(); - } - - if (mDrawable.notNull()) - { - // Drawables are reference counted, mark as dead, then nuke the pointer. - mDrawable->markDead(); - mDrawable = NULL; - } - - if (mText) - { - mText->markDead(); - mText = NULL; - } - - if (mIcon) - { - mIcon->markDead(); - mIcon = NULL; - } - - if (mPartSourcep) - { - mPartSourcep->setDead(); - mPartSourcep = NULL; - } - - if (mAudioSourcep) - { - // Do some cleanup - if (gAudiop) - { - gAudiop->cleanupAudioSource(mAudioSourcep); - } - mAudioSourcep = NULL; - } - - if (flagAnimSource()) - { - if (isAgentAvatarValid()) - { - // stop motions associated with this object - gAgentAvatarp->stopMotionFromSource(mID); - } - } - - if (flagCameraSource()) - { - LLFollowCamMgr::getInstance()->removeFollowCamParams(mID); - } + // Mark itself as dead + mDead = TRUE; + if(mRegionp) + { + mRegionp->removeFromCreatedList(getLocalID()); + } + gObjectList.cleanupReferences(this); + + LLViewerObject *childp; + while (mChildList.size() > 0) + { + childp = mChildList.back(); + if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) + { + //LL_INFOS() << "Marking child " << childp->getLocalID() << " as dead." << LL_ENDL; + childp->setParent(NULL); // LLViewerObject::markDead 1 + childp->markDead(); + } + else + { + // make sure avatar is no longer parented, + // so we can properly set it's position + childp->setDrawableParent(NULL); + ((LLVOAvatar*)childp)->getOffObject(); + childp->setParent(NULL); // LLViewerObject::markDead 2 + } + mChildList.pop_back(); + } + + if (mDrawable.notNull()) + { + // Drawables are reference counted, mark as dead, then nuke the pointer. + mDrawable->markDead(); + mDrawable = NULL; + } + + if (mText) + { + mText->markDead(); + mText = NULL; + } + + if (mIcon) + { + mIcon->markDead(); + mIcon = NULL; + } + + if (mPartSourcep) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } + + if (mAudioSourcep) + { + // Do some cleanup + if (gAudiop) + { + gAudiop->cleanupAudioSource(mAudioSourcep); + } + mAudioSourcep = NULL; + } + + if (flagAnimSource()) + { + if (isAgentAvatarValid()) + { + // stop motions associated with this object + gAgentAvatarp->stopMotionFromSource(mID); + } + } + + if (flagCameraSource()) + { + LLFollowCamMgr::getInstance()->removeFollowCamParams(mID); + } if (mReflectionProbe.notNull()) { @@ -530,225 +530,225 @@ void LLViewerObject::markDead() mReflectionProbe = nullptr; } - sNumZombieObjects++; - } + sNumZombieObjects++; + } } void LLViewerObject::dump() const { - LL_INFOS() << "Type: " << pCodeToString(mPrimitiveCode) << LL_ENDL; - LL_INFOS() << "Drawable: " << (LLDrawable *)mDrawable << LL_ENDL; - LL_INFOS() << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << LL_ENDL; - - LL_INFOS() << "Parent: " << getParent() << LL_ENDL; - LL_INFOS() << "ID: " << mID << LL_ENDL; - LL_INFOS() << "LocalID: " << mLocalID << LL_ENDL; - LL_INFOS() << "PositionRegion: " << getPositionRegion() << LL_ENDL; - LL_INFOS() << "PositionAgent: " << getPositionAgent() << LL_ENDL; - LL_INFOS() << "PositionGlobal: " << getPositionGlobal() << LL_ENDL; - LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL; - if (mDrawable.notNull() && - mDrawable->getNumFaces() && - mDrawable->getFace(0)) - { - LLFacePool *poolp = mDrawable->getFace(0)->getPool(); - if (poolp) - { - LL_INFOS() << "Pool: " << poolp << LL_ENDL; - LL_INFOS() << "Pool reference count: " << poolp->mReferences.size() << LL_ENDL; - } - } - //LL_INFOS() << "BoxTree Min: " << mDrawable->getBox()->getMin() << LL_ENDL; - //LL_INFOS() << "BoxTree Max: " << mDrawable->getBox()->getMin() << LL_ENDL; - /* - LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL; - LL_INFOS() << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << LL_ENDL; - LL_INFOS() << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << LL_ENDL; - LL_INFOS() << "AppAngle: " << mAppAngle << LL_ENDL; - LL_INFOS() << "PixelArea: " << mPixelArea << LL_ENDL; - - char buffer[1000]; - char *key; - for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() ) - { - mNameValuePairs[key]->printNameValue(buffer); - LL_INFOS() << buffer << LL_ENDL; - } - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - LL_INFOS() << " child " << child->getID() << LL_ENDL; - } - */ + LL_INFOS() << "Type: " << pCodeToString(mPrimitiveCode) << LL_ENDL; + LL_INFOS() << "Drawable: " << (LLDrawable *)mDrawable << LL_ENDL; + LL_INFOS() << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << LL_ENDL; + + LL_INFOS() << "Parent: " << getParent() << LL_ENDL; + LL_INFOS() << "ID: " << mID << LL_ENDL; + LL_INFOS() << "LocalID: " << mLocalID << LL_ENDL; + LL_INFOS() << "PositionRegion: " << getPositionRegion() << LL_ENDL; + LL_INFOS() << "PositionAgent: " << getPositionAgent() << LL_ENDL; + LL_INFOS() << "PositionGlobal: " << getPositionGlobal() << LL_ENDL; + LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL; + if (mDrawable.notNull() && + mDrawable->getNumFaces() && + mDrawable->getFace(0)) + { + LLFacePool *poolp = mDrawable->getFace(0)->getPool(); + if (poolp) + { + LL_INFOS() << "Pool: " << poolp << LL_ENDL; + LL_INFOS() << "Pool reference count: " << poolp->mReferences.size() << LL_ENDL; + } + } + //LL_INFOS() << "BoxTree Min: " << mDrawable->getBox()->getMin() << LL_ENDL; + //LL_INFOS() << "BoxTree Max: " << mDrawable->getBox()->getMin() << LL_ENDL; + /* + LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL; + LL_INFOS() << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << LL_ENDL; + LL_INFOS() << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << LL_ENDL; + LL_INFOS() << "AppAngle: " << mAppAngle << LL_ENDL; + LL_INFOS() << "PixelArea: " << mPixelArea << LL_ENDL; + + char buffer[1000]; + char *key; + for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() ) + { + mNameValuePairs[key]->printNameValue(buffer); + LL_INFOS() << buffer << LL_ENDL; + } + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + LL_INFOS() << " child " << child->getID() << LL_ENDL; + } + */ } void LLViewerObject::printNameValuePairs() const { - for (name_value_map_t::const_iterator iter = mNameValuePairs.begin(); - iter != mNameValuePairs.end(); iter++) - { - LLNameValue* nv = iter->second; - LL_INFOS() << nv->printNameValue() << LL_ENDL; - } + for (name_value_map_t::const_iterator iter = mNameValuePairs.begin(); + iter != mNameValuePairs.end(); iter++) + { + LLNameValue* nv = iter->second; + LL_INFOS() << nv->printNameValue() << LL_ENDL; + } } void LLViewerObject::initVOClasses() { - // Initialized shared class stuff first. - LLVOAvatar::initClass(); - LLVOTree::initClass(); - LL_INFOS() << "Viewer Object size: " << sizeof(LLViewerObject) << LL_ENDL; - LLVOGrass::initClass(); - LLVOWater::initClass(); - LLVOVolume::initClass(); + // Initialized shared class stuff first. + LLVOAvatar::initClass(); + LLVOTree::initClass(); + LL_INFOS() << "Viewer Object size: " << sizeof(LLViewerObject) << LL_ENDL; + LLVOGrass::initClass(); + LLVOWater::initClass(); + LLVOVolume::initClass(); - initObjectDataMap(); + initObjectDataMap(); } void LLViewerObject::cleanupVOClasses() { - SUBSYSTEM_CLEANUP(LLVOGrass); - SUBSYSTEM_CLEANUP(LLVOWater); - SUBSYSTEM_CLEANUP(LLVOTree); - SUBSYSTEM_CLEANUP(LLVOAvatar); - SUBSYSTEM_CLEANUP(LLVOVolume); + SUBSYSTEM_CLEANUP(LLVOGrass); + SUBSYSTEM_CLEANUP(LLVOWater); + SUBSYSTEM_CLEANUP(LLVOTree); + SUBSYSTEM_CLEANUP(LLVOAvatar); + SUBSYSTEM_CLEANUP(LLVOVolume); - sObjectDataMap.clear(); + sObjectDataMap.clear(); } //object data map for compressed && !OUT_TERSE_IMPROVED //static void LLViewerObject::initObjectDataMap() { - U32 count = 0; + U32 count = 0; - sObjectDataMap["ID"] = count; //full id //LLUUID - count += sizeof(LLUUID); + sObjectDataMap["ID"] = count; //full id //LLUUID + count += sizeof(LLUUID); - sObjectDataMap["LocalID"] = count; //U32 - count += sizeof(U32); + sObjectDataMap["LocalID"] = count; //U32 + count += sizeof(U32); - sObjectDataMap["PCode"] = count; //U8 - count += sizeof(U8); + sObjectDataMap["PCode"] = count; //U8 + count += sizeof(U8); - sObjectDataMap["State"] = count; //U8 - count += sizeof(U8); + sObjectDataMap["State"] = count; //U8 + count += sizeof(U8); - sObjectDataMap["CRC"] = count; //U32 - count += sizeof(U32); + sObjectDataMap["CRC"] = count; //U32 + count += sizeof(U32); - sObjectDataMap["Material"] = count; //U8 - count += sizeof(U8); + sObjectDataMap["Material"] = count; //U8 + count += sizeof(U8); - sObjectDataMap["ClickAction"] = count; //U8 - count += sizeof(U8); + sObjectDataMap["ClickAction"] = count; //U8 + count += sizeof(U8); - sObjectDataMap["Scale"] = count; //LLVector3 - count += sizeof(LLVector3); + sObjectDataMap["Scale"] = count; //LLVector3 + count += sizeof(LLVector3); - sObjectDataMap["Pos"] = count; //LLVector3 - count += sizeof(LLVector3); + sObjectDataMap["Pos"] = count; //LLVector3 + count += sizeof(LLVector3); - sObjectDataMap["Rot"] = count; //LLVector3 - count += sizeof(LLVector3); + sObjectDataMap["Rot"] = count; //LLVector3 + count += sizeof(LLVector3); - sObjectDataMap["SpecialCode"] = count; //U32 - count += sizeof(U32); + sObjectDataMap["SpecialCode"] = count; //U32 + count += sizeof(U32); - sObjectDataMap["Owner"] = count; //LLUUID - count += sizeof(LLUUID); + sObjectDataMap["Owner"] = count; //LLUUID + count += sizeof(LLUUID); - sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set - count += sizeof(LLVector3); + sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set + count += sizeof(LLVector3); - //ParentID is after Omega if there is Omega, otherwise is after Owner - sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set - count += sizeof(U32); + //ParentID is after Omega if there is Omega, otherwise is after Owner + sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set + count += sizeof(U32); - //------- - //The rest items are not included here - //------- + //------- + //The rest items are not included here + //------- } -//static +//static void LLViewerObject::unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name) { - dp->shift(sObjectDataMap[name]); - dp->unpackVector3(value, name.c_str()); - dp->reset(); + dp->shift(sObjectDataMap[name]); + dp->unpackVector3(value, name.c_str()); + dp->reset(); } -//static +//static void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name) { - dp->shift(sObjectDataMap[name]); - dp->unpackUUID(value, name.c_str()); - dp->reset(); + dp->shift(sObjectDataMap[name]); + dp->unpackUUID(value, name.c_str()); + dp->reset(); } - -//static + +//static void LLViewerObject::unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name) { - dp->shift(sObjectDataMap[name]); - dp->unpackU32(value, name.c_str()); - dp->reset(); + dp->shift(sObjectDataMap[name]); + dp->unpackU32(value, name.c_str()); + dp->reset(); } - -//static + +//static void LLViewerObject::unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name) { - dp->shift(sObjectDataMap[name]); - dp->unpackU8(value, name.c_str()); - dp->reset(); + dp->shift(sObjectDataMap[name]); + dp->unpackU8(value, name.c_str()); + dp->reset(); } -//static +//static U32 LLViewerObject::unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id) { - dp->shift(sObjectDataMap["SpecialCode"]); - U32 value; - dp->unpackU32(value, "SpecialCode"); + dp->shift(sObjectDataMap["SpecialCode"]); + U32 value; + dp->unpackU32(value, "SpecialCode"); - parent_id = 0; - if(value & 0x20) - { - S32 offset = sObjectDataMap["ParentID"]; - if(!(value & 0x80)) - { - offset -= sizeof(LLVector3); - } + parent_id = 0; + if(value & 0x20) + { + S32 offset = sObjectDataMap["ParentID"]; + if(!(value & 0x80)) + { + offset -= sizeof(LLVector3); + } - dp->shift(offset); - dp->unpackU32(parent_id, "ParentID"); - } - dp->reset(); + dp->shift(offset); + dp->unpackU32(parent_id, "ParentID"); + } + dp->reset(); - return parent_id; + return parent_id; } // Replaces all name value pairs with data from \n delimited list // Does not update server void LLViewerObject::setNameValueList(const std::string& name_value_list) { - // Clear out the old - for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ; - mNameValuePairs.clear(); - - // Bring in the new - std::string::size_type length = name_value_list.length(); - std::string::size_type start = 0; - while (start < length) - { - std::string::size_type end = name_value_list.find_first_of("\n", start); - if (end == std::string::npos) end = length; - if (end > start) - { - std::string tok = name_value_list.substr(start, end - start); - addNVPair(tok); - } - start = end+1; - } + // Clear out the old + for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ; + mNameValuePairs.clear(); + + // Bring in the new + std::string::size_type length = name_value_list.length(); + std::string::size_type start = 0; + while (start < length) + { + std::string::size_type end = name_value_list.find_first_of("\n", start); + if (end == std::string::npos) end = length; + if (end > start) + { + std::string tok = name_value_list.substr(start, end - start); + addNVPair(tok); + } + start = end+1; + } } BOOL LLViewerObject::isAnySelected() const @@ -765,183 +765,183 @@ BOOL LLViewerObject::isAnySelected() const void LLViewerObject::setSelected(BOOL sel) { - mUserSelected = sel; - resetRot(); + mUserSelected = sel; + resetRot(); - if (!sel) - { - setAllTESelected(false); - } + if (!sel) + { + setAllTESelected(false); + } } // This method returns true if the object is over land owned by the // agent. bool LLViewerObject::isReturnable() { - if (isAttachment()) - { - return false; - } - - std::vector boxes; - boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); - } - - bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0; - - if ( !result ) - { - //Get list of neighboring regions relative to this vo's region - std::vector uniqueRegions; - mRegionp->getNeighboringRegions( uniqueRegions ); - - //Build aabb's - for root and all children - std::vector returnables; - typedef std::vector::iterator RegionIt; - RegionIt regionStart = uniqueRegions.begin(); - RegionIt regionEnd = uniqueRegions.end(); - - for (; regionStart != regionEnd; ++regionStart ) - { - LLViewerRegion* pTargetRegion = *regionStart; - //Add the root vo as there may be no children and we still want - //to test for any edge overlap - buildReturnablesForChildrenVO( returnables, this, pTargetRegion ); - //Add it's children - for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++) - { - LLViewerObject* pChild = *iter; - buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion ); - } - } - - //TBD#Eventually create a region -> box list map - typedef std::vector::iterator ReturnablesIt; - ReturnablesIt retCurrentIt = returnables.begin(); - ReturnablesIt retEndIt = returnables.end(); - - for ( ; retCurrentIt !=retEndIt; ++retCurrentIt ) - { - boxes.clear(); - LLViewerRegion* pRegion = (*retCurrentIt).pRegion; - boxes.push_back( (*retCurrentIt).box ); - bool retResult = pRegion - && pRegion->childrenObjectReturnable( boxes ) - && pRegion->canManageEstate(); - if ( retResult ) - { - result = true; - break; - } - } - } - return result; + if (isAttachment()) + { + return false; + } + + std::vector boxes; + boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } + + bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0; + + if ( !result ) + { + //Get list of neighboring regions relative to this vo's region + std::vector uniqueRegions; + mRegionp->getNeighboringRegions( uniqueRegions ); + + //Build aabb's - for root and all children + std::vector returnables; + typedef std::vector::iterator RegionIt; + RegionIt regionStart = uniqueRegions.begin(); + RegionIt regionEnd = uniqueRegions.end(); + + for (; regionStart != regionEnd; ++regionStart ) + { + LLViewerRegion* pTargetRegion = *regionStart; + //Add the root vo as there may be no children and we still want + //to test for any edge overlap + buildReturnablesForChildrenVO( returnables, this, pTargetRegion ); + //Add it's children + for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++) + { + LLViewerObject* pChild = *iter; + buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion ); + } + } + + //TBD#Eventually create a region -> box list map + typedef std::vector::iterator ReturnablesIt; + ReturnablesIt retCurrentIt = returnables.begin(); + ReturnablesIt retEndIt = returnables.end(); + + for ( ; retCurrentIt !=retEndIt; ++retCurrentIt ) + { + boxes.clear(); + LLViewerRegion* pRegion = (*retCurrentIt).pRegion; + boxes.push_back( (*retCurrentIt).box ); + bool retResult = pRegion + && pRegion->childrenObjectReturnable( boxes ) + && pRegion->canManageEstate(); + if ( retResult ) + { + result = true; + break; + } + } + } + return result; } void LLViewerObject::buildReturnablesForChildrenVO( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) { - if ( !pChild ) - { - LL_ERRS()<<"child viewerobject is NULL "<mChildList.begin(); iter != pChild->mChildList.end(); iter++) - { - LLViewerObject* pChildofChild = *iter; - buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion ); - } + if ( !pChild ) + { + LL_ERRS()<<"child viewerobject is NULL "<mChildList.begin(); iter != pChild->mChildList.end(); iter++) + { + LLViewerObject* pChildofChild = *iter; + buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion ); + } } void LLViewerObject::constructAndAddReturnable( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) { - - LLVector3 targetRegionPos; - targetRegionPos.setVec( pChild->getPositionGlobal() ); - - LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f, - pChild->getScale() * 0.5f).getAxisAligned(); - - LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal(); - LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal(); - - LLVector3d edgeAd, edgeBd; - edgeAd.setVec(edgeA); - edgeBd.setVec(edgeB); - - //Only add the box when either of the extents are in a neighboring region - if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) ) - { - PotentialReturnableObject returnableObj; - returnableObj.box = childBBox; - returnableObj.pRegion = pTargetRegion; - returnables.push_back( returnableObj ); - } + + LLVector3 targetRegionPos; + targetRegionPos.setVec( pChild->getPositionGlobal() ); + + LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f, + pChild->getScale() * 0.5f).getAxisAligned(); + + LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal(); + LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal(); + + LLVector3d edgeAd, edgeBd; + edgeAd.setVec(edgeA); + edgeBd.setVec(edgeB); + + //Only add the box when either of the extents are in a neighboring region + if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) ) + { + PotentialReturnableObject returnableObj; + returnableObj.box = childBBox; + returnableObj.pRegion = pTargetRegion; + returnables.push_back( returnableObj ); + } } bool LLViewerObject::crossesParcelBounds() { - std::vector boxes; - boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); - } + std::vector boxes; + boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } - return mRegionp && mRegionp->objectsCrossParcel(boxes); + return mRegionp && mRegionp->objectsCrossParcel(boxes); } BOOL LLViewerObject::setParent(LLViewerObject* parent) { - if(mParent != parent) - { - LLViewerObject* old_parent = (LLViewerObject*)mParent ; - BOOL ret = LLPrimitive::setParent(parent); - if(ret && old_parent && parent) - { - old_parent->removeChild(this) ; - } - return ret ; - } + if(mParent != parent) + { + LLViewerObject* old_parent = (LLViewerObject*)mParent ; + BOOL ret = LLPrimitive::setParent(parent); + if(ret && old_parent && parent) + { + old_parent->removeChild(this) ; + } + return ret ; + } - return FALSE ; + return FALSE ; } void LLViewerObject::addChild(LLViewerObject *childp) { - for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) - { - if (*i == childp) - { //already has child - return; - } - } - - if (!isAvatar()) - { - // propagate selection properties - childp->mbCanSelect = mbCanSelect; - } - - if(childp->setParent(this)) - { - mChildList.push_back(childp); - childp->afterReparent(); - - if (childp->isAvatar()) - { - mSeatCount++; - } - } + for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) + { + if (*i == childp) + { //already has child + return; + } + } + + if (!isAvatar()) + { + // propagate selection properties + childp->mbCanSelect = mbCanSelect; + } + + if(childp->setParent(this)) + { + mChildList.push_back(childp); + childp->afterReparent(); + + if (childp->isAvatar()) + { + mSeatCount++; + } + } } void LLViewerObject::onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) @@ -954,149 +954,149 @@ void LLViewerObject::afterReparent() void LLViewerObject::removeChild(LLViewerObject *childp) { - for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) - { - if (*i == childp) - { - if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar()) - { - gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME); - } - - mChildList.erase(i); - - if(childp->getParent() == this) - { - childp->setParent(NULL); - } - - if (childp->isAvatar()) - { - mSeatCount--; - } - break; - } - } - - if (childp->isSelected()) - { - LLSelectMgr::getInstance()->deselectObjectAndFamily(childp); - BOOL add_to_end = TRUE; - LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end); - } + for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) + { + if (*i == childp) + { + if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar()) + { + gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME); + } + + mChildList.erase(i); + + if(childp->getParent() == this) + { + childp->setParent(NULL); + } + + if (childp->isAvatar()) + { + mSeatCount--; + } + break; + } + } + + if (childp->isSelected()) + { + LLSelectMgr::getInstance()->deselectObjectAndFamily(childp); + BOOL add_to_end = TRUE; + LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end); + } } void LLViewerObject::addThisAndAllChildren(std::vector& objects) { - objects.push_back(this); - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - if (!child->isAvatar()) - { - child->addThisAndAllChildren(objects); - } - } + objects.push_back(this); + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + if (!child->isAvatar()) + { + child->addThisAndAllChildren(objects); + } + } } void LLViewerObject::addThisAndNonJointChildren(std::vector& objects) { - objects.push_back(this); - // don't add any attachments when temporarily selecting avatar - if (isAvatar()) - { - return; - } - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - if ( (!child->isAvatar())) - { - child->addThisAndNonJointChildren(objects); - } - } + objects.push_back(this); + // don't add any attachments when temporarily selecting avatar + if (isAvatar()) + { + return; + } + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + if ( (!child->isAvatar())) + { + child->addThisAndNonJointChildren(objects); + } + } } BOOL LLViewerObject::isChild(LLViewerObject *childp) const { - for (child_list_t::const_iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* testchild = *iter; - if (testchild == childp) - return TRUE; - } - return FALSE; + for (child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* testchild = *iter; + if (testchild == childp) + return TRUE; + } + return FALSE; } // returns TRUE if at least one avatar is sitting on this object BOOL LLViewerObject::isSeat() const { - return mSeatCount > 0; + return mSeatCount > 0; } BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) { - if (mDrawable.isNull()) - { - return FALSE; - } - - BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL); - if(!ret) - { - return FALSE ; - } - LLDrawable* old_parent = mDrawable->mParent; - mDrawable->mParent = parentp; - - if (parentp && mDrawable->isActive()) - { - parentp->makeActive(); - parentp->setState(LLDrawable::ACTIVE_CHILD); - } - - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - if( (old_parent != parentp && old_parent) - || (parentp && parentp->isActive())) - { - // *TODO we should not be relying on setDrawable parent to call markMoved - gPipeline.markMoved(mDrawable, FALSE); - } - else if (!mDrawable->isAvatar()) - { - mDrawable->updateXform(TRUE); - /*if (!mDrawable->getSpatialGroup()) - { - mDrawable->movePartition(); - }*/ - } - - return ret; + if (mDrawable.isNull()) + { + return FALSE; + } + + BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL); + if(!ret) + { + return FALSE ; + } + LLDrawable* old_parent = mDrawable->mParent; + mDrawable->mParent = parentp; + + if (parentp && mDrawable->isActive()) + { + parentp->makeActive(); + parentp->setState(LLDrawable::ACTIVE_CHILD); + } + + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + if( (old_parent != parentp && old_parent) + || (parentp && parentp->isActive())) + { + // *TODO we should not be relying on setDrawable parent to call markMoved + gPipeline.markMoved(mDrawable, FALSE); + } + else if (!mDrawable->isAvatar()) + { + mDrawable->updateXform(TRUE); + /*if (!mDrawable->getSpatialGroup()) + { + mDrawable->movePartition(); + }*/ + } + + return ret; } // Show or hide particles, icon and HUD void LLViewerObject::hideExtraDisplayItems( BOOL hidden ) { - if( mPartSourcep.notNull() ) - { - LLViewerPartSourceScript *partSourceScript = mPartSourcep.get(); - partSourceScript->setSuspended( hidden ); - } + if( mPartSourcep.notNull() ) + { + LLViewerPartSourceScript *partSourceScript = mPartSourcep.get(); + partSourceScript->setSuspended( hidden ); + } - if( mText.notNull() ) - { - LLHUDText *hudText = mText.get(); - hudText->setHidden( hidden ); - } + if( mText.notNull() ) + { + LLHUDText *hudText = mText.get(); + hudText->setHidden( hidden ); + } - if( mIcon.notNull() ) - { - LLHUDIcon *hudIcon = mIcon.get(); - hudIcon->setHidden( hidden ); - } + if( mIcon.notNull() ) + { + LLHUDIcon *hudIcon = mIcon.get(); + hudIcon->setHidden( hidden ); + } } U32 LLViewerObject::checkMediaURL(const std::string &media_url) @@ -1121,9 +1121,9 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url) else if (mMedia->mMediaURL != media_url) // <-- This is an optimization. If they are equal don't bother with below's test. { /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() && - LLTextureEntry::getVersionFromMediaVersionString(media_url) == + LLTextureEntry::getVersionFromMediaVersionString(media_url) == LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1)) - */ + */ { // If the media URL is different and WE were not the one who // changed it, mark dirty. @@ -1141,1356 +1141,1356 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url) //static U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot) { - U32 parent_id = 0; - LLViewerObject::unpackParentID(dp, parent_id); + U32 parent_id = 0; + LLViewerObject::unpackParentID(dp, parent_id); - LLViewerObject::unpackVector3(dp, scale, "Scale"); - LLViewerObject::unpackVector3(dp, pos, "Pos"); - - LLVector3 vec; - LLViewerObject::unpackVector3(dp, vec, "Rot"); - rot.unpackFromVector3(vec); - - return parent_id; + LLViewerObject::unpackVector3(dp, scale, "Scale"); + LLViewerObject::unpackVector3(dp, pos, "Pos"); + + LLVector3 vec; + LLViewerObject::unpackVector3(dp, vec, "Rot"); + rot.unpackFromVector3(vec); + + return parent_id; } U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, - const EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp) { LL_PROFILE_ZONE_SCOPED; - LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL; + LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL; LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL; dumpStack("ObjectUpdateStack"); - U32 retval = 0x0; - - // If region is removed from the list it is also deleted. - if (!LLWorld::instance().isRegionListed(mRegionp)) - { - LL_WARNS() << "Updating object in an invalid region" << LL_ENDL; - return retval; - } - - // Coordinates of objects on simulators are region-local. - U64 region_handle = 0; - - if(mesgsys != NULL) - { - mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); - LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); - if(regionp != mRegionp && regionp && mRegionp)//region cross - { - //this is the redundant position and region update, but it is necessary in case the viewer misses the following - //position and region update messages from sim. - //this redundant update should not cause any problems. - LLVector3 delta_pos = mRegionp->getOriginAgent() - regionp->getOriginAgent(); - setPositionParent(getPosition() + delta_pos); //update to the new region position immediately. - setRegion(regionp) ; //change the region. - } - else - { - if(regionp != mRegionp) - { - if(mRegionp) - { - mRegionp->removeFromCreatedList(getLocalID()); - } - if(regionp) - { - regionp->addToCreatedList(getLocalID()); - } - } - mRegionp = regionp ; - } - } - - if (!mRegionp) - { - U32 x, y; - from_region_handle(region_handle, &x, &y); - - LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL; - return retval; - } - - F32 time_dilation = 1.f; - if(mesgsys != NULL) - { - U16 time_dilation16; - mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16); - time_dilation = ((F32) time_dilation16) / 65535.f; - mRegionp->setTimeDilation(time_dilation); - } + U32 retval = 0x0; - // this will be used to determine if we've really changed position - // Use getPosition, not getPositionRegion, since this is what we're comparing directly against. - LLVector3 test_pos_parent = getPosition(); + // If region is removed from the list it is also deleted. + if (!LLWorld::instance().isRegionListed(mRegionp)) + { + LL_WARNS() << "Updating object in an invalid region" << LL_ENDL; + return retval; + } - // This needs to match the largest size below. See switch(length) - U8 data[MAX_OBJECT_BINARY_DATA_SIZE]; + // Coordinates of objects on simulators are region-local. + U64 region_handle = 0; -#ifdef LL_BIG_ENDIAN - U16 valswizzle[4]; -#endif - U16 *val; - const F32 size = LLWorld::getInstance()->getRegionWidthInMeters(); - const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight(); - const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight(); - S32 length; - S32 count; - S32 this_update_precision = 32; // in bits - - // Temporaries, because we need to compare w/ previous to set dirty flags... - LLVector3 new_pos_parent; - LLVector3 new_vel; - LLVector3 new_acc; - LLVector3 new_angv; - LLVector3 old_angv = getAngularVelocity(); - LLQuaternion new_rot; - LLVector3 new_scale = getScale(); - - U32 parent_id = 0; - U8 material = 0; - U8 click_action = 0; - U32 crc = 0; - - bool old_special_hover_cursor = specialHoverCursor(); - - LLViewerObject *cur_parentp = (LLViewerObject *)getParent(); - - if (cur_parentp) - { - parent_id = cur_parentp->mLocalID; - } - - if (!dp) - { - switch(update_type) - { - case OUT_FULL: - { -#ifdef DEBUG_UPDATE_TYPE - LL_INFOS() << "Full:" << getID() << LL_ENDL; + if(mesgsys != NULL) + { + mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); + if(regionp != mRegionp && regionp && mRegionp)//region cross + { + //this is the redundant position and region update, but it is necessary in case the viewer misses the following + //position and region update messages from sim. + //this redundant update should not cause any problems. + LLVector3 delta_pos = mRegionp->getOriginAgent() - regionp->getOriginAgent(); + setPositionParent(getPosition() + delta_pos); //update to the new region position immediately. + setRegion(regionp) ; //change the region. + } + else + { + if(regionp != mRegionp) + { + if(mRegionp) + { + mRegionp->removeFromCreatedList(getLocalID()); + } + if(regionp) + { + regionp->addToCreatedList(getLocalID()); + } + } + mRegionp = regionp ; + } + } + + if (!mRegionp) + { + U32 x, y; + from_region_handle(region_handle, &x, &y); + + LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL; + return retval; + } + + F32 time_dilation = 1.f; + if(mesgsys != NULL) + { + U16 time_dilation16; + mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16); + time_dilation = ((F32) time_dilation16) / 65535.f; + mRegionp->setTimeDilation(time_dilation); + } + + // this will be used to determine if we've really changed position + // Use getPosition, not getPositionRegion, since this is what we're comparing directly against. + LLVector3 test_pos_parent = getPosition(); + + // This needs to match the largest size below. See switch(length) + U8 data[MAX_OBJECT_BINARY_DATA_SIZE]; + +#ifdef LL_BIG_ENDIAN + U16 valswizzle[4]; #endif - //clear cost and linkset cost - setObjectCostStale(); - if (isSelected()) - { - gFloaterTools->dirty(); - } - - LLUUID audio_uuid; - LLUUID owner_id; // only valid if audio_uuid or particle system is not null - F32 gain; - F32 cutoff; - U8 sound_flags; - - mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num); - mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num); - mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num ); - // HACK: Owner id only valid if non-null sound id or particle system - mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num ); - mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num ); - mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num ); - mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num ); - mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num ); - mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num); - mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num ); - length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); - - mTotalCRC = crc; + U16 *val; + const F32 size = LLWorld::getInstance()->getRegionWidthInMeters(); + const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight(); + const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight(); + S32 length; + S32 count; + S32 this_update_precision = 32; // in bits + + // Temporaries, because we need to compare w/ previous to set dirty flags... + LLVector3 new_pos_parent; + LLVector3 new_vel; + LLVector3 new_acc; + LLVector3 new_angv; + LLVector3 old_angv = getAngularVelocity(); + LLQuaternion new_rot; + LLVector3 new_scale = getScale(); + + U32 parent_id = 0; + U8 material = 0; + U8 click_action = 0; + U32 crc = 0; + + bool old_special_hover_cursor = specialHoverCursor(); + + LLViewerObject *cur_parentp = (LLViewerObject *)getParent(); + + if (cur_parentp) + { + parent_id = cur_parentp->mLocalID; + } + + if (!dp) + { + switch(update_type) + { + case OUT_FULL: + { +#ifdef DEBUG_UPDATE_TYPE + LL_INFOS() << "Full:" << getID() << LL_ENDL; +#endif + //clear cost and linkset cost + setObjectCostStale(); + if (isSelected()) + { + gFloaterTools->dirty(); + } + + LLUUID audio_uuid; + LLUUID owner_id; // only valid if audio_uuid or particle system is not null + F32 gain; + F32 cutoff; + U8 sound_flags; + + mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num); + mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num); + mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num ); + // HACK: Owner id only valid if non-null sound id or particle system + mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num ); + mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num ); + mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num ); + mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num ); + mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num ); + mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num); + mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num ); + length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData); + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); + + mTotalCRC = crc; // Might need to update mSourceMuted here to properly pick up new radius - mSoundCutOffRadius = cutoff; - - // Owner ID used for sound muting or particle system muting - setAttachedSound(audio_uuid, owner_id, gain, sound_flags); - - U8 old_material = getMaterial(); - if (old_material != material) - { - setMaterial(material); - if (mDrawable.notNull()) - { - gPipeline.markMoved(mDrawable, FALSE); // undamped - } - } - setClickAction(click_action); - - count = 0; - LLVector4 collision_plane; - - switch(length) - { - case (60 + 16): - // pull out collision normal for avatar - htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); - ((LLVOAvatar*)this)->setFootPlane(collision_plane); - count += sizeof(LLVector4); - // fall through - case 60: - this_update_precision = 32; - // this is a terse update - // pos - htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // vel - htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // acc - htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // theta - { - LLVector3 vec; - htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - new_rot.unpackFromVector3(vec); - } - count += sizeof(LLVector3); - // omega - htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - if (new_angv.isExactlyZero()) - { - // reset rotation time - resetRot(); - } - setAngularVelocity(new_angv); + mSoundCutOffRadius = cutoff; + + // Owner ID used for sound muting or particle system muting + setAttachedSound(audio_uuid, owner_id, gain, sound_flags); + + U8 old_material = getMaterial(); + if (old_material != material) + { + setMaterial(material); + if (mDrawable.notNull()) + { + gPipeline.markMoved(mDrawable, FALSE); // undamped + } + } + setClickAction(click_action); + + count = 0; + LLVector4 collision_plane; + + switch(length) + { + case (60 + 16): + // pull out collision normal for avatar + htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); + ((LLVOAvatar*)this)->setFootPlane(collision_plane); + count += sizeof(LLVector4); + // fall through + case 60: + this_update_precision = 32; + // this is a terse update + // pos + htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // vel + htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // acc + htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // theta + { + LLVector3 vec; + htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + new_rot.unpackFromVector3(vec); + } + count += sizeof(LLVector3); + // omega + htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + if (new_angv.isExactlyZero()) + { + // reset rotation time + resetRot(); + } + setAngularVelocity(new_angv); #if LL_DARWIN - if (length == 76) - { - setAngularVelocity(LLVector3::zero); - } + if (length == 76) + { + setAngularVelocity(LLVector3::zero); + } #endif - break; - case(32 + 16): - // pull out collision normal for avatar - htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); - ((LLVOAvatar*)this)->setFootPlane(collision_plane); - count += sizeof(LLVector4); - // fall through - case 32: - this_update_precision = 16; - test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); - - // This is a terse 16 update, so treat data as an array of U16's. + break; + case(32 + 16): + // pull out collision normal for avatar + htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); + ((LLVOAvatar*)this)->setFootPlane(collision_plane); + count += sizeof(LLVector4); + // fall through + case 32: + this_update_precision = 16; + test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); + + // This is a terse 16 update, so treat data as an array of U16's. #ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; #else - val = (U16 *) &data[count]; + val = (U16 *) &data[count]; #endif - count += sizeof(U16)*3; - new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT); + count += sizeof(U16)*3; + new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT); #ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; #else - val = (U16 *) &data[count]; + val = (U16 *) &data[count]; #endif - count += sizeof(U16)*3; - setVelocity(LLVector3(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size))); + count += sizeof(U16)*3; + setVelocity(LLVector3(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size))); #ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; #else - val = (U16 *) &data[count]; + val = (U16 *) &data[count]; #endif - count += sizeof(U16)*3; - setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size))); + count += sizeof(U16)*3; + setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size))); #ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4); - val = valswizzle; + htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4); + val = valswizzle; #else - val = (U16 *) &data[count]; + val = (U16 *) &data[count]; #endif - count += sizeof(U16)*4; - new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); - new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); - new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); - new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f); + count += sizeof(U16)*4; + new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); + new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); + new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); + new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + new_angv.setVec(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size)); + if (new_angv.isExactlyZero()) + { + // reset rotation time + resetRot(); + } + setAngularVelocity(new_angv); + break; + + case 16: + this_update_precision = 8; + test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); + // this is a terse 8 update + new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); + + setVelocity(U8_to_F32(data[3], -size, size), + U8_to_F32(data[4], -size, size), + U8_to_F32(data[5], -size, size) ); + + setAcceleration(U8_to_F32(data[6], -size, size), + U8_to_F32(data[7], -size, size), + U8_to_F32(data[8], -size, size) ); + + new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); + new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); + new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); + new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); + + new_angv.setVec(U8_to_F32(data[13], -size, size), + U8_to_F32(data[14], -size, size), + U8_to_F32(data[15], -size, size) ); + if (new_angv.isExactlyZero()) + { + // reset rotation time + resetRot(); + } + setAngularVelocity(new_angv); + break; + } + + //////////////////////////////////////////////////// + // + // Here we handle data specific to the full message. + // + + U32 flags; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); + // clear all but local flags + mFlags &= FLAGS_LOCAL; + mFlags |= flags; + + U8 state; + mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); + mAttachmentState = state; + + // ...new objects that should come in selected need to be added to the selected list + mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + + // Set all name value pairs + S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue); + if (nv_size > 0) + { + std::string name_value_list; + mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num); + setNameValueList(name_value_list); + } + + // Clear out any existing generic data + if (mData) + { + delete [] mData; + } + + // Check for appended generic data + S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data); + if (data_size <= 0) + { + mData = NULL; + } + else + { + // ...has generic data + mData = new U8[data_size]; + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num); + } + + S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text); + if (text_size > 1) + { + // Setup object text + if (!mText) + { + initHudText(); + } + + std::string temp_string; + mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); + + LLColor4U coloru; + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); + + // alpha was flipped so that it zero encoded better + coloru.mV[3] = 255 - coloru.mV[3]; + + mText->setColor(LLColor4(coloru)); + mText->setString(temp_string); + + mHudText = temp_string; + mHudTextColor = LLColor4(coloru); + + setChanged(MOVED | SILHOUETTE); + } + else + { + if (mText.notNull()) + { + mText->markDead(); + mText = NULL; + } + mHudText.clear(); + } + + std::string media_url; + mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num); + retval |= checkMediaURL(media_url); + + // + // Unpack particle system data + // + unpackParticleSource(block_num, owner_id); + + // Mark all extra parameters not used + std::unordered_map::iterator iter; + for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) + { + iter->second->in_use = FALSE; + } + + // Unpack extra parameters + S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams); + if (size > 0) + { + U8 *buffer = new U8[size]; + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num); + LLDataPackerBinaryBuffer dp(buffer, size); + + U8 num_parameters; + dp.unpackU8(num_parameters, "num_params"); + U8 param_block[MAX_OBJECT_PARAMS_SIZE]; + for (U8 param=0; paramsecond->in_use) + { + // Send an update message in case it was formerly in use + parameterChanged(iter->first, iter->second->data, FALSE, false); + } + } + + break; + } + + case OUT_TERSE_IMPROVED: + { +#ifdef DEBUG_UPDATE_TYPE + LL_INFOS() << "TI:" << getID() << LL_ENDL; +#endif + length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData); + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); + count = 0; + LLVector4 collision_plane; + + switch(length) + { + case(60 + 16): + // pull out collision normal for avatar + htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); + ((LLVOAvatar*)this)->setFootPlane(collision_plane); + count += sizeof(LLVector4); + // fall through + case 60: + // this is a terse 32 update + // pos + this_update_precision = 32; + htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // vel + htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // acc + htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + count += sizeof(LLVector3); + // theta + { + LLVector3 vec; + htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + new_rot.unpackFromVector3(vec); + } + count += sizeof(LLVector3); + // omega + htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); + if (new_angv.isExactlyZero()) + { + // reset rotation time + resetRot(); + } + setAngularVelocity(new_angv); +#if LL_DARWIN + if (length == 76) + { + setAngularVelocity(LLVector3::zero); + } +#endif + break; + case(32 + 16): + // pull out collision normal for avatar + htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); + ((LLVOAvatar*)this)->setFootPlane(collision_plane); + count += sizeof(LLVector4); + // fall through + case 32: + // this is a terse 16 update + this_update_precision = 16; + test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + count += sizeof(U16)*3; + new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + count += sizeof(U16)*3; + setVelocity(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size)); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + count += sizeof(U16)*3; + setAcceleration(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size)); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + count += sizeof(U16)*4; + new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); + new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); + new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); + new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f); + +#ifdef LL_BIG_ENDIAN + htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); + val = valswizzle; +#else + val = (U16 *) &data[count]; +#endif + new_angv.set(U16_to_F32(val[VX], -size, size), + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size)); + setAngularVelocity(new_angv); + break; + + case 16: + // this is a terse 8 update + this_update_precision = 8; + test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); + new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); + new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); + + setVelocity(U8_to_F32(data[3], -size, size), + U8_to_F32(data[4], -size, size), + U8_to_F32(data[5], -size, size) ); + + setAcceleration(U8_to_F32(data[6], -size, size), + U8_to_F32(data[7], -size, size), + U8_to_F32(data[8], -size, size) ); + + new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); + new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); + new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); + new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); + + new_angv.set(U8_to_F32(data[13], -size, size), + U8_to_F32(data[14], -size, size), + U8_to_F32(data[15], -size, size) ); + setAngularVelocity(new_angv); + break; + } + + U8 state; + mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); + mAttachmentState = state; + break; + } + + default: + break; + + } + } + else + { + // handle the compressed case + LLUUID sound_uuid; + LLUUID owner_id; + F32 gain = 0; + U8 sound_flags = 0; + F32 cutoff = 0; + + U16 val[4]; + + U8 state; + + dp->unpackU8(state, "State"); + mAttachmentState = state; + + switch(update_type) + { + case OUT_TERSE_IMPROVED: + { +#ifdef DEBUG_UPDATE_TYPE + LL_INFOS() << "CompTI:" << getID() << LL_ENDL; +#endif + U8 value; + dp->unpackU8(value, "agent"); + if (value) + { + LLVector4 collision_plane; + dp->unpackVector4(collision_plane, "Plane"); + ((LLVOAvatar*)this)->setFootPlane(collision_plane); + } + test_pos_parent = getPosition(); + dp->unpackVector3(new_pos_parent, "Pos"); + dp->unpackU16(val[VX], "VelX"); + dp->unpackU16(val[VY], "VelY"); + dp->unpackU16(val[VZ], "VelZ"); + setVelocity(U16_to_F32(val[VX], -128.f, 128.f), + U16_to_F32(val[VY], -128.f, 128.f), + U16_to_F32(val[VZ], -128.f, 128.f)); + dp->unpackU16(val[VX], "AccX"); + dp->unpackU16(val[VY], "AccY"); + dp->unpackU16(val[VZ], "AccZ"); + setAcceleration(U16_to_F32(val[VX], -64.f, 64.f), + U16_to_F32(val[VY], -64.f, 64.f), + U16_to_F32(val[VZ], -64.f, 64.f)); + + dp->unpackU16(val[VX], "ThetaX"); + dp->unpackU16(val[VY], "ThetaY"); + dp->unpackU16(val[VZ], "ThetaZ"); + dp->unpackU16(val[VS], "ThetaS"); + new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); + new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); + new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); + new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f); + dp->unpackU16(val[VX], "AccX"); + dp->unpackU16(val[VY], "AccY"); + dp->unpackU16(val[VZ], "AccZ"); + new_angv.set(U16_to_F32(val[VX], -64.f, 64.f), + U16_to_F32(val[VY], -64.f, 64.f), + U16_to_F32(val[VZ], -64.f, 64.f)); + setAngularVelocity(new_angv); + } + break; + case OUT_FULL_COMPRESSED: + case OUT_FULL_CACHED: + { +#ifdef DEBUG_UPDATE_TYPE + LL_INFOS() << "CompFull:" << getID() << LL_ENDL; +#endif + setObjectCostStale(); + + if (isSelected()) + { + gFloaterTools->dirty(); + } + + dp->unpackU32(crc, "CRC"); + mTotalCRC = crc; + dp->unpackU8(material, "Material"); + U8 old_material = getMaterial(); + if (old_material != material) + { + setMaterial(material); + if (mDrawable.notNull()) + { + gPipeline.markMoved(mDrawable, FALSE); // undamped + } + } + dp->unpackU8(click_action, "ClickAction"); + setClickAction(click_action); + dp->unpackVector3(new_scale, "Scale"); + dp->unpackVector3(new_pos_parent, "Pos"); + LLVector3 vec; + dp->unpackVector3(vec, "Rot"); + new_rot.unpackFromVector3(vec); + setAcceleration(LLVector3::zero); + + U32 value; + dp->unpackU32(value, "SpecialCode"); + dp->setPassFlags(value); + dp->unpackUUID(owner_id, "Owner"); + + mOwnerID = owner_id; + + if (value & 0x80) + { + dp->unpackVector3(new_angv, "Omega"); + setAngularVelocity(new_angv); + } + + if (value & 0x20) + { + dp->unpackU32(parent_id, "ParentID"); + } + else + { + parent_id = 0; + } + + S32 sp_size; + U32 size; + if (value & 0x2) + { + sp_size = 1; + delete [] mData; + mData = new U8[1]; + dp->unpackU8(((U8*)mData)[0], "TreeData"); + } + else if (value & 0x1) + { + dp->unpackU32(size, "ScratchPadSize"); + delete [] mData; + mData = new U8[size]; + dp->unpackBinaryData((U8 *)mData, sp_size, "PartData"); + } + else + { + mData = NULL; + } + + // Setup object text + if (!mText && (value & 0x4)) + { + initHudText(); + } + + if (value & 0x4) + { + std::string temp_string; + dp->unpackString(temp_string, "Text"); + + LLColor4U coloru; + dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); + coloru.mV[3] = 255 - coloru.mV[3]; + mText->setColor(LLColor4(coloru)); + mText->setString(temp_string); + + mHudText = temp_string; + mHudTextColor = LLColor4(coloru); + + setChanged(TEXTURE); + } + else + { + if (mText.notNull()) + { + mText->markDead(); + mText = NULL; + } + mHudText.clear(); + } + + std::string media_url; + if (value & 0x200) + { + dp->unpackString(media_url, "MediaURL"); + } + retval |= checkMediaURL(media_url); + + // + // Unpack particle system data (legacy) + // + if (value & 0x8) + { + unpackParticleSource(*dp, owner_id, true); + } + else if (!(value & 0x400)) + { + deleteParticleSource(); + } + + // Mark all extra parameters not used + std::unordered_map::iterator iter; + for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) + { + iter->second->in_use = FALSE; + } + + // Unpack extra params + U8 num_parameters; + dp->unpackU8(num_parameters, "num_params"); + U8 param_block[MAX_OBJECT_PARAMS_SIZE]; + for (U8 param=0; paramunpackU16(param_type, "param_type"); + dp->unpackBinaryData(param_block, param_size, "param_data"); + //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL; + LLDataPackerBinaryBuffer dp2(param_block, param_size); + unpackParameterEntry(param_type, &dp2); + } + + for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) + { + if (!iter->second->in_use) + { + // Send an update message in case it was formerly in use + parameterChanged(iter->first, iter->second->data, FALSE, false); + } + } + + if (value & 0x10) + { + dp->unpackUUID(sound_uuid, "SoundUUID"); + dp->unpackF32(gain, "SoundGain"); + dp->unpackU8(sound_flags, "SoundFlags"); + dp->unpackF32(cutoff, "SoundRadius"); + } + + if (value & 0x100) + { + std::string name_value_list; + dp->unpackString(name_value_list, "NV"); + + setNameValueList(name_value_list); + } + + mTotalCRC = crc; + mSoundCutOffRadius = cutoff; + + setAttachedSound(sound_uuid, owner_id, gain, sound_flags); + + // only get these flags on updates from sim, not cached ones + // Preload these five flags for every object. + // Finer shades require the object to be selected, and the selection manager + // stores the extended permission info. + if(mesgsys != NULL) + { + U32 flags; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); + loadFlags(flags); + } + } + break; + + default: + break; + } + } + + // + // Fix object parenting. + // + BOOL b_changed_status = FALSE; + + if (OUT_TERSE_IMPROVED != update_type) + { + // We only need to update parenting on full updates, terse updates + // don't send parenting information. + if (!cur_parentp) + { + if (parent_id == 0) + { + // No parent now, no parent in message -> do nothing + } + else + { + // No parent now, new parent in message -> attach to that parent if possible + LLUUID parent_uuid; + + if(mesgsys != NULL) + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mesgsys->getSenderIP(), + mesgsys->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } + + LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid); + + // + // Check to see if we have the corresponding viewer object for the parent. + // + if (sent_parentp && sent_parentp->getParent() == this) + { + // Try to recover if we attempt to attach a parent to its child + LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL; + this->removeChild(sent_parentp); + sent_parentp->setDrawableParent(NULL); + } + + if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead()) + { + if (((LLViewerObject*)sent_parentp)->isAvatar()) + { + //LL_DEBUGS("Avatar") << "ATT got object update for attachment " << LL_ENDL; + } + + // + // We have a viewer object for the parent, and it's not dead. + // Do the actual reparenting here. + // + + // new parent is valid + b_changed_status = TRUE; + // ...no current parent, so don't try to remove child + if (mDrawable.notNull()) + { + if (mDrawable->isDead() || !mDrawable->getVObj()) + { + LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL; + sent_parentp->addChild(this); + } + else + { + if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1 + { + // Bad, we got a cycle somehow. + // Kill both the parent and the child, and + // set cache misses for both of them. + LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL; + LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL; + LL_WARNS() << "Adding to cache miss list" << LL_ENDL; + setParent(NULL); + sent_parentp->setParent(NULL); + getRegion()->addCacheMissFull(getLocalID()); + getRegion()->addCacheMissFull(sent_parentp->getLocalID()); + gObjectList.killObject(sent_parentp); + gObjectList.killObject(this); + return retval; + } + sent_parentp->addChild(this); + // make sure this object gets a non-damped update + if (sent_parentp->mDrawable.notNull()) + { + gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped + } + } + } + else + { + sent_parentp->addChild(this); + } + + // Show particles, icon and HUD + hideExtraDisplayItems( FALSE ); + + setChanged(MOVED | SILHOUETTE); + } + else + { + // + // No corresponding viewer object for the parent, put the various + // pieces on the orphan list. + // + + //parent_id + U32 ip, port; + + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } + gObjectList.orphanize(this, parent_id, ip, port); + + // Hide particles, icon and HUD + hideExtraDisplayItems( TRUE ); + } + } + } + else + { + // BUG: this is a bad assumption once border crossing is alowed + if ( (parent_id == cur_parentp->mLocalID) + &&(update_type == OUT_TERSE_IMPROVED)) + { + // Parent now, same parent in message -> do nothing + + // Debugging for suspected problems with local ids. + //LLUUID parent_uuid; + //LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() ); + //if (parent_uuid != cur_parentp->getID() ) + //{ + // LL_ERRS() << "Local ID match but UUID mismatch of viewer object" << LL_ENDL; + //} + } + else + { + // Parented now, different parent in message + LLViewerObject *sent_parentp; + if (parent_id == 0) + { + // + // This object is no longer parented, we sent in a zero parent ID. + // + sent_parentp = NULL; + } + else + { + LLUUID parent_uuid; + + if(mesgsys != NULL) + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + gMessageSystem->getSenderIP(), + gMessageSystem->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } + sent_parentp = gObjectList.findObject(parent_uuid); + + if (isAvatar()) + { + // This logic is meant to handle the case where a sitting avatar has reached a new sim + // ahead of the object she was sitting on (which is common as objects are transfered through + // a slower route than agents)... + // In this case, the local id for the object will not be valid, since the viewer has not received + // a full update for the object from that sim yet, so we assume that the agent is still sitting + // where she was originally. --RN + if (!sent_parentp) + { + sent_parentp = cur_parentp; + } + } + else if (!sent_parentp) + { + // + // Switching parents, but we don't know the new parent. + // + U32 ip, port; + + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } + + // We're an orphan, flag things appropriately. + gObjectList.orphanize(this, parent_id, ip, port); + } + } + + // Reattach if possible. + if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this) + { + // New parent is valid, detach and reattach + b_changed_status = TRUE; + if (mDrawable.notNull()) + { + if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2 + { + // Bad, we got a cycle somehow. + // Kill both the parent and the child, and + // set cache misses for both of them. + LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL; + LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL; + LL_WARNS() << "Adding to cache miss list" << LL_ENDL; + setParent(NULL); + sent_parentp->setParent(NULL); + getRegion()->addCacheMissFull(getLocalID()); + getRegion()->addCacheMissFull(sent_parentp->getLocalID()); + gObjectList.killObject(sent_parentp); + gObjectList.killObject(this); + return retval; + } + // make sure this object gets a non-damped update + } + cur_parentp->removeChild(this); + sent_parentp->addChild(this); + setChanged(MOVED | SILHOUETTE); + sent_parentp->setChanged(MOVED | SILHOUETTE); + if (sent_parentp->mDrawable.notNull()) + { + gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped + } + } + else if (!sent_parentp) + { + bool remove_parent = true; + // No new parent, or the parent that we sent doesn't exist on the viewer. + LLViewerObject *parentp = (LLViewerObject *)getParent(); + if (parentp) + { + if (parentp->getRegion() != getRegion()) + { + // This is probably an object flying across a region boundary, the + // object probably ISN'T being reparented, but just got an object + // update out of order (child update before parent). + //LL_INFOS() << "Don't reparent object handoffs!" << LL_ENDL; + remove_parent = false; + } + } + + if (remove_parent) + { + b_changed_status = TRUE; + if (mDrawable.notNull()) + { + // clear parent to removeChild can put the drawable on the damped list + setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3 + } + + cur_parentp->removeChild(this); + + setChanged(MOVED | SILHOUETTE); + + if (mDrawable.notNull()) + { + // make sure this object gets a non-damped update + gPipeline.markMoved(mDrawable, FALSE); // undamped + } + } + } + } + } + } + + new_rot.normQuat(); + + if (sPingInterpolate && mesgsys != NULL) + { + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender()); + if (cdp) + { + // Note: delay is U32 and usually less then second, + // converting it into seconds with valueInUnits will result in 0 + F32 ping_delay = 0.5f * time_dilation * ( ((F32)cdp->getPingDelay().value()) * 0.001f + gFrameDTClamped); + LLVector3 diff = getVelocity() * ping_delay; + new_pos_parent += diff; + } + else + { + LL_WARNS() << "findCircuit() returned NULL; skipping interpolation" << LL_ENDL; + } + } + + ////////////////////////// + // + // Set the generic change flags... + // + // + + // If we're going to skip this message, why are we + // doing all the parenting, etc above? + if(mesgsys != NULL) + { + U32 packet_id = mesgsys->getCurrentRecvPacketID(); + if (packet_id < mLatestRecvPacketID && + mLatestRecvPacketID - packet_id < 65536) + { + //skip application of this message, it's old + return retval; + } + mLatestRecvPacketID = packet_id; + } + + // Set the change flags for scale + if (new_scale != getScale()) + { + setChanged(SCALED | SILHOUETTE); + setScale(new_scale); // Must follow setting permYouOwner() + } + + // first, let's see if the new position is actually a change + + //static S32 counter = 0; + + F32 vel_mag_sq = getVelocity().magVecSquared(); + F32 accel_mag_sq = getAcceleration().magVecSquared(); + + if ( ((b_changed_status)||(test_pos_parent != new_pos_parent)) + ||( (!isSelected()) + &&( (vel_mag_sq != 0.f) + ||(accel_mag_sq != 0.f) + ||(this_update_precision > mBestUpdatePrecision)))) + { + mBestUpdatePrecision = this_update_precision; + + LLVector3 diff = new_pos_parent - test_pos_parent ; + F32 mag_sqr = diff.magVecSquared() ; + if(llfinite(mag_sqr)) + { + setPositionParent(new_pos_parent); + } + else + { + LL_WARNS() << "Can not move the object/avatar to an infinite location!" << LL_ENDL ; -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - new_angv.setVec(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size)); - if (new_angv.isExactlyZero()) - { - // reset rotation time - resetRot(); - } - setAngularVelocity(new_angv); - break; - - case 16: - this_update_precision = 8; - test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); - // this is a terse 8 update - new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); - - setVelocity(U8_to_F32(data[3], -size, size), - U8_to_F32(data[4], -size, size), - U8_to_F32(data[5], -size, size) ); - - setAcceleration(U8_to_F32(data[6], -size, size), - U8_to_F32(data[7], -size, size), - U8_to_F32(data[8], -size, size) ); - - new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); - new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); - new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); - new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); - - new_angv.setVec(U8_to_F32(data[13], -size, size), - U8_to_F32(data[14], -size, size), - U8_to_F32(data[15], -size, size) ); - if (new_angv.isExactlyZero()) - { - // reset rotation time - resetRot(); - } - setAngularVelocity(new_angv); - break; - } - - //////////////////////////////////////////////////// - // - // Here we handle data specific to the full message. - // - - U32 flags; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); - // clear all but local flags - mFlags &= FLAGS_LOCAL; - mFlags |= flags; - - U8 state; - mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); - mAttachmentState = state; - - // ...new objects that should come in selected need to be added to the selected list - mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); - - // Set all name value pairs - S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue); - if (nv_size > 0) - { - std::string name_value_list; - mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num); - setNameValueList(name_value_list); - } - - // Clear out any existing generic data - if (mData) - { - delete [] mData; - } - - // Check for appended generic data - S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data); - if (data_size <= 0) - { - mData = NULL; - } - else - { - // ...has generic data - mData = new U8[data_size]; - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num); - } - - S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text); - if (text_size > 1) - { - // Setup object text - if (!mText) - { - initHudText(); - } - - std::string temp_string; - mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); - - LLColor4U coloru; - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); - - // alpha was flipped so that it zero encoded better - coloru.mV[3] = 255 - coloru.mV[3]; - - mText->setColor(LLColor4(coloru)); - mText->setString(temp_string); - - mHudText = temp_string; - mHudTextColor = LLColor4(coloru); - - setChanged(MOVED | SILHOUETTE); - } - else - { - if (mText.notNull()) - { - mText->markDead(); - mText = NULL; - } - mHudText.clear(); - } - - std::string media_url; - mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num); - retval |= checkMediaURL(media_url); - - // - // Unpack particle system data - // - unpackParticleSource(block_num, owner_id); - - // Mark all extra parameters not used - std::unordered_map::iterator iter; - for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) - { - iter->second->in_use = FALSE; - } - - // Unpack extra parameters - S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams); - if (size > 0) - { - U8 *buffer = new U8[size]; - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num); - LLDataPackerBinaryBuffer dp(buffer, size); - - U8 num_parameters; - dp.unpackU8(num_parameters, "num_params"); - U8 param_block[MAX_OBJECT_PARAMS_SIZE]; - for (U8 param=0; paramsecond->in_use) - { - // Send an update message in case it was formerly in use - parameterChanged(iter->first, iter->second->data, FALSE, false); - } - } - - break; - } - - case OUT_TERSE_IMPROVED: - { -#ifdef DEBUG_UPDATE_TYPE - LL_INFOS() << "TI:" << getID() << LL_ENDL; -#endif - length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); - count = 0; - LLVector4 collision_plane; - - switch(length) - { - case(60 + 16): - // pull out collision normal for avatar - htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); - ((LLVOAvatar*)this)->setFootPlane(collision_plane); - count += sizeof(LLVector4); - // fall through - case 60: - // this is a terse 32 update - // pos - this_update_precision = 32; - htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // vel - htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // acc - htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - count += sizeof(LLVector3); - // theta - { - LLVector3 vec; - htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - new_rot.unpackFromVector3(vec); - } - count += sizeof(LLVector3); - // omega - htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); - if (new_angv.isExactlyZero()) - { - // reset rotation time - resetRot(); - } - setAngularVelocity(new_angv); -#if LL_DARWIN - if (length == 76) - { - setAngularVelocity(LLVector3::zero); - } -#endif - break; - case(32 + 16): - // pull out collision normal for avatar - htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); - ((LLVOAvatar*)this)->setFootPlane(collision_plane); - count += sizeof(LLVector4); - // fall through - case 32: - // this is a terse 16 update - this_update_precision = 16; - test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); + retval |= INVALID_UPDATE ; + } -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - count += sizeof(U16)*3; - new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT); + if (mParent && ((LLViewerObject*)mParent)->isAvatar()) + { + // we have changed the position of an attachment, so we need to clamp it + LLVOAvatar *avatar = (LLVOAvatar*)mParent; -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - count += sizeof(U16)*3; - setVelocity(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size)); + avatar->clampAttachmentPositions(); + } -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - count += sizeof(U16)*3; - setAcceleration(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size)); + // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps + if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) + { + record(LLStatViewer::AGENT_POSITION_SNAP, LLUnit(diff.length())); + } + } -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - count += sizeof(U16)*4; - new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); - new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); - new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); - new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f); + if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO)) + || (new_angv != old_angv)) + { + if (new_rot != mPreviousRotation) + { + resetRot(); + } + else if (new_angv != old_angv) + { + if (flagUsePhysics()) + { + resetRot(); + } + else + { + resetRotTime(); + } + } -#ifdef LL_BIG_ENDIAN - htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6); - val = valswizzle; -#else - val = (U16 *) &data[count]; -#endif - new_angv.set(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size)); - setAngularVelocity(new_angv); - break; - - case 16: - // this is a terse 8 update - this_update_precision = 8; - test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); - new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); - new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); - - setVelocity(U8_to_F32(data[3], -size, size), - U8_to_F32(data[4], -size, size), - U8_to_F32(data[5], -size, size) ); - - setAcceleration(U8_to_F32(data[6], -size, size), - U8_to_F32(data[7], -size, size), - U8_to_F32(data[8], -size, size) ); - - new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); - new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); - new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); - new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); - - new_angv.set(U8_to_F32(data[13], -size, size), - U8_to_F32(data[14], -size, size), - U8_to_F32(data[15], -size, size) ); - setAngularVelocity(new_angv); - break; - } - - U8 state; - mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); - mAttachmentState = state; - break; - } - - default: - break; - - } - } - else - { - // handle the compressed case - LLUUID sound_uuid; - LLUUID owner_id; - F32 gain = 0; - U8 sound_flags = 0; - F32 cutoff = 0; - - U16 val[4]; - - U8 state; - - dp->unpackU8(state, "State"); - mAttachmentState = state; - - switch(update_type) - { - case OUT_TERSE_IMPROVED: - { -#ifdef DEBUG_UPDATE_TYPE - LL_INFOS() << "CompTI:" << getID() << LL_ENDL; -#endif - U8 value; - dp->unpackU8(value, "agent"); - if (value) - { - LLVector4 collision_plane; - dp->unpackVector4(collision_plane, "Plane"); - ((LLVOAvatar*)this)->setFootPlane(collision_plane); - } - test_pos_parent = getPosition(); - dp->unpackVector3(new_pos_parent, "Pos"); - dp->unpackU16(val[VX], "VelX"); - dp->unpackU16(val[VY], "VelY"); - dp->unpackU16(val[VZ], "VelZ"); - setVelocity(U16_to_F32(val[VX], -128.f, 128.f), - U16_to_F32(val[VY], -128.f, 128.f), - U16_to_F32(val[VZ], -128.f, 128.f)); - dp->unpackU16(val[VX], "AccX"); - dp->unpackU16(val[VY], "AccY"); - dp->unpackU16(val[VZ], "AccZ"); - setAcceleration(U16_to_F32(val[VX], -64.f, 64.f), - U16_to_F32(val[VY], -64.f, 64.f), - U16_to_F32(val[VZ], -64.f, 64.f)); - - dp->unpackU16(val[VX], "ThetaX"); - dp->unpackU16(val[VY], "ThetaY"); - dp->unpackU16(val[VZ], "ThetaZ"); - dp->unpackU16(val[VS], "ThetaS"); - new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); - new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); - new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); - new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f); - dp->unpackU16(val[VX], "AccX"); - dp->unpackU16(val[VY], "AccY"); - dp->unpackU16(val[VZ], "AccZ"); - new_angv.set(U16_to_F32(val[VX], -64.f, 64.f), - U16_to_F32(val[VY], -64.f, 64.f), - U16_to_F32(val[VZ], -64.f, 64.f)); - setAngularVelocity(new_angv); - } - break; - case OUT_FULL_COMPRESSED: - case OUT_FULL_CACHED: - { -#ifdef DEBUG_UPDATE_TYPE - LL_INFOS() << "CompFull:" << getID() << LL_ENDL; -#endif - setObjectCostStale(); - - if (isSelected()) - { - gFloaterTools->dirty(); - } - - dp->unpackU32(crc, "CRC"); - mTotalCRC = crc; - dp->unpackU8(material, "Material"); - U8 old_material = getMaterial(); - if (old_material != material) - { - setMaterial(material); - if (mDrawable.notNull()) - { - gPipeline.markMoved(mDrawable, FALSE); // undamped - } - } - dp->unpackU8(click_action, "ClickAction"); - setClickAction(click_action); - dp->unpackVector3(new_scale, "Scale"); - dp->unpackVector3(new_pos_parent, "Pos"); - LLVector3 vec; - dp->unpackVector3(vec, "Rot"); - new_rot.unpackFromVector3(vec); - setAcceleration(LLVector3::zero); - - U32 value; - dp->unpackU32(value, "SpecialCode"); - dp->setPassFlags(value); - dp->unpackUUID(owner_id, "Owner"); - - mOwnerID = owner_id; - - if (value & 0x80) - { - dp->unpackVector3(new_angv, "Omega"); - setAngularVelocity(new_angv); - } - - if (value & 0x20) - { - dp->unpackU32(parent_id, "ParentID"); - } - else - { - parent_id = 0; - } - - S32 sp_size; - U32 size; - if (value & 0x2) - { - sp_size = 1; - delete [] mData; - mData = new U8[1]; - dp->unpackU8(((U8*)mData)[0], "TreeData"); - } - else if (value & 0x1) - { - dp->unpackU32(size, "ScratchPadSize"); - delete [] mData; - mData = new U8[size]; - dp->unpackBinaryData((U8 *)mData, sp_size, "PartData"); - } - else - { - mData = NULL; - } - - // Setup object text - if (!mText && (value & 0x4)) - { - initHudText(); - } - - if (value & 0x4) - { - std::string temp_string; - dp->unpackString(temp_string, "Text"); - - LLColor4U coloru; - dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); - coloru.mV[3] = 255 - coloru.mV[3]; - mText->setColor(LLColor4(coloru)); - mText->setString(temp_string); + // Remember the last rotation value + mPreviousRotation = new_rot; - mHudText = temp_string; - mHudTextColor = LLColor4(coloru); + // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega) + setRotation(new_rot * mAngularVelocityRot); + setChanged(ROTATED | SILHOUETTE); + } + + if ( gShowObjectUpdates ) + { + LLColor4 color; + if (update_type == OUT_TERSE_IMPROVED) + { + color.setVec(0.f, 0.f, 1.f, 1.f); + } + else + { + color.setVec(1.f, 0.f, 0.f, 1.f); + } + gPipeline.addDebugBlip(getPositionAgent(), color); + LL_DEBUGS("MessageBlip") << "Update type " << (S32)update_type << " blip for local " << mLocalID << " at " << getPositionAgent() << LL_ENDL; + } - setChanged(TEXTURE); - } - else - { - if (mText.notNull()) - { - mText->markDead(); - mText = NULL; - } - mHudText.clear(); - } + const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; - std::string media_url; - if (value & 0x200) - { - dp->unpackString(media_url, "MediaURL"); - } - retval |= checkMediaURL(media_url); + llassert(vel_mag_sq >= 0.f); + llassert(accel_mag_sq >= 0.f); + llassert(getAngularVelocity().magVecSquared() >= 0.f); - // - // Unpack particle system data (legacy) - // - if (value & 0x8) - { - unpackParticleSource(*dp, owner_id, true); - } - else if (!(value & 0x400)) - { - deleteParticleSource(); - } - - // Mark all extra parameters not used - std::unordered_map::iterator iter; - for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) - { - iter->second->in_use = FALSE; - } - - // Unpack extra params - U8 num_parameters; - dp->unpackU8(num_parameters, "num_params"); - U8 param_block[MAX_OBJECT_PARAMS_SIZE]; - for (U8 param=0; paramunpackU16(param_type, "param_type"); - dp->unpackBinaryData(param_block, param_size, "param_data"); - //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL; - LLDataPackerBinaryBuffer dp2(param_block, param_size); - unpackParameterEntry(param_type, &dp2); - } - - for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) - { - if (!iter->second->in_use) - { - // Send an update message in case it was formerly in use - parameterChanged(iter->first, iter->second->data, FALSE, false); - } - } - - if (value & 0x10) - { - dp->unpackUUID(sound_uuid, "SoundUUID"); - dp->unpackF32(gain, "SoundGain"); - dp->unpackU8(sound_flags, "SoundFlags"); - dp->unpackF32(cutoff, "SoundRadius"); - } - - if (value & 0x100) - { - std::string name_value_list; - dp->unpackString(name_value_list, "NV"); - - setNameValueList(name_value_list); - } - - mTotalCRC = crc; - mSoundCutOffRadius = cutoff; - - setAttachedSound(sound_uuid, owner_id, gain, sound_flags); - - // only get these flags on updates from sim, not cached ones - // Preload these five flags for every object. - // Finer shades require the object to be selected, and the selection manager - // stores the extended permission info. - if(mesgsys != NULL) - { - U32 flags; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); - loadFlags(flags); - } - } - break; - - default: - break; - } - } - - // - // Fix object parenting. - // - BOOL b_changed_status = FALSE; - - if (OUT_TERSE_IMPROVED != update_type) - { - // We only need to update parenting on full updates, terse updates - // don't send parenting information. - if (!cur_parentp) - { - if (parent_id == 0) - { - // No parent now, no parent in message -> do nothing - } - else - { - // No parent now, new parent in message -> attach to that parent if possible - LLUUID parent_uuid; - - if(mesgsys != NULL) - { - LLViewerObjectList::getUUIDFromLocal(parent_uuid, - parent_id, - mesgsys->getSenderIP(), - mesgsys->getSenderPort()); - } - else - { - LLViewerObjectList::getUUIDFromLocal(parent_uuid, - parent_id, - mRegionp->getHost().getAddress(), - mRegionp->getHost().getPort()); - } - - LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid); - - // - // Check to see if we have the corresponding viewer object for the parent. - // - if (sent_parentp && sent_parentp->getParent() == this) - { - // Try to recover if we attempt to attach a parent to its child - LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL; - this->removeChild(sent_parentp); - sent_parentp->setDrawableParent(NULL); - } - - if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead()) - { - if (((LLViewerObject*)sent_parentp)->isAvatar()) - { - //LL_DEBUGS("Avatar") << "ATT got object update for attachment " << LL_ENDL; - } - - // - // We have a viewer object for the parent, and it's not dead. - // Do the actual reparenting here. - // - - // new parent is valid - b_changed_status = TRUE; - // ...no current parent, so don't try to remove child - if (mDrawable.notNull()) - { - if (mDrawable->isDead() || !mDrawable->getVObj()) - { - LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL; - sent_parentp->addChild(this); - } - else - { - if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1 - { - // Bad, we got a cycle somehow. - // Kill both the parent and the child, and - // set cache misses for both of them. - LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL; - LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL; - LL_WARNS() << "Adding to cache miss list" << LL_ENDL; - setParent(NULL); - sent_parentp->setParent(NULL); - getRegion()->addCacheMissFull(getLocalID()); - getRegion()->addCacheMissFull(sent_parentp->getLocalID()); - gObjectList.killObject(sent_parentp); - gObjectList.killObject(this); - return retval; - } - sent_parentp->addChild(this); - // make sure this object gets a non-damped update - if (sent_parentp->mDrawable.notNull()) - { - gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped - } - } - } - else - { - sent_parentp->addChild(this); - } - - // Show particles, icon and HUD - hideExtraDisplayItems( FALSE ); - - setChanged(MOVED | SILHOUETTE); - } - else - { - // - // No corresponding viewer object for the parent, put the various - // pieces on the orphan list. - // - - //parent_id - U32 ip, port; - - if(mesgsys != NULL) - { - ip = mesgsys->getSenderIP(); - port = mesgsys->getSenderPort(); - } - else - { - ip = mRegionp->getHost().getAddress(); - port = mRegionp->getHost().getPort(); - } - gObjectList.orphanize(this, parent_id, ip, port); - - // Hide particles, icon and HUD - hideExtraDisplayItems( TRUE ); - } - } - } - else - { - // BUG: this is a bad assumption once border crossing is alowed - if ( (parent_id == cur_parentp->mLocalID) - &&(update_type == OUT_TERSE_IMPROVED)) - { - // Parent now, same parent in message -> do nothing - - // Debugging for suspected problems with local ids. - //LLUUID parent_uuid; - //LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() ); - //if (parent_uuid != cur_parentp->getID() ) - //{ - // LL_ERRS() << "Local ID match but UUID mismatch of viewer object" << LL_ENDL; - //} - } - else - { - // Parented now, different parent in message - LLViewerObject *sent_parentp; - if (parent_id == 0) - { - // - // This object is no longer parented, we sent in a zero parent ID. - // - sent_parentp = NULL; - } - else - { - LLUUID parent_uuid; - - if(mesgsys != NULL) - { - LLViewerObjectList::getUUIDFromLocal(parent_uuid, - parent_id, - gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); - } - else - { - LLViewerObjectList::getUUIDFromLocal(parent_uuid, - parent_id, - mRegionp->getHost().getAddress(), - mRegionp->getHost().getPort()); - } - sent_parentp = gObjectList.findObject(parent_uuid); - - if (isAvatar()) - { - // This logic is meant to handle the case where a sitting avatar has reached a new sim - // ahead of the object she was sitting on (which is common as objects are transfered through - // a slower route than agents)... - // In this case, the local id for the object will not be valid, since the viewer has not received - // a full update for the object from that sim yet, so we assume that the agent is still sitting - // where she was originally. --RN - if (!sent_parentp) - { - sent_parentp = cur_parentp; - } - } - else if (!sent_parentp) - { - // - // Switching parents, but we don't know the new parent. - // - U32 ip, port; - - if(mesgsys != NULL) - { - ip = mesgsys->getSenderIP(); - port = mesgsys->getSenderPort(); - } - else - { - ip = mRegionp->getHost().getAddress(); - port = mRegionp->getHost().getPort(); - } - - // We're an orphan, flag things appropriately. - gObjectList.orphanize(this, parent_id, ip, port); - } - } - - // Reattach if possible. - if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this) - { - // New parent is valid, detach and reattach - b_changed_status = TRUE; - if (mDrawable.notNull()) - { - if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2 - { - // Bad, we got a cycle somehow. - // Kill both the parent and the child, and - // set cache misses for both of them. - LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL; - LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL; - LL_WARNS() << "Adding to cache miss list" << LL_ENDL; - setParent(NULL); - sent_parentp->setParent(NULL); - getRegion()->addCacheMissFull(getLocalID()); - getRegion()->addCacheMissFull(sent_parentp->getLocalID()); - gObjectList.killObject(sent_parentp); - gObjectList.killObject(this); - return retval; - } - // make sure this object gets a non-damped update - } - cur_parentp->removeChild(this); - sent_parentp->addChild(this); - setChanged(MOVED | SILHOUETTE); - sent_parentp->setChanged(MOVED | SILHOUETTE); - if (sent_parentp->mDrawable.notNull()) - { - gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped - } - } - else if (!sent_parentp) - { - bool remove_parent = true; - // No new parent, or the parent that we sent doesn't exist on the viewer. - LLViewerObject *parentp = (LLViewerObject *)getParent(); - if (parentp) - { - if (parentp->getRegion() != getRegion()) - { - // This is probably an object flying across a region boundary, the - // object probably ISN'T being reparented, but just got an object - // update out of order (child update before parent). - //LL_INFOS() << "Don't reparent object handoffs!" << LL_ENDL; - remove_parent = false; - } - } - - if (remove_parent) - { - b_changed_status = TRUE; - if (mDrawable.notNull()) - { - // clear parent to removeChild can put the drawable on the damped list - setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3 - } - - cur_parentp->removeChild(this); - - setChanged(MOVED | SILHOUETTE); - - if (mDrawable.notNull()) - { - // make sure this object gets a non-damped update - gPipeline.markMoved(mDrawable, FALSE); // undamped - } - } - } - } - } - } - - new_rot.normQuat(); - - if (sPingInterpolate && mesgsys != NULL) - { - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender()); - if (cdp) - { - // Note: delay is U32 and usually less then second, - // converting it into seconds with valueInUnits will result in 0 - F32 ping_delay = 0.5f * time_dilation * ( ((F32)cdp->getPingDelay().value()) * 0.001f + gFrameDTClamped); - LLVector3 diff = getVelocity() * ping_delay; - new_pos_parent += diff; - } - else - { - LL_WARNS() << "findCircuit() returned NULL; skipping interpolation" << LL_ENDL; - } - } - - ////////////////////////// - // - // Set the generic change flags... - // - // - - // If we're going to skip this message, why are we - // doing all the parenting, etc above? - if(mesgsys != NULL) - { - U32 packet_id = mesgsys->getCurrentRecvPacketID(); - if (packet_id < mLatestRecvPacketID && - mLatestRecvPacketID - packet_id < 65536) - { - //skip application of this message, it's old - return retval; - } - mLatestRecvPacketID = packet_id; - } - - // Set the change flags for scale - if (new_scale != getScale()) - { - setChanged(SCALED | SILHOUETTE); - setScale(new_scale); // Must follow setting permYouOwner() - } - - // first, let's see if the new position is actually a change - - //static S32 counter = 0; - - F32 vel_mag_sq = getVelocity().magVecSquared(); - F32 accel_mag_sq = getAcceleration().magVecSquared(); - - if ( ((b_changed_status)||(test_pos_parent != new_pos_parent)) - ||( (!isSelected()) - &&( (vel_mag_sq != 0.f) - ||(accel_mag_sq != 0.f) - ||(this_update_precision > mBestUpdatePrecision)))) - { - mBestUpdatePrecision = this_update_precision; - - LLVector3 diff = new_pos_parent - test_pos_parent ; - F32 mag_sqr = diff.magVecSquared() ; - if(llfinite(mag_sqr)) - { - setPositionParent(new_pos_parent); - } - else - { - LL_WARNS() << "Can not move the object/avatar to an infinite location!" << LL_ENDL ; - - retval |= INVALID_UPDATE ; - } - - if (mParent && ((LLViewerObject*)mParent)->isAvatar()) - { - // we have changed the position of an attachment, so we need to clamp it - LLVOAvatar *avatar = (LLVOAvatar*)mParent; - - avatar->clampAttachmentPositions(); - } - - // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps - if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) - { - record(LLStatViewer::AGENT_POSITION_SNAP, LLUnit(diff.length())); - } - } - - if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO)) - || (new_angv != old_angv)) - { - if (new_rot != mPreviousRotation) - { - resetRot(); - } - else if (new_angv != old_angv) - { - if (flagUsePhysics()) - { - resetRot(); - } - else - { - resetRotTime(); - } - } - - // Remember the last rotation value - mPreviousRotation = new_rot; - - // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega) - setRotation(new_rot * mAngularVelocityRot); - setChanged(ROTATED | SILHOUETTE); - } - - if ( gShowObjectUpdates ) - { - LLColor4 color; - if (update_type == OUT_TERSE_IMPROVED) - { - color.setVec(0.f, 0.f, 1.f, 1.f); - } - else - { - color.setVec(1.f, 0.f, 0.f, 1.f); - } - gPipeline.addDebugBlip(getPositionAgent(), color); - LL_DEBUGS("MessageBlip") << "Update type " << (S32)update_type << " blip for local " << mLocalID << " at " << getPositionAgent() << LL_ENDL; - } - - const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; - - llassert(vel_mag_sq >= 0.f); - llassert(accel_mag_sq >= 0.f); - llassert(getAngularVelocity().magVecSquared() >= 0.f); - - if ((MAG_CUTOFF >= vel_mag_sq) && - (MAG_CUTOFF >= accel_mag_sq) && - (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) - { - mStatic = TRUE; // This object doesn't move! - } - else - { - mStatic = FALSE; - } + if ((MAG_CUTOFF >= vel_mag_sq) && + (MAG_CUTOFF >= accel_mag_sq) && + (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) + { + mStatic = TRUE; // This object doesn't move! + } + else + { + mStatic = FALSE; + } // BUG: This code leads to problems during group rotate and any scale operation. -// Small discepencies between the simulator and viewer representations cause the +// Small discepencies between the simulator and viewer representations cause the // selection center to creep, leading to objects moving around the wrong center. -// +// // Removing this, however, means that if someone else drags an object you have // selected, your selection center and dialog boxes will be wrong. It also means // that higher precision information on selected objects will be ignored. // // I believe the group rotation problem is fixed. JNC 1.21.2002 // - // Additionally, if any child is selected, need to update the dialogs and selection - // center. - BOOL needs_refresh = mUserSelected; - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - needs_refresh = needs_refresh || child->mUserSelected; - } + // Additionally, if any child is selected, need to update the dialogs and selection + // center. + BOOL needs_refresh = mUserSelected; + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + needs_refresh = needs_refresh || child->mUserSelected; + } static LLCachedControl allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE); - if (needs_refresh) - { - LLSelectMgr::getInstance()->updateSelectionCenter(); - dialog_refresh_all(); - } + if (needs_refresh) + { + LLSelectMgr::getInstance()->updateSelectionCenter(); + dialog_refresh_all(); + } else if (allow_select_avatar && asAvatar()) { // Override any avatar position updates received @@ -2500,280 +2500,280 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } - // Mark update time as approx. now, with the ping delay. - // Ping delay is off because it's not set for velocity interpolation, causing - // much jumping and hopping around... + // Mark update time as approx. now, with the ping delay. + // Ping delay is off because it's not set for velocity interpolation, causing + // much jumping and hopping around... -// U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay(); - mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds(); - mLastMessageUpdateSecs = mLastInterpUpdateSecs; - if (mDrawable.notNull()) - { - // Don't clear invisibility flag on update if still orphaned! - if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned) - { -// LL_DEBUGS() << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << LL_ENDL; - mDrawable->clearState(LLDrawable::FORCE_INVISIBLE); - gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL); - } - } +// U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay(); + mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds(); + mLastMessageUpdateSecs = mLastInterpUpdateSecs; + if (mDrawable.notNull()) + { + // Don't clear invisibility flag on update if still orphaned! + if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned) + { +// LL_DEBUGS() << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << LL_ENDL; + mDrawable->clearState(LLDrawable::FORCE_INVISIBLE); + gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL); + } + } - // Update special hover cursor status - bool special_hover_cursor = specialHoverCursor(); - if (old_special_hover_cursor != special_hover_cursor - && mDrawable.notNull()) - { - mDrawable->updateSpecialHoverCursor(special_hover_cursor); - } + // Update special hover cursor status + bool special_hover_cursor = specialHoverCursor(); + if (old_special_hover_cursor != special_hover_cursor + && mDrawable.notNull()) + { + mDrawable->updateSpecialHoverCursor(special_hover_cursor); + } - return retval; + return retval; } BOOL LLViewerObject::isActive() const { - return TRUE; + return TRUE; } //load flags from cache or from message void LLViewerObject::loadFlags(U32 flags) { - if(flags == (U32)(-1)) - { - return; //invalid - } + if(flags == (U32)(-1)) + { + return; //invalid + } - // keep local flags and overwrite remote-controlled flags - mFlags = (mFlags & FLAGS_LOCAL) | flags; + // keep local flags and overwrite remote-controlled flags + mFlags = (mFlags & FLAGS_LOCAL) | flags; - // ...new objects that should come in selected need to be added to the selected list - mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); - return; + // ...new objects that should come in selected need to be added to the selected list + mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + return; } void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time) { - if (!mDead) - { - if (!mStatic && sVelocityInterpolate && !isSelected()) - { - // calculate dt from last update - F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f; - F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value(); - F32 dt = time_dilation * dt_raw; + if (!mDead) + { + if (!mStatic && sVelocityInterpolate && !isSelected()) + { + // calculate dt from last update + F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f; + F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value(); + F32 dt = time_dilation * dt_raw; - applyAngularVelocity(dt); + applyAngularVelocity(dt); - if (isAttachment()) - { - mLastInterpUpdateSecs = (F64Seconds)frame_time; - return; - } - else - { // Move object based on it's velocity and rotation - interpolateLinearMotion(frame_time, dt); - } - } + if (isAttachment()) + { + mLastInterpUpdateSecs = (F64Seconds)frame_time; + return; + } + else + { // Move object based on it's velocity and rotation + interpolateLinearMotion(frame_time, dt); + } + } - updateDrawable(FALSE); - } + updateDrawable(FALSE); + } } // Move an object due to idle-time viewer side updates by interpolating motion void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds) { - // linear motion - // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object - // updates represents the average velocity of the last timestep, rather than the final velocity. - // the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically - // - // *TODO: should also wrap linear accel/velocity in check - // to see if object is selected, instead of explicitly - // zeroing it out - - F32 dt = dt_seconds; - F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs; - if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f) - { - return; - } - - LLVector3 accel = getAcceleration(); - LLVector3 vel = getVelocity(); - - if (sMaxUpdateInterpolationTime <= (F64Seconds)0.0) - { // Old code path ... unbounded, simple interpolation - if (!(accel.isExactlyZero() && vel.isExactlyZero())) - { - LLVector3 pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt; - - // region local - setPositionRegion(pos + getPositionRegion()); - setVelocity(vel + accel*dt); - - // for objects that are spinning but not translating, make sure to flag them as having moved - setChanged(MOVED | SILHOUETTE); - } - } - else if (!accel.isExactlyZero() || !vel.isExactlyZero()) // object is moving - { // Object is moving, and hasn't been too long since we got an update from the server - - // Calculate predicted position and velocity - LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt; - LLVector3 new_v = accel * dt; - - if (time_since_last_update > sPhaseOutUpdateInterpolationTime && - sPhaseOutUpdateInterpolationTime > (F64Seconds)0.0) - { // Haven't seen a viewer update in a while, check to see if the circuit is still active - if (mRegionp) - { // The simulator will NOT send updates if the object continues normally on the path - // predicted by the velocity and the acceleration (often gravity) sent to the viewer - // So check to see if the circuit is blocked, which means the sim is likely in a long lag - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() ); - if (cdp) - { - // Find out how many seconds since last packet arrived on the circuit - F64Seconds time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime(); - - if (!cdp->isAlive() || // Circuit is dead or blocked - cdp->isBlocked() || // or doesn't seem to be getting any packets - (time_since_last_packet > sPhaseOutUpdateInterpolationTime)) - { - // Start to reduce motion interpolation since we haven't seen a server update in a while - F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs; - F64 phase_out = 1.0; - if (time_since_last_update > sMaxUpdateInterpolationTime) - { // Past the time limit, so stop the object - phase_out = 0.0; - //LL_INFOS() << "Motion phase out to zero" << LL_ENDL; - - // Kill angular motion as well. Note - not adding this due to paranoia - // about stopping rotation for llTargetOmega objects and not having it restart - // setAngularVelocity(LLVector3::zero); - } - else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime) - { // Last update was already phased out a bit - phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / - (sMaxUpdateInterpolationTime - time_since_last_interpolation); - //LL_INFOS() << "Continuing motion phase out of " << (F32) phase_out << LL_ENDL; - } - else - { // Phase out from full value - phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / - (sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime); - //LL_INFOS() << "Starting motion phase out of " << (F32) phase_out << LL_ENDL; - } - phase_out = llclamp(phase_out, 0.0, 1.0); - - new_pos = new_pos * ((F32) phase_out); - new_v = new_v * ((F32) phase_out); - } - } - } - } - - new_pos = new_pos + getPositionRegion(); - new_v = new_v + vel; - - - // Clamp interpolated position to minimum underground and maximum region height - LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); - F32 min_height; - if (isAvatar()) - { // Make a better guess about AVs not going underground - min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global); - min_height += (0.5f * getScale().mV[VZ]); - } - else - { // This will put the object underground, but we can't tell if it will stop - // at ground level or not - min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global); - // Cap maximum height - new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]); - } - - new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]); - - // Check to see if it's going off the region - LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f); - if (temp.clamp(0.f, mRegionp->getWidth())) - { // Going off this region, so see if we might end up on another region - LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); - new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); // Re-fetch in case it got clipped above - - // Clip the positions to known regions - LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global); - if (clip_pos_global != new_pos_global) - { - // Was clipped, so this means we hit a edge where there is no region to enter - LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global); - LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to " - << clip_pos - << " from " << new_pos << LL_ENDL; - new_pos = clip_pos; - - // Stop motion and get server update for bouncing on the edge - new_v.clear(); - setAcceleration(LLVector3::zero); - } - else - { - // Check for how long we are crossing. - // Note: theoretically we can find time from velocity, acceleration and - // distance from border to new position, but it is not going to work - // if 'phase_out' activates - if (mRegionCrossExpire == 0) - { - // Workaround: we can't accurately figure out time when we cross border - // so just write down time 'after the fact', it is far from optimal in - // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first - LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL; - mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime; - } - else if (frame_time > mRegionCrossExpire) - { - // Predicting crossing over 1s, stop motion - // Stop motion - LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL; - new_v.clear(); - setAcceleration(LLVector3::zero); - mRegionCrossExpire = 0; - } - } - } - else - { - mRegionCrossExpire = 0; - } - - // Set new position and velocity - setPositionRegion(new_pos); - setVelocity(new_v); - - // for objects that are spinning but not translating, make sure to flag them as having moved - setChanged(MOVED | SILHOUETTE); - } - - // Update the last time we did anything - mLastInterpUpdateSecs = frame_time; + // linear motion + // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object + // updates represents the average velocity of the last timestep, rather than the final velocity. + // the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically + // + // *TODO: should also wrap linear accel/velocity in check + // to see if object is selected, instead of explicitly + // zeroing it out + + F32 dt = dt_seconds; + F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs; + if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f) + { + return; + } + + LLVector3 accel = getAcceleration(); + LLVector3 vel = getVelocity(); + + if (sMaxUpdateInterpolationTime <= (F64Seconds)0.0) + { // Old code path ... unbounded, simple interpolation + if (!(accel.isExactlyZero() && vel.isExactlyZero())) + { + LLVector3 pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt; + + // region local + setPositionRegion(pos + getPositionRegion()); + setVelocity(vel + accel*dt); + + // for objects that are spinning but not translating, make sure to flag them as having moved + setChanged(MOVED | SILHOUETTE); + } + } + else if (!accel.isExactlyZero() || !vel.isExactlyZero()) // object is moving + { // Object is moving, and hasn't been too long since we got an update from the server + + // Calculate predicted position and velocity + LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt; + LLVector3 new_v = accel * dt; + + if (time_since_last_update > sPhaseOutUpdateInterpolationTime && + sPhaseOutUpdateInterpolationTime > (F64Seconds)0.0) + { // Haven't seen a viewer update in a while, check to see if the circuit is still active + if (mRegionp) + { // The simulator will NOT send updates if the object continues normally on the path + // predicted by the velocity and the acceleration (often gravity) sent to the viewer + // So check to see if the circuit is blocked, which means the sim is likely in a long lag + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() ); + if (cdp) + { + // Find out how many seconds since last packet arrived on the circuit + F64Seconds time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime(); + + if (!cdp->isAlive() || // Circuit is dead or blocked + cdp->isBlocked() || // or doesn't seem to be getting any packets + (time_since_last_packet > sPhaseOutUpdateInterpolationTime)) + { + // Start to reduce motion interpolation since we haven't seen a server update in a while + F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs; + F64 phase_out = 1.0; + if (time_since_last_update > sMaxUpdateInterpolationTime) + { // Past the time limit, so stop the object + phase_out = 0.0; + //LL_INFOS() << "Motion phase out to zero" << LL_ENDL; + + // Kill angular motion as well. Note - not adding this due to paranoia + // about stopping rotation for llTargetOmega objects and not having it restart + // setAngularVelocity(LLVector3::zero); + } + else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime) + { // Last update was already phased out a bit + phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / + (sMaxUpdateInterpolationTime - time_since_last_interpolation); + //LL_INFOS() << "Continuing motion phase out of " << (F32) phase_out << LL_ENDL; + } + else + { // Phase out from full value + phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / + (sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime); + //LL_INFOS() << "Starting motion phase out of " << (F32) phase_out << LL_ENDL; + } + phase_out = llclamp(phase_out, 0.0, 1.0); + + new_pos = new_pos * ((F32) phase_out); + new_v = new_v * ((F32) phase_out); + } + } + } + } + + new_pos = new_pos + getPositionRegion(); + new_v = new_v + vel; + + + // Clamp interpolated position to minimum underground and maximum region height + LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); + F32 min_height; + if (isAvatar()) + { // Make a better guess about AVs not going underground + min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global); + min_height += (0.5f * getScale().mV[VZ]); + } + else + { // This will put the object underground, but we can't tell if it will stop + // at ground level or not + min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global); + // Cap maximum height + new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]); + } + + new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]); + + // Check to see if it's going off the region + LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f); + if (temp.clamp(0.f, mRegionp->getWidth())) + { // Going off this region, so see if we might end up on another region + LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); + new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); // Re-fetch in case it got clipped above + + // Clip the positions to known regions + LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global); + if (clip_pos_global != new_pos_global) + { + // Was clipped, so this means we hit a edge where there is no region to enter + LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global); + LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to " + << clip_pos + << " from " << new_pos << LL_ENDL; + new_pos = clip_pos; + + // Stop motion and get server update for bouncing on the edge + new_v.clear(); + setAcceleration(LLVector3::zero); + } + else + { + // Check for how long we are crossing. + // Note: theoretically we can find time from velocity, acceleration and + // distance from border to new position, but it is not going to work + // if 'phase_out' activates + if (mRegionCrossExpire == 0) + { + // Workaround: we can't accurately figure out time when we cross border + // so just write down time 'after the fact', it is far from optimal in + // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first + LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL; + mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime; + } + else if (frame_time > mRegionCrossExpire) + { + // Predicting crossing over 1s, stop motion + // Stop motion + LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL; + new_v.clear(); + setAcceleration(LLVector3::zero); + mRegionCrossExpire = 0; + } + } + } + else + { + mRegionCrossExpire = 0; + } + + // Set new position and velocity + setPositionRegion(new_pos); + setVelocity(new_v); + + // for objects that are spinning but not translating, make sure to flag them as having moved + setChanged(MOVED | SILHOUETTE); + } + + // Update the last time we did anything + mLastInterpUpdateSecs = frame_time; } BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size) { - delete [] mData; + delete [] mData; - if (datap) - { - mData = new U8[data_size]; - if (!mData) - { - return FALSE; - } - memcpy(mData, datap, data_size); /* Flawfinder: ignore */ - } - return TRUE; + if (datap) + { + mData = new U8[data_size]; + if (!mData) + { + return FALSE; + } + memcpy(mData, datap, data_size); /* Flawfinder: ignore */ + } + return TRUE; } // delete an item in the inventory, but don't tell the server. This is @@ -2781,213 +2781,213 @@ BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size) // This will only delete the first item with an item_id in the list void LLViewerObject::deleteInventoryItem(const LLUUID& item_id) { - if(mInventory) - { - LLInventoryObject::object_list_t::iterator it = mInventory->begin(); - LLInventoryObject::object_list_t::iterator end = mInventory->end(); - for( ; it != end; ++it ) - { - if((*it)->getUUID() == item_id) - { - // This is safe only because we return immediatly. - mInventory->erase(it); // will deref and delete it - return; - } - } - doInventoryCallback(); - } + if(mInventory) + { + LLInventoryObject::object_list_t::iterator it = mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = mInventory->end(); + for( ; it != end; ++it ) + { + if((*it)->getUUID() == item_id) + { + // This is safe only because we return immediatly. + mInventory->erase(it); // will deref and delete it + return; + } + } + doInventoryCallback(); + } } void LLViewerObject::doUpdateInventory( - LLPointer& item, - U8 key, - bool is_new) -{ - LLViewerInventoryItem* old_item = NULL; - if(TASK_INVENTORY_ITEM_KEY == key) - { - old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID()); - } - else if(TASK_INVENTORY_ASSET_KEY == key) - { - old_item = getInventoryItemByAsset(item->getAssetUUID()); - } - LLUUID item_id; - LLUUID new_owner; - LLUUID new_group; - BOOL group_owned = FALSE; - if(old_item) - { - item_id = old_item->getUUID(); - new_owner = old_item->getPermissions().getOwner(); - new_group = old_item->getPermissions().getGroup(); - group_owned = old_item->getPermissions().isGroupOwned(); - old_item = NULL; - } - else - { - item_id = item->getUUID(); - } - if(!is_new && mInventory) - { - // Attempt to update the local inventory. If we can get the - // object perm, we have perfect visibility, so we want the - // serial number to match. Otherwise, take our best guess and - // make sure that the serial number does not match. - deleteInventoryItem(item_id); - LLPermissions perm(item->getPermissions()); - LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); - bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true; - if(obj_perm) - { - perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic); - } - else - { - if(group_owned) - { - perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic); - } - else if(!new_owner.isNull()) - { - // The object used to be in inventory, so we can - // assume the owner and group will match what they are - // there. - perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic); - } - // *FIX: can make an even better guess by using the mPermGroup flags - else if(permYouOwner()) - { - // best guess. - perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic); - --mExpectedInventorySerialNum; - } - else - { - // dummy it up. - perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic); - --mExpectedInventorySerialNum; - } - } - LLViewerInventoryItem* oldItem = item; - LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem); - new_item->setPermissions(perm); - mInventory->push_front(new_item); - doInventoryCallback(); - ++mExpectedInventorySerialNum; - } - else if (is_new) - { - ++mExpectedInventorySerialNum; - } + LLPointer& item, + U8 key, + bool is_new) +{ + LLViewerInventoryItem* old_item = NULL; + if(TASK_INVENTORY_ITEM_KEY == key) + { + old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID()); + } + else if(TASK_INVENTORY_ASSET_KEY == key) + { + old_item = getInventoryItemByAsset(item->getAssetUUID()); + } + LLUUID item_id; + LLUUID new_owner; + LLUUID new_group; + BOOL group_owned = FALSE; + if(old_item) + { + item_id = old_item->getUUID(); + new_owner = old_item->getPermissions().getOwner(); + new_group = old_item->getPermissions().getGroup(); + group_owned = old_item->getPermissions().isGroupOwned(); + old_item = NULL; + } + else + { + item_id = item->getUUID(); + } + if(!is_new && mInventory) + { + // Attempt to update the local inventory. If we can get the + // object perm, we have perfect visibility, so we want the + // serial number to match. Otherwise, take our best guess and + // make sure that the serial number does not match. + deleteInventoryItem(item_id); + LLPermissions perm(item->getPermissions()); + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); + bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true; + if(obj_perm) + { + perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic); + } + else + { + if(group_owned) + { + perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic); + } + else if(!new_owner.isNull()) + { + // The object used to be in inventory, so we can + // assume the owner and group will match what they are + // there. + perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic); + } + // *FIX: can make an even better guess by using the mPermGroup flags + else if(permYouOwner()) + { + // best guess. + perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic); + --mExpectedInventorySerialNum; + } + else + { + // dummy it up. + perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic); + --mExpectedInventorySerialNum; + } + } + LLViewerInventoryItem* oldItem = item; + LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem); + new_item->setPermissions(perm); + mInventory->push_front(new_item); + doInventoryCallback(); + ++mExpectedInventorySerialNum; + } + else if (is_new) + { + ++mExpectedInventorySerialNum; + } } // save a script, which involves removing the old one, and rezzing // in the new one. This method should be called with the asset id // of the new and old script AFTER the bytecode has been saved. void LLViewerObject::saveScript( - const LLViewerInventoryItem* item, - BOOL active, - bool is_new) -{ - /* - * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the - * interaction with doUpdateInventory() called below. - */ - LL_DEBUGS() << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << LL_ENDL; - - LLPointer task_item = - new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), - item->getAssetUUID(), item->getType(), - item->getInventoryType(), - item->getName(), item->getDescription(), - item->getSaleInfo(), item->getFlags(), - item->getCreationDate()); - task_item->setTransactionID(item->getTransactionID()); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RezScript); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - msg->nextBlockFast(_PREHASH_UpdateBlock); - msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID)); - U8 enabled = active; - msg->addBOOLFast(_PREHASH_Enabled, enabled); - msg->nextBlockFast(_PREHASH_InventoryBlock); - task_item->packMessage(msg); - msg->sendReliable(mRegionp->getHost()); - - // do the internal logic - doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new); + const LLViewerInventoryItem* item, + BOOL active, + bool is_new) +{ + /* + * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the + * interaction with doUpdateInventory() called below. + */ + LL_DEBUGS() << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << LL_ENDL; + + LLPointer task_item = + new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), + item->getAssetUUID(), item->getType(), + item->getInventoryType(), + item->getName(), item->getDescription(), + item->getSaleInfo(), item->getFlags(), + item->getCreationDate()); + task_item->setTransactionID(item->getTransactionID()); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RezScript); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + msg->nextBlockFast(_PREHASH_UpdateBlock); + msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID)); + U8 enabled = active; + msg->addBOOLFast(_PREHASH_Enabled, enabled); + msg->nextBlockFast(_PREHASH_InventoryBlock); + task_item->packMessage(msg); + msg->sendReliable(mRegionp->getHost()); + + // do the internal logic + doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new); } void LLViewerObject::moveInventory(const LLUUID& folder_id, - const LLUUID& item_id) -{ - LL_DEBUGS() << "LLViewerObject::moveInventory " << item_id << LL_ENDL; - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MoveTaskInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_FolderID, folder_id); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_LocalID, mLocalID); - msg->addUUIDFast(_PREHASH_ItemID, item_id); - msg->sendReliable(mRegionp->getHost()); - - LLInventoryObject* inv_obj = getInventoryObject(item_id); - if(inv_obj) - { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj; - if(!item->getPermissions().allowCopyBy(gAgent.getID())) - { - deleteInventoryItem(item_id); - ++mExpectedInventorySerialNum; - } - } + const LLUUID& item_id) +{ + LL_DEBUGS() << "LLViewerObject::moveInventory " << item_id << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoveTaskInventory); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_FolderID, folder_id); + msg->nextBlockFast(_PREHASH_InventoryData); + msg->addU32Fast(_PREHASH_LocalID, mLocalID); + msg->addUUIDFast(_PREHASH_ItemID, item_id); + msg->sendReliable(mRegionp->getHost()); + + LLInventoryObject* inv_obj = getInventoryObject(item_id); + if(inv_obj) + { + LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj; + if(!item->getPermissions().allowCopyBy(gAgent.getID())) + { + deleteInventoryItem(item_id); + ++mExpectedInventorySerialNum; + } + } } void LLViewerObject::dirtyInventory() { - // If there aren't any LLVOInventoryListeners, we won't be - // able to update our mInventory when it comes back from the - // simulator, so we should not clear the inventory either. - if(mInventory && !mInventoryCallbacks.empty()) - { - mInventory->clear(); // will deref and delete entries - delete mInventory; - mInventory = NULL; - } - mInventoryDirty = TRUE; + // If there aren't any LLVOInventoryListeners, we won't be + // able to update our mInventory when it comes back from the + // simulator, so we should not clear the inventory either. + if(mInventory && !mInventoryCallbacks.empty()) + { + mInventory->clear(); // will deref and delete entries + delete mInventory; + mInventory = NULL; + } + mInventoryDirty = TRUE; } void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data) { - LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo; - info->mListener = listener; - info->mInventoryData = user_data; - mInventoryCallbacks.push_front(info); + LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo; + info->mListener = listener; + info->mInventoryData = user_data; + mInventoryCallbacks.push_front(info); } void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener) { - if (listener == NULL) - return; - for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); - iter != mInventoryCallbacks.end(); ) - { - callback_list_t::iterator curiter = iter++; - LLInventoryCallbackInfo* info = *curiter; - if (info->mListener == listener) - { - delete info; - mInventoryCallbacks.erase(curiter); - break; - } - } + if (listener == NULL) + return; + for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); + iter != mInventoryCallbacks.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLInventoryCallbackInfo* info = *curiter; + if (info->mListener == listener) + { + delete info; + mInventoryCallbacks.erase(curiter); + break; + } + } } BOOL LLViewerObject::isInventoryPending() @@ -2997,60 +2997,60 @@ BOOL LLViewerObject::isInventoryPending() void LLViewerObject::clearInventoryListeners() { - for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer()); - mInventoryCallbacks.clear(); + for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer()); + mInventoryCallbacks.clear(); } bool LLViewerObject::hasInventoryListeners() { - return !mInventoryCallbacks.empty(); + return !mInventoryCallbacks.empty(); } void LLViewerObject::requestInventory() { - if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty()) - { - mInventory->clear(); // will deref and delete entries - delete mInventory; - mInventory = NULL; - } - - if(mInventory) - { - // inventory is either up to date or doesn't has a listener - // if it is dirty, leave it this way in case we gain a listener - doInventoryCallback(); - } - else - { - // since we are going to request it now - mInventoryDirty = FALSE; - - // Note: throws away duplicate requests - fetchInventoryFromServer(); - } + if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty()) + { + mInventory->clear(); // will deref and delete entries + delete mInventory; + mInventory = NULL; + } + + if(mInventory) + { + // inventory is either up to date or doesn't has a listener + // if it is dirty, leave it this way in case we gain a listener + doInventoryCallback(); + } + else + { + // since we are going to request it now + mInventoryDirty = FALSE; + + // Note: throws away duplicate requests + fetchInventoryFromServer(); + } } void LLViewerObject::fetchInventoryFromServer() { - if (!isInventoryPending()) - { - delete mInventory; - mInventory = NULL; - - // Results in processTaskInv - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RequestTaskInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_LocalID, mLocalID); - msg->sendReliable(mRegionp->getHost()); - - // This will get reset by doInventoryCallback or processTaskInv - mInvRequestState = INVENTORY_REQUEST_PENDING; - } + if (!isInventoryPending()) + { + delete mInventory; + mInventory = NULL; + + // Results in processTaskInv + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RequestTaskInventory); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_InventoryData); + msg->addU32Fast(_PREHASH_LocalID, mLocalID); + msg->sendReliable(mRegionp->getHost()); + + // This will get reset by doInventoryCallback or processTaskInv + mInvRequestState = INVENTORY_REQUEST_PENDING; + } } void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds) @@ -3166,8 +3166,8 @@ void LLViewerObject::linkControlAvatar() return; } mControlAvatar = LLControlAvatar::createControlAvatar(volp); - LL_DEBUGS("AnimatedObjects") << volp->getID() - << " created control av for " + LL_DEBUGS("AnimatedObjects") << volp->getID() + << " created control av for " << (S32) (1+volp->numChildren()) << " prims" << LL_ENDL; } LLControlAvatar *cav = getControlAvatar(); @@ -3217,26 +3217,26 @@ bool LLViewerObject::isAnimatedObject() const struct LLFilenameAndTask { - LLUUID mTaskID; - std::string mFilename; + LLUUID mTaskID; + std::string mFilename; - // for sequencing in case of multiple updates - S16 mSerial; + // for sequencing in case of multiple updates + S16 mSerial; #ifdef _DEBUG - static S32 sCount; - LLFilenameAndTask() - { - ++sCount; - LL_DEBUGS() << "Constructing LLFilenameAndTask: " << sCount << LL_ENDL; - } - ~LLFilenameAndTask() - { - --sCount; - LL_DEBUGS() << "Destroying LLFilenameAndTask: " << sCount << LL_ENDL; - } + static S32 sCount; + LLFilenameAndTask() + { + ++sCount; + LL_DEBUGS() << "Constructing LLFilenameAndTask: " << sCount << LL_ENDL; + } + ~LLFilenameAndTask() + { + --sCount; + LL_DEBUGS() << "Destroying LLFilenameAndTask: " << sCount << LL_ENDL; + } private: - LLFilenameAndTask(const LLFilenameAndTask& rhs); - const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const; + LLFilenameAndTask(const LLFilenameAndTask& rhs); + const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const; #endif }; @@ -3289,7 +3289,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) LLFilenameAndTask* ft = new LLFilenameAndTask; ft->mTaskID = task_id; ft->mSerial = serial; - + // We received version we expected or newer. Load it. object->mInventorySerialNum = ft->mSerial; object->mExpectedInventorySerialNum = ft->mSerial; @@ -3345,154 +3345,154 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status) { - LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data; - LLViewerObject* object = NULL; - - if (ft - && (0 == error_code) - && (object = gObjectList.findObject(ft->mTaskID)) - && ft->mSerial >= object->mInventorySerialNum) - { - object->mInventorySerialNum = ft->mSerial; - LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL; - if (ft->mSerial < object->mExpectedInventorySerialNum) - { - // User managed to change something while inventory was loading - LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL; - } - - if (object->loadTaskInvFile(ft->mFilename)) - { - - LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); - LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); - std::list& pending_lst = object->mPendingInventoryItemsIDs; - - for (; it != end && pending_lst.size(); ++it) - { - LLViewerInventoryItem* item = dynamic_cast(it->get()); - if(item && item->getType() != LLAssetType::AT_CATEGORY) - { - std::list::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); - if (id_it != pending_lst.end()) - { - pending_lst.erase(id_it); - } - } - } - } - else - { - // MAINT-2597 - crash when trying to edit a no-mod object - // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?) - // Stated repro was specific to no-mod objects so failing without user interaction should be safe. - LL_WARNS() << "Trying to load invalid task inventory file. Ignoring file contents." << LL_ENDL; - } - } - else - { - // This Occurs When two requests were made, and the first one - // has already handled it. - LL_DEBUGS() << "Problem loading task inventory. Return code: " - << error_code << LL_ENDL; - } - delete ft; + LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data; + LLViewerObject* object = NULL; + + if (ft + && (0 == error_code) + && (object = gObjectList.findObject(ft->mTaskID)) + && ft->mSerial >= object->mInventorySerialNum) + { + object->mInventorySerialNum = ft->mSerial; + LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL; + if (ft->mSerial < object->mExpectedInventorySerialNum) + { + // User managed to change something while inventory was loading + LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL; + } + + if (object->loadTaskInvFile(ft->mFilename)) + { + + LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); + std::list& pending_lst = object->mPendingInventoryItemsIDs; + + for (; it != end && pending_lst.size(); ++it) + { + LLViewerInventoryItem* item = dynamic_cast(it->get()); + if(item && item->getType() != LLAssetType::AT_CATEGORY) + { + std::list::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); + if (id_it != pending_lst.end()) + { + pending_lst.erase(id_it); + } + } + } + } + else + { + // MAINT-2597 - crash when trying to edit a no-mod object + // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?) + // Stated repro was specific to no-mod objects so failing without user interaction should be safe. + LL_WARNS() << "Trying to load invalid task inventory file. Ignoring file contents." << LL_ENDL; + } + } + else + { + // This Occurs When two requests were made, and the first one + // has already handled it. + LL_DEBUGS() << "Problem loading task inventory. Return code: " + << error_code << LL_ENDL; + } + delete ft; } BOOL LLViewerObject::loadTaskInvFile(const std::string& filename) { - std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename); - llifstream ifs(filename_and_local_path.c_str()); - if(ifs.good()) - { - U32 fail_count = 0; - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - // *NOTE: This buffer size is hard coded into scanf() below. - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - if(mInventory) - { - mInventory->clear(); // will deref and delete it - } - else - { - mInventory = new LLInventoryObject::object_list_t; - } - while(ifs.good()) - { - ifs.getline(buffer, MAX_STRING); - if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */ - { - // Blank file? - LL_WARNS() << "Issue reading from file '" - << filename << "'" << LL_ENDL; - break; - } - else if(0 == strcmp("inv_item", keyword)) - { - LLPointer inv = new LLViewerInventoryItem; - inv->importLegacyStream(ifs); - mInventory->push_front(inv); - } - else if(0 == strcmp("inv_object", keyword)) - { - LLPointer inv = new LLInventoryObject; - inv->importLegacyStream(ifs); - inv->rename("Contents"); - mInventory->push_front(inv); - } - else if (fail_count >= MAX_INV_FILE_READ_FAILS) - { - LL_WARNS() << "Encountered too many unknowns while reading from file: '" - << filename << "'" << LL_ENDL; - break; - } - else - { - // Is there really a point to continue processing? We already failing to display full inventory - fail_count++; - LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '" - << keyword << "'" << LL_ENDL; - } - } - ifs.close(); - LLFile::remove(filename_and_local_path); - } - else - { - LL_WARNS() << "unable to load task inventory: " << filename_and_local_path - << LL_ENDL; - return FALSE; - } - doInventoryCallback(); - - return TRUE; + std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename); + llifstream ifs(filename_and_local_path.c_str()); + if(ifs.good()) + { + U32 fail_count = 0; + char buffer[MAX_STRING]; /* Flawfinder: ignore */ + // *NOTE: This buffer size is hard coded into scanf() below. + char keyword[MAX_STRING]; /* Flawfinder: ignore */ + if(mInventory) + { + mInventory->clear(); // will deref and delete it + } + else + { + mInventory = new LLInventoryObject::object_list_t; + } + while(ifs.good()) + { + ifs.getline(buffer, MAX_STRING); + if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */ + { + // Blank file? + LL_WARNS() << "Issue reading from file '" + << filename << "'" << LL_ENDL; + break; + } + else if(0 == strcmp("inv_item", keyword)) + { + LLPointer inv = new LLViewerInventoryItem; + inv->importLegacyStream(ifs); + mInventory->push_front(inv); + } + else if(0 == strcmp("inv_object", keyword)) + { + LLPointer inv = new LLInventoryObject; + inv->importLegacyStream(ifs); + inv->rename("Contents"); + mInventory->push_front(inv); + } + else if (fail_count >= MAX_INV_FILE_READ_FAILS) + { + LL_WARNS() << "Encountered too many unknowns while reading from file: '" + << filename << "'" << LL_ENDL; + break; + } + else + { + // Is there really a point to continue processing? We already failing to display full inventory + fail_count++; + LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '" + << keyword << "'" << LL_ENDL; + } + } + ifs.close(); + LLFile::remove(filename_and_local_path); + } + else + { + LL_WARNS() << "unable to load task inventory: " << filename_and_local_path + << LL_ENDL; + return FALSE; + } + doInventoryCallback(); + + return TRUE; } -void LLViewerObject::doInventoryCallback() -{ - for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); - iter != mInventoryCallbacks.end(); ) - { - callback_list_t::iterator curiter = iter++; - LLInventoryCallbackInfo* info = *curiter; - if (info->mListener != NULL) - { - info->mListener->inventoryChanged(this, - mInventory, - mInventorySerialNum, - info->mInventoryData); - } - else - { - LL_INFOS() << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << LL_ENDL; - delete info; - mInventoryCallbacks.erase(curiter); - } - } - - // release inventory loading state - mInvRequestXFerId = 0; - mInvRequestState = INVENTORY_REQUEST_STOPPED; +void LLViewerObject::doInventoryCallback() +{ + for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); + iter != mInventoryCallbacks.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLInventoryCallbackInfo* info = *curiter; + if (info->mListener != NULL) + { + info->mListener->inventoryChanged(this, + mInventory, + mInventorySerialNum, + info->mInventoryData); + } + else + { + LL_INFOS() << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << LL_ENDL; + delete info; + mInventoryCallbacks.erase(curiter); + } + } + + // release inventory loading state + mInvRequestXFerId = 0; + mInvRequestState = INVENTORY_REQUEST_STOPPED; } void LLViewerObject::removeInventory(const LLUUID& item_id) @@ -3503,17 +3503,17 @@ void LLViewerObject::removeInventory(const LLUUID& item_id) params["object"] = mID; LLFloaterReg::hideInstance("item_properties", params); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RemoveTaskInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_LocalID, mLocalID); - msg->addUUIDFast(_PREHASH_ItemID, item_id); - msg->sendReliable(mRegionp->getHost()); - deleteInventoryItem(item_id); - ++mExpectedInventorySerialNum; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RemoveTaskInventory); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_InventoryData); + msg->addU32Fast(_PREHASH_LocalID, mLocalID); + msg->addUUIDFast(_PREHASH_ItemID, item_id); + msg->sendReliable(mRegionp->getHost()); + deleteInventoryItem(item_id); + ++mExpectedInventorySerialNum; } bool LLViewerObject::isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type) @@ -3565,136 +3565,136 @@ void LLViewerObject::updateMaterialInventory(LLViewerInventoryItem* item, U8 key } void LLViewerObject::updateInventory( - LLViewerInventoryItem* item, - U8 key, - bool is_new) -{ - // This slices the object into what we're concerned about on the - // viewer. The simulator will take the permissions and transfer - // ownership. - LLPointer task_item = - new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), - item->getAssetUUID(), item->getType(), - item->getInventoryType(), - item->getName(), item->getDescription(), - item->getSaleInfo(), - item->getFlags(), - item->getCreationDate()); - task_item->setTransactionID(item->getTransactionID()); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateTaskInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_UpdateData); - msg->addU32Fast(_PREHASH_LocalID, mLocalID); - msg->addU8Fast(_PREHASH_Key, key); - msg->nextBlockFast(_PREHASH_InventoryData); - task_item->packMessage(msg); - msg->sendReliable(mRegionp->getHost()); - - // do the internal logic - doUpdateInventory(task_item, key, is_new); + LLViewerInventoryItem* item, + U8 key, + bool is_new) +{ + // This slices the object into what we're concerned about on the + // viewer. The simulator will take the permissions and transfer + // ownership. + LLPointer task_item = + new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), + item->getAssetUUID(), item->getType(), + item->getInventoryType(), + item->getName(), item->getDescription(), + item->getSaleInfo(), + item->getFlags(), + item->getCreationDate()); + task_item->setTransactionID(item->getTransactionID()); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_UpdateTaskInventory); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_UpdateData); + msg->addU32Fast(_PREHASH_LocalID, mLocalID); + msg->addU8Fast(_PREHASH_Key, key); + msg->nextBlockFast(_PREHASH_InventoryData); + task_item->packMessage(msg); + msg->sendReliable(mRegionp->getHost()); + + // do the internal logic + doUpdateInventory(task_item, key, is_new); } void LLViewerObject::updateInventoryLocal(LLInventoryItem* item, U8 key) { - LLPointer task_item = - new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), - item->getAssetUUID(), item->getType(), - item->getInventoryType(), - item->getName(), item->getDescription(), - item->getSaleInfo(), item->getFlags(), - item->getCreationDate()); + LLPointer task_item = + new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), + item->getAssetUUID(), item->getType(), + item->getInventoryType(), + item->getName(), item->getDescription(), + item->getSaleInfo(), item->getFlags(), + item->getCreationDate()); - // do the internal logic - const bool is_new = false; - doUpdateInventory(task_item, key, is_new); + // do the internal logic + const bool is_new = false; + doUpdateInventory(task_item, key, is_new); } LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id) { - LLInventoryObject* rv = NULL; - if(mInventory) - { - LLInventoryObject::object_list_t::iterator it = mInventory->begin(); - LLInventoryObject::object_list_t::iterator end = mInventory->end(); - for ( ; it != end; ++it) - { - if((*it)->getUUID() == item_id) - { - rv = *it; - break; - } - } - } - return rv; + LLInventoryObject* rv = NULL; + if(mInventory) + { + LLInventoryObject::object_list_t::iterator it = mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = mInventory->end(); + for ( ; it != end; ++it) + { + if((*it)->getUUID() == item_id) + { + rv = *it; + break; + } + } + } + return rv; } LLInventoryItem* LLViewerObject::getInventoryItem(const LLUUID& item_id) { - LLInventoryObject* iobj = getInventoryObject(item_id); - if (!iobj || iobj->getType() == LLAssetType::AT_CATEGORY) - { - return NULL; - } - LLInventoryItem* item = dynamic_cast(iobj); - return item; + LLInventoryObject* iobj = getInventoryObject(item_id); + if (!iobj || iobj->getType() == LLAssetType::AT_CATEGORY) + { + return NULL; + } + LLInventoryItem* item = dynamic_cast(iobj); + return item; } void LLViewerObject::getInventoryContents(LLInventoryObject::object_list_t& objects) { - if(mInventory) - { - LLInventoryObject::object_list_t::iterator it = mInventory->begin(); - LLInventoryObject::object_list_t::iterator end = mInventory->end(); - for( ; it != end; ++it) - { - if ((*it)->getType() != LLAssetType::AT_CATEGORY) - { - objects.push_back(*it); - } - } - } + if(mInventory) + { + LLInventoryObject::object_list_t::iterator it = mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = mInventory->end(); + for( ; it != end; ++it) + { + if ((*it)->getType() != LLAssetType::AT_CATEGORY) + { + objects.push_back(*it); + } + } + } } LLInventoryObject* LLViewerObject::getInventoryRoot() { - if (!mInventory || !mInventory->size()) - { - return NULL; - } - return mInventory->back(); + if (!mInventory || !mInventory->size()) + { + return NULL; + } + return mInventory->back(); } LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id) { - if (mInventoryDirty) - LL_WARNS() << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << LL_ENDL; - - LLViewerInventoryItem* rv = NULL; - if(mInventory) - { - LLViewerInventoryItem* item = NULL; - - LLInventoryObject::object_list_t::iterator it = mInventory->begin(); - LLInventoryObject::object_list_t::iterator end = mInventory->end(); - for( ; it != end; ++it) - { - LLInventoryObject* obj = *it; - if(obj->getType() != LLAssetType::AT_CATEGORY) - { - // *FIX: gank-ass down cast! - item = (LLViewerInventoryItem*)obj; - if(item->getAssetUUID() == asset_id) - { - rv = item; - break; - } - } - } - } - return rv; + if (mInventoryDirty) + LL_WARNS() << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << LL_ENDL; + + LLViewerInventoryItem* rv = NULL; + if(mInventory) + { + LLViewerInventoryItem* item = NULL; + + LLInventoryObject::object_list_t::iterator it = mInventory->begin(); + LLInventoryObject::object_list_t::iterator end = mInventory->end(); + for( ; it != end; ++it) + { + LLInventoryObject* obj = *it; + if(obj->getType() != LLAssetType::AT_CATEGORY) + { + // *FIX: gank-ass down cast! + item = (LLViewerInventoryItem*)obj; + if(item->getAssetUUID() == asset_id) + { + rv = item; + break; + } + } + } + } + return rv; } LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type) @@ -3736,70 +3736,70 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass } void LLViewerObject::updateViewerInventoryAsset( - const LLViewerInventoryItem* item, - const LLUUID& new_asset) + const LLViewerInventoryItem* item, + const LLUUID& new_asset) { - LLPointer task_item = - new LLViewerInventoryItem(item); - task_item->setAssetUUID(new_asset); + LLPointer task_item = + new LLViewerInventoryItem(item); + task_item->setAssetUUID(new_asset); - // do the internal logic - doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false); + // do the internal logic + doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false); } void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent) { - if (getVolume()) - { //volumes calculate pixel area and angle per face - return; - } - - LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); - LLVector3 pos_agent = getRenderPosition(); - - F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX]; - F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY]; - F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ]; - - F32 max_scale = getMaxScale(); - F32 mid_scale = getMidScale(); - F32 min_scale = getMinScale(); - - // IW: estimate - when close to large objects, computing range based on distance from center is no good - // to try to get a min distance from face, subtract min_scale/2 from the range. - // This means we'll load too much detail sometimes, but that's better than not enough - // I don't think there's a better way to do this without calculating distance per-poly - F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2; - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - if (range < 0.001f || isHUDAttachment()) // range == zero - { - mAppAngle = 180.f; - mPixelArea = (F32)camera->getScreenPixelArea(); - } - else - { - mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; - - F32 pixels_per_meter = camera->getPixelMeterRatio() / range; - - mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale); - if (mPixelArea > camera->getScreenPixelArea()) - { - mAppAngle = 180.f; - mPixelArea = (F32)camera->getScreenPixelArea(); - } - } + if (getVolume()) + { //volumes calculate pixel area and angle per face + return; + } + + LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); + LLVector3 pos_agent = getRenderPosition(); + + F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX]; + F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY]; + F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ]; + + F32 max_scale = getMaxScale(); + F32 mid_scale = getMidScale(); + F32 min_scale = getMinScale(); + + // IW: estimate - when close to large objects, computing range based on distance from center is no good + // to try to get a min distance from face, subtract min_scale/2 from the range. + // This means we'll load too much detail sometimes, but that's better than not enough + // I don't think there's a better way to do this without calculating distance per-poly + F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2; + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + if (range < 0.001f || isHUDAttachment()) // range == zero + { + mAppAngle = 180.f; + mPixelArea = (F32)camera->getScreenPixelArea(); + } + else + { + mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; + + F32 pixels_per_meter = camera->getPixelMeterRatio() / range; + + mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale); + if (mPixelArea > camera->getScreenPixelArea()) + { + mAppAngle = 180.f; + mPixelArea = (F32)camera->getScreenPixelArea(); + } + } } BOOL LLViewerObject::updateLOD() { - return FALSE; + return FALSE; } BOOL LLViewerObject::updateGeometry(LLDrawable *drawable) { - return TRUE; + return TRUE; } void LLViewerObject::updateGL() @@ -3809,51 +3809,51 @@ void LLViewerObject::updateGL() void LLViewerObject::updateFaceSize(S32 idx) { - + } LLDrawable* LLViewerObject::createDrawable(LLPipeline *pipeline) { - return NULL; + return NULL; } void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) { - LLPrimitive::setScale(scale); - if (mDrawable.notNull()) - { - //encompass completely sheared objects by taking - //the most extreme point possible (<1,1,0.5>) - mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec()); - updateDrawable(damped); - } - - if( (LL_PCODE_VOLUME == getPCode()) && !isDead() ) - { - if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) ) - { - if (!mOnMap) - { - llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle())); - - gObjectList.addToMap(this); - mOnMap = TRUE; - } - } - else - { - if (mOnMap) - { - gObjectList.removeFromMap(this); - mOnMap = FALSE; - } - } - } + LLPrimitive::setScale(scale); + if (mDrawable.notNull()) + { + //encompass completely sheared objects by taking + //the most extreme point possible (<1,1,0.5>) + mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec()); + updateDrawable(damped); + } + + if( (LL_PCODE_VOLUME == getPCode()) && !isDead() ) + { + if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) ) + { + if (!mOnMap) + { + llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle())); + + gObjectList.addToMap(this); + mOnMap = TRUE; + } + } + else + { + if (mOnMap) + { + gObjectList.removeFromMap(this); + mOnMap = FALSE; + } + } + } } void LLViewerObject::setObjectCostStale() { - mCostStale = true; + mCostStale = true; // *NOTE: This is harmlessly redundant for Blinn-Phong material updates, as // the root prim currently gets set stale anyway due to other property // updates. But it is needed for GLTF material ID updates. @@ -3863,96 +3863,96 @@ void LLViewerObject::setObjectCostStale() void LLViewerObject::setObjectCost(F32 cost) { - mObjectCost = cost; - mCostStale = false; + mObjectCost = cost; + mCostStale = false; - if (isSelected()) - { - gFloaterTools->dirty(); - } + if (isSelected()) + { + gFloaterTools->dirty(); + } } void LLViewerObject::setLinksetCost(F32 cost) { - mLinksetCost = cost; - mCostStale = false; + mLinksetCost = cost; + mCostStale = false; - BOOL needs_refresh = isSelected(); - child_list_t::iterator iter = mChildList.begin(); - while(iter != mChildList.end() && !needs_refresh) - { - LLViewerObject* child = *iter; - needs_refresh = child->isSelected(); - iter++; - } + BOOL needs_refresh = isSelected(); + child_list_t::iterator iter = mChildList.begin(); + while(iter != mChildList.end() && !needs_refresh) + { + LLViewerObject* child = *iter; + needs_refresh = child->isSelected(); + iter++; + } - if (needs_refresh) - { - gFloaterTools->dirty(); - } + if (needs_refresh) + { + gFloaterTools->dirty(); + } } void LLViewerObject::setPhysicsCost(F32 cost) { - mPhysicsCost = cost; - mCostStale = false; + mPhysicsCost = cost; + mCostStale = false; - if (isSelected()) - { - gFloaterTools->dirty(); - } + if (isSelected()) + { + gFloaterTools->dirty(); + } } void LLViewerObject::setLinksetPhysicsCost(F32 cost) { - mLinksetPhysicsCost = cost; - mCostStale = false; - - if (isSelected()) - { - gFloaterTools->dirty(); - } + mLinksetPhysicsCost = cost; + mCostStale = false; + + if (isSelected()) + { + gFloaterTools->dirty(); + } } F32 LLViewerObject::getObjectCost() { - if (mCostStale) - { - gObjectList.updateObjectCost(this); - } - - return mObjectCost; + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mObjectCost; } F32 LLViewerObject::getLinksetCost() { - if (mCostStale) - { - gObjectList.updateObjectCost(this); - } + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } - return mLinksetCost; + return mLinksetCost; } F32 LLViewerObject::getPhysicsCost() { - if (mCostStale) - { - gObjectList.updateObjectCost(this); - } - - return mPhysicsCost; + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mPhysicsCost; } F32 LLViewerObject::getLinksetPhysicsCost() { - if (mCostStale) - { - gObjectList.updateObjectCost(this); - } + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } - return mLinksetPhysicsCost; + return mLinksetPhysicsCost; } F32 LLViewerObject::recursiveGetEstTrianglesMax() const @@ -3973,7 +3973,7 @@ F32 LLViewerObject::recursiveGetEstTrianglesMax() const S32 LLViewerObject::getAnimatedObjectMaxTris() const { S32 max_tris = 0; - if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) + if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) { max_tris = S32_MAX; } @@ -4005,7 +4005,7 @@ F32 LLViewerObject::getEstTrianglesStreamingCost() const // virtual F32 LLViewerObject::getStreamingCost() const { - return 0.f; + return 0.f; } // virtual @@ -4017,12 +4017,12 @@ bool LLViewerObject::getCostData(LLMeshCostData& costs) const U32 LLViewerObject::getTriangleCount(S32* vcount) const { - return 0; + return 0; } U32 LLViewerObject::getHighLODTriangleCount() { - return 0; + return 0; } U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const @@ -4057,7 +4057,7 @@ F32 LLViewerObject::recursiveGetScaledSurfaceArea() const { if (volume->getVolume()) { - const LLVector3& scale = volume->getScale(); + const LLVector3& scale = volume->getScale(); area += volume->getVolume()->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); } LLViewerObject::const_child_list_t children = volume->getChildren(); @@ -4080,68 +4080,68 @@ F32 LLViewerObject::recursiveGetScaledSurfaceArea() const void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { - LLVector4a center; - center.load3(getRenderPosition().mV); - LLVector4a size; - size.load3(getScale().mV); - newMin.setSub(center, size); - newMax.setAdd(center, size); - - mDrawable->setPositionGroup(center); + LLVector4a center; + center.load3(getRenderPosition().mV); + LLVector4a size; + size.load3(getScale().mV); + newMin.setSub(center, size); + newMax.setAdd(center, size); + + mDrawable->setPositionGroup(center); } F32 LLViewerObject::getBinRadius() { - if (mDrawable.notNull()) - { - const LLVector4a* ext = mDrawable->getSpatialExtents(); - LLVector4a diff; - diff.setSub(ext[1], ext[0]); - return diff.getLength3().getF32(); - } - - return getScale().magVec(); + if (mDrawable.notNull()) + { + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a diff; + diff.setSub(ext[1], ext[0]); + return diff.getLength3().getF32(); + } + + return getScale().magVec(); } F32 LLViewerObject::getMaxScale() const { - return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]); + return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]); } F32 LLViewerObject::getMinScale() const { - return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]); + return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]); } F32 LLViewerObject::getMidScale() const { - if (getScale().mV[VX] < getScale().mV[VY]) - { - if (getScale().mV[VY] < getScale().mV[VZ]) - { - return getScale().mV[VY]; - } - else if (getScale().mV[VX] < getScale().mV[VZ]) - { - return getScale().mV[VZ]; - } - else - { - return getScale().mV[VX]; - } - } - else if (getScale().mV[VX] < getScale().mV[VZ]) - { - return getScale().mV[VX]; - } - else if (getScale().mV[VY] < getScale().mV[VZ]) - { - return getScale().mV[VZ]; - } - else - { - return getScale().mV[VY]; - } + if (getScale().mV[VX] < getScale().mV[VY]) + { + if (getScale().mV[VY] < getScale().mV[VZ]) + { + return getScale().mV[VY]; + } + else if (getScale().mV[VX] < getScale().mV[VZ]) + { + return getScale().mV[VZ]; + } + else + { + return getScale().mV[VX]; + } + } + else if (getScale().mV[VX] < getScale().mV[VZ]) + { + return getScale().mV[VX]; + } + else if (getScale().mV[VY] < getScale().mV[VZ]) + { + return getScale().mV[VZ]; + } + else + { + return getScale().mV[VY]; + } } @@ -4151,68 +4151,68 @@ void LLViewerObject::updateTextures() void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) { - if (isDead() || !getVolume()) - { - return; - } - - S32 i; - S32 tex_count = getNumTEs(); - for (i = 0; i < tex_count; i++) - { - getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED); - } - - if (isSculpted() && !isMesh()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); - } - - if (boost_children) - { - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - child->boostTexturePriority(); - } - } + if (isDead() || !getVolume()) + { + return; + } + + S32 i; + S32 tex_count = getNumTEs(); + for (i = 0; i < tex_count; i++) + { + getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + } + + if (isSculpted() && !isMesh()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID sculpt_id = sculpt_params->getSculptTexture(); + LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + } + + if (boost_children) + { + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + child->boostTexturePriority(); + } + } } void LLViewerObject::setLineWidthForWindowSize(S32 window_width) { - if (window_width < 700) - { - LLUI::setLineWidth(2.0f); - } - else if (window_width < 1100) - { - LLUI::setLineWidth(3.0f); - } - else if (window_width < 2000) - { - LLUI::setLineWidth(4.0f); - } - else - { - // _damn_, what a nice monitor! - LLUI::setLineWidth(5.0f); - } + if (window_width < 700) + { + LLUI::setLineWidth(2.0f); + } + else if (window_width < 1100) + { + LLUI::setLineWidth(3.0f); + } + else if (window_width < 2000) + { + LLUI::setLineWidth(4.0f); + } + else + { + // _damn_, what a nice monitor! + LLUI::setLineWidth(5.0f); + } } void LLViewerObject::increaseArrowLength() { /* ??? - if (mAxisArrowLength == 50) - { - mAxisArrowLength = 100; - } - else - { - mAxisArrowLength = 150; - } + if (mAxisArrowLength == 50) + { + mAxisArrowLength = 100; + } + else + { + mAxisArrowLength = 150; + } */ } @@ -4220,158 +4220,158 @@ void LLViewerObject::increaseArrowLength() void LLViewerObject::decreaseArrowLength() { /* ??? - if (mAxisArrowLength == 150) - { - mAxisArrowLength = 100; - } - else - { - mAxisArrowLength = 50; - } + if (mAxisArrowLength == 150) + { + mAxisArrowLength = 100; + } + else + { + mAxisArrowLength = 50; + } */ } // Culled from newsim LLTask::addNVPair void LLViewerObject::addNVPair(const std::string& data) { - // cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl; - LLNameValue *nv = new LLNameValue(data.c_str()); - -// char splat[MAX_STRING]; -// temp->printNameValue(splat); -// LL_INFOS() << "addNVPair " << splat << LL_ENDL; - - name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName); - if (iter != mNameValuePairs.end()) - { - LLNameValue* foundnv = iter->second; - if (foundnv->mClass != NVC_READ_ONLY) - { - delete foundnv; - mNameValuePairs.erase(iter); - } - else - { - delete nv; -// LL_INFOS() << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << LL_ENDL; - return; - } - } - mNameValuePairs[nv->mName] = nv; + // cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl; + LLNameValue *nv = new LLNameValue(data.c_str()); + +// char splat[MAX_STRING]; +// temp->printNameValue(splat); +// LL_INFOS() << "addNVPair " << splat << LL_ENDL; + + name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName); + if (iter != mNameValuePairs.end()) + { + LLNameValue* foundnv = iter->second; + if (foundnv->mClass != NVC_READ_ONLY) + { + delete foundnv; + mNameValuePairs.erase(iter); + } + else + { + delete nv; +// LL_INFOS() << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << LL_ENDL; + return; + } + } + mNameValuePairs[nv->mName] = nv; } BOOL LLViewerObject::removeNVPair(const std::string& name) { - char* canonical_name = gNVNameTable.addString(name); + char* canonical_name = gNVNameTable.addString(name); - LL_DEBUGS() << "LLViewerObject::removeNVPair(): " << name << LL_ENDL; + LL_DEBUGS() << "LLViewerObject::removeNVPair(): " << name << LL_ENDL; - name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name); - if (iter != mNameValuePairs.end()) - { - if( mRegionp ) - { - LLNameValue* nv = iter->second; + name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name); + if (iter != mNameValuePairs.end()) + { + if( mRegionp ) + { + LLNameValue* nv = iter->second; /* - std::string buffer = nv->printNameValue(); - gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair); - gMessageSystem->nextBlockFast(_PREHASH_TaskData); - gMessageSystem->addUUIDFast(_PREHASH_ID, mID); - - gMessageSystem->nextBlockFast(_PREHASH_NameValueData); - gMessageSystem->addStringFast(_PREHASH_NVPair, buffer); - - gMessageSystem->sendReliable( mRegionp->getHost() ); + std::string buffer = nv->printNameValue(); + gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair); + gMessageSystem->nextBlockFast(_PREHASH_TaskData); + gMessageSystem->addUUIDFast(_PREHASH_ID, mID); + + gMessageSystem->nextBlockFast(_PREHASH_NameValueData); + gMessageSystem->addStringFast(_PREHASH_NVPair, buffer); + + gMessageSystem->sendReliable( mRegionp->getHost() ); */ - // Remove the NV pair from the local list. - delete nv; - mNameValuePairs.erase(iter); - return TRUE; - } - else - { - LL_DEBUGS() << "removeNVPair - No region for object" << LL_ENDL; - } - } - return FALSE; + // Remove the NV pair from the local list. + delete nv; + mNameValuePairs.erase(iter); + return TRUE; + } + else + { + LL_DEBUGS() << "removeNVPair - No region for object" << LL_ENDL; + } + } + return FALSE; } LLNameValue *LLViewerObject::getNVPair(const std::string& name) const { - char *canonical_name; + char *canonical_name; - canonical_name = gNVNameTable.addString(name); + canonical_name = gNVNameTable.addString(name); - // If you access a map with a name that isn't in it, it will add the name and a null pointer. - // So first check if the data is in the map. - name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name); - if (iter != mNameValuePairs.end()) - { - return iter->second; - } - else - { - return NULL; - } + // If you access a map with a name that isn't in it, it will add the name and a null pointer. + // So first check if the data is in the map. + name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name); + if (iter != mNameValuePairs.end()) + { + return iter->second; + } + else + { + return NULL; + } } void LLViewerObject::updatePositionCaches() const { - // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) - { - if (!isRoot()) - { - mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation(); - mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); - } - else - { - mPositionRegion = getPosition(); - mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); - } - } + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) + { + if (!isRoot()) + { + mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation(); + mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); + } + else + { + mPositionRegion = getPosition(); + mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); + } + } } const LLVector3d LLViewerObject::getPositionGlobal() const -{ - // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) - { - LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); - - if (isAttachment()) - { - position_global = gAgent.getPosGlobalFromAgent(getRenderPosition()); - } - return position_global; - } - else - { - LLVector3d position_global(getPosition()); - return position_global; - } +{ + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) + { + LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); + + if (isAttachment()) + { + position_global = gAgent.getPosGlobalFromAgent(getRenderPosition()); + } + return position_global; + } + else + { + LLVector3d position_global(getPosition()); + return position_global; + } } const LLVector3 &LLViewerObject::getPositionAgent() const { - // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) - { - if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent())) - { - // Don't return cached position if you have a parent, recalc (until all dirtying is done correctly. - LLVector3 position_region; - position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation(); - mPositionAgent = mRegionp->getPosAgentFromRegion(position_region); - } - else - { - mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition()); - } - } - return mPositionAgent; + // If region is removed from the list it is also deleted. + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) + { + if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent())) + { + // Don't return cached position if you have a parent, recalc (until all dirtying is done correctly. + LLVector3 position_region; + position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation(); + mPositionAgent = mRegionp->getPosAgentFromRegion(position_region); + } + else + { + mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition()); + } + } + return mPositionAgent; } LLMatrix4a LLViewerObject::getGLTFAssetToAgentTransform() const @@ -4517,7 +4517,7 @@ void LLViewerObject::moveGLTFNode(S32 node_index, const LLVector3& offset) LLVector4a origin = LLVector4a::getZero(); LLVector4a offset_v; offset_v.load3(offset.mV); - + agent_to_node.affineTransform(offset_v, offset_v); agent_to_node.affineTransform(origin, origin); @@ -4538,37 +4538,37 @@ void LLViewerObject::moveGLTFNode(S32 node_index, const LLVector3& offset) const LLVector3 &LLViewerObject::getPositionRegion() const { - if (!isRoot()) - { - LLViewerObject *parent = (LLViewerObject *)getParent(); - mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation()); - } - else - { - mPositionRegion = getPosition(); - } + if (!isRoot()) + { + LLViewerObject *parent = (LLViewerObject *)getParent(); + mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation()); + } + else + { + mPositionRegion = getPosition(); + } - return mPositionRegion; + return mPositionRegion; } const LLVector3 LLViewerObject::getPositionEdit() const { - if (isRootEdit()) - { - return getPosition(); - } - else - { - LLViewerObject *parent = (LLViewerObject *)getParent(); - LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit(); - return position_edit; - } + if (isRootEdit()) + { + return getPosition(); + } + else + { + LLViewerObject *parent = (LLViewerObject *)getParent(); + LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit(); + return position_edit; + } } const LLVector3 LLViewerObject::getRenderPosition() const { - if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) - { + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) + { LLControlAvatar *cav = getControlAvatar(); if (isRoot() && cav) { @@ -4581,448 +4581,448 @@ const LLVector3 LLViewerObject::getRenderPosition() const return pos; } } - LLVOAvatar* avatar = getAvatar(); - if ((avatar) && !getControlAvatar()) - { - return avatar->getPositionAgent(); - } - } + LLVOAvatar* avatar = getAvatar(); + if ((avatar) && !getControlAvatar()) + { + return avatar->getPositionAgent(); + } + } - if (mDrawable.isNull() || mDrawable->getGeneration() < 0) - { - return getPositionAgent(); - } - else - { - return mDrawable->getPositionAgent(); - } + if (mDrawable.isNull() || mDrawable->getGeneration() < 0) + { + return getPositionAgent(); + } + else + { + return mDrawable->getPositionAgent(); + } } const LLVector3 LLViewerObject::getPivotPositionAgent() const { - return getRenderPosition(); + return getRenderPosition(); } const LLQuaternion LLViewerObject::getRenderRotation() const { - LLQuaternion ret; - if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED) && !isAnimatedObject()) - { - return ret; - } - - if (mDrawable.isNull() || mDrawable->isStatic()) - { - ret = getRotationEdit(); - } - else - { - if (!mDrawable->isRoot()) - { - ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix()); - } - else - { - ret = LLQuaternion(mDrawable->getWorldMatrix()); - } - } - - return ret; + LLQuaternion ret; + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED) && !isAnimatedObject()) + { + return ret; + } + + if (mDrawable.isNull() || mDrawable->isStatic()) + { + ret = getRotationEdit(); + } + else + { + if (!mDrawable->isRoot()) + { + ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix()); + } + else + { + ret = LLQuaternion(mDrawable->getWorldMatrix()); + } + } + + return ret; } const LLMatrix4 LLViewerObject::getRenderMatrix() const { - return mDrawable->getWorldMatrix(); + return mDrawable->getWorldMatrix(); } const LLQuaternion LLViewerObject::getRotationRegion() const { - LLQuaternion global_rotation = getRotation(); - if (!((LLXform *)this)->isRoot()) - { - global_rotation = global_rotation * getParent()->getRotation(); - } - return global_rotation; + LLQuaternion global_rotation = getRotation(); + if (!((LLXform *)this)->isRoot()) + { + global_rotation = global_rotation * getParent()->getRotation(); + } + return global_rotation; } const LLQuaternion LLViewerObject::getRotationEdit() const { - LLQuaternion global_rotation = getRotation(); - if (!((LLXform *)this)->isRootEdit()) - { - global_rotation = global_rotation * getParent()->getRotation(); - } - return global_rotation; + LLQuaternion global_rotation = getRotation(); + if (!((LLXform *)this)->isRootEdit()) + { + global_rotation = global_rotation * getParent()->getRotation(); + } + return global_rotation; } void LLViewerObject::setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped ) { - if (isAttachment()) - { - LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global); - if (isRootEdit()) - { - new_pos -= mDrawable->mXform.getParent()->getWorldPosition(); - LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation(); - new_pos = new_pos * ~world_rotation; - } - else - { - LLViewerObject* parentp = (LLViewerObject*)getParent(); - new_pos -= parentp->getPositionAgent(); - new_pos = new_pos * ~parentp->getRotationRegion(); - } - LLViewerObject::setPosition(new_pos); - - if (mParent && ((LLViewerObject*)mParent)->isAvatar()) - { - // we have changed the position of an attachment, so we need to clamp it - LLVOAvatar *avatar = (LLVOAvatar*)mParent; - - avatar->clampAttachmentPositions(); - } - } - else - { - if( isRoot() ) - { - setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global)); - } - else - { - // the relative position with the parent is not constant - LLViewerObject* parent = (LLViewerObject *)getParent(); - //RN: this assumes we are only calling this function from the edit tools - gPipeline.updateMoveNormalAsync(parent->mDrawable); - - LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion(); - pos_local = pos_local * ~parent->getRotationRegion(); - LLViewerObject::setPosition( pos_local ); - } - } - //RN: assumes we always want to snap the object when calling this function - gPipeline.updateMoveNormalAsync(mDrawable); + if (isAttachment()) + { + LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global); + if (isRootEdit()) + { + new_pos -= mDrawable->mXform.getParent()->getWorldPosition(); + LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation(); + new_pos = new_pos * ~world_rotation; + } + else + { + LLViewerObject* parentp = (LLViewerObject*)getParent(); + new_pos -= parentp->getPositionAgent(); + new_pos = new_pos * ~parentp->getRotationRegion(); + } + LLViewerObject::setPosition(new_pos); + + if (mParent && ((LLViewerObject*)mParent)->isAvatar()) + { + // we have changed the position of an attachment, so we need to clamp it + LLVOAvatar *avatar = (LLVOAvatar*)mParent; + + avatar->clampAttachmentPositions(); + } + } + else + { + if( isRoot() ) + { + setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global)); + } + else + { + // the relative position with the parent is not constant + LLViewerObject* parent = (LLViewerObject *)getParent(); + //RN: this assumes we are only calling this function from the edit tools + gPipeline.updateMoveNormalAsync(parent->mDrawable); + + LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion(); + pos_local = pos_local * ~parent->getRotationRegion(); + LLViewerObject::setPosition( pos_local ); + } + } + //RN: assumes we always want to snap the object when calling this function + gPipeline.updateMoveNormalAsync(mDrawable); } void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped) { - if (getPosition() != pos) - { - setChanged(TRANSLATED | SILHOUETTE); - } - - LLXform::setPosition(pos); - updateDrawable(damped); - if (isRoot()) - { - // position caches need to be up to date on root objects - updatePositionCaches(); - } + if (getPosition() != pos) + { + setChanged(TRANSLATED | SILHOUETTE); + } + + LLXform::setPosition(pos); + updateDrawable(damped); + if (isRoot()) + { + // position caches need to be up to date on root objects + updatePositionCaches(); + } } void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped) { - if (isAttachment()) - { - if (isRootEdit()) - { - LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global); - newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition(); - - LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation(); - invWorldRotation.transQuat(); - - newPos = newPos * invWorldRotation; - LLViewerObject::setPosition(newPos); - } - else - { - // assumes parent is root editable (root of attachment) - LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global); - newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition(); - LLVector3 delta_pos = newPos - getPosition(); - - LLQuaternion invRotation = mDrawable->getRotation(); - invRotation.transQuat(); - - delta_pos = delta_pos * invRotation; - - // *FIX: is this right? Shouldn't we be calling the - // LLViewerObject version of setPosition? - LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition(); - mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos); - setChanged(TRANSLATED | SILHOUETTE); - } - if (mParent && ((LLViewerObject*)mParent)->isAvatar()) - { - // we have changed the position of an attachment, so we need to clamp it - LLVOAvatar *avatar = (LLVOAvatar*)mParent; - - avatar->clampAttachmentPositions(); - } - } - else - { - if (isRoot()) - { - setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global)); - } - else - { - // the relative position with the parent is constant, but the parent's position needs to be changed - LLVector3d position_offset; - position_offset.setVec(getPosition()*getParent()->getRotation()); - LLVector3d new_pos_global = pos_global - position_offset; - ((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global); - } - } - updateDrawable(damped); + if (isAttachment()) + { + if (isRootEdit()) + { + LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global); + newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition(); + + LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation(); + invWorldRotation.transQuat(); + + newPos = newPos * invWorldRotation; + LLViewerObject::setPosition(newPos); + } + else + { + // assumes parent is root editable (root of attachment) + LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global); + newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition(); + LLVector3 delta_pos = newPos - getPosition(); + + LLQuaternion invRotation = mDrawable->getRotation(); + invRotation.transQuat(); + + delta_pos = delta_pos * invRotation; + + // *FIX: is this right? Shouldn't we be calling the + // LLViewerObject version of setPosition? + LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition(); + mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos); + setChanged(TRANSLATED | SILHOUETTE); + } + if (mParent && ((LLViewerObject*)mParent)->isAvatar()) + { + // we have changed the position of an attachment, so we need to clamp it + LLVOAvatar *avatar = (LLVOAvatar*)mParent; + + avatar->clampAttachmentPositions(); + } + } + else + { + if (isRoot()) + { + setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global)); + } + else + { + // the relative position with the parent is constant, but the parent's position needs to be changed + LLVector3d position_offset; + position_offset.setVec(getPosition()*getParent()->getRotation()); + LLVector3d new_pos_global = pos_global - position_offset; + ((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global); + } + } + updateDrawable(damped); } void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped) { - // Set position relative to parent, if no parent, relative to region - if (!isRoot()) - { - LLViewerObject::setPosition(pos_parent, damped); - //updateDrawable(damped); - } - else - { - setPositionRegion(pos_parent, damped); - } + // Set position relative to parent, if no parent, relative to region + if (!isRoot()) + { + LLViewerObject::setPosition(pos_parent, damped); + //updateDrawable(damped); + } + else + { + setPositionRegion(pos_parent, damped); + } } void LLViewerObject::setPositionRegion(const LLVector3 &pos_region, BOOL damped) { - if (!isRootEdit()) - { - LLViewerObject* parent = (LLViewerObject*) getParent(); - LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion()); - } - else - { - LLViewerObject::setPosition(pos_region); - mPositionRegion = pos_region; - mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); - } + if (!isRootEdit()) + { + LLViewerObject* parent = (LLViewerObject*) getParent(); + LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion()); + } + else + { + LLViewerObject::setPosition(pos_region); + mPositionRegion = pos_region; + mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); + } } void LLViewerObject::setPositionAgent(const LLVector3 &pos_agent, BOOL damped) { - LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent); - setPositionRegion(pos_region, damped); + LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent); + setPositionRegion(pos_region, damped); } -// identical to setPositionRegion() except it checks for child-joints +// identical to setPositionRegion() except it checks for child-joints // and doesn't also move the joint-parent // TODO -- implement similar intelligence for joint-parents toward // their joint-children void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped) { - if (!isRootEdit()) - { - // the relative position with the parent is constant, but the parent's position needs to be changed - LLVector3 position_offset = getPosition() * getParent()->getRotation(); + if (!isRootEdit()) + { + // the relative position with the parent is constant, but the parent's position needs to be changed + LLVector3 position_offset = getPosition() * getParent()->getRotation(); - ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset); - updateDrawable(damped); - } - else - { - LLViewerObject::setPosition(pos_edit, damped); - mPositionRegion = pos_edit; - mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); - } + ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset); + updateDrawable(damped); + } + else + { + LLViewerObject::setPosition(pos_edit, damped); + mPositionRegion = pos_edit; + mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); + } } LLViewerObject* LLViewerObject::getRootEdit() const { - const LLViewerObject* root = this; - while (root->mParent - && !((LLViewerObject*)root->mParent)->isAvatar()) - { - root = (LLViewerObject*)root->mParent; - } - return (LLViewerObject*)root; + const LLViewerObject* root = this; + while (root->mParent + && !((LLViewerObject*)root->mParent)->isAvatar()) + { + root = (LLViewerObject*)root->mParent; + } + return (LLViewerObject*)root; } BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face, - BOOL pick_transparent, - BOOL pick_rigged, + S32 face, + BOOL pick_transparent, + BOOL pick_rigged, BOOL pick_unselectable, - S32* face_hit, - LLVector4a* intersection, - LLVector2* tex_coord, - LLVector4a* normal, - LLVector4a* tangent) + S32* face_hit, + LLVector4a* intersection, + LLVector2* tex_coord, + LLVector4a* normal, + LLVector4a* tangent) { - return false; + return false; } BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end) { - if (mDrawable.isNull() || mDrawable->isDead()) - { - return FALSE; - } + if (mDrawable.isNull() || mDrawable->isDead()) + { + return FALSE; + } - const LLVector4a* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); - //VECTORIZE THIS - LLVector4a center; - center.setAdd(ext[1], ext[0]); - center.mul(0.5f); - LLVector4a size; - size.setSub(ext[1], ext[0]); - size.mul(0.5f); + //VECTORIZE THIS + LLVector4a center; + center.setAdd(ext[1], ext[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); - return LLLineSegmentBoxIntersect(start, end, center, size); + return LLLineSegmentBoxIntersect(start, end, center, size); } U8 LLViewerObject::getMediaType() const { - if (mMedia) - { - return mMedia->mMediaType; - } - else - { - return LLViewerObject::MEDIA_NONE; - } + if (mMedia) + { + return mMedia->mMediaType; + } + else + { + return LLViewerObject::MEDIA_NONE; + } } void LLViewerObject::setMediaType(U8 media_type) { - if (!mMedia) - { - // TODO what if we don't have a media pointer? - } - else if (mMedia->mMediaType != media_type) - { - mMedia->mMediaType = media_type; + if (!mMedia) + { + // TODO what if we don't have a media pointer? + } + else if (mMedia->mMediaType != media_type) + { + mMedia->mMediaType = media_type; - // TODO: update materials with new image - } + // TODO: update materials with new image + } } std::string LLViewerObject::getMediaURL() const { - if (mMedia) - { - return mMedia->mMediaURL; - } - else - { - return std::string(); - } + if (mMedia) + { + return mMedia->mMediaURL; + } + else + { + return std::string(); + } } void LLViewerObject::setMediaURL(const std::string& media_url) { - if (!mMedia) - { - mMedia = new LLViewerObjectMedia; - mMedia->mMediaURL = media_url; - mMedia->mPassedWhitelist = FALSE; + if (!mMedia) + { + mMedia = new LLViewerObjectMedia; + mMedia->mMediaURL = media_url; + mMedia->mPassedWhitelist = FALSE; - // TODO: update materials with new image - } - else if (mMedia->mMediaURL != media_url) - { - mMedia->mMediaURL = media_url; - mMedia->mPassedWhitelist = FALSE; + // TODO: update materials with new image + } + else if (mMedia->mMediaURL != media_url) + { + mMedia->mMediaURL = media_url; + mMedia->mPassedWhitelist = FALSE; - // TODO: update materials with new image - } + // TODO: update materials with new image + } } BOOL LLViewerObject::getMediaPassedWhitelist() const { - if (mMedia) - { - return mMedia->mPassedWhitelist; - } - else - { - return FALSE; - } + if (mMedia) + { + return mMedia->mPassedWhitelist; + } + else + { + return FALSE; + } } void LLViewerObject::setMediaPassedWhitelist(BOOL passed) { - if (mMedia) - { - mMedia->mPassedWhitelist = passed; - } + if (mMedia) + { + mMedia->mPassedWhitelist = passed; + } } BOOL LLViewerObject::setMaterial(const U8 material) { - BOOL res = LLPrimitive::setMaterial(material); - if (res) - { - setChanged(TEXTURE); - } - return res; + BOOL res = LLPrimitive::setMaterial(material); + if (res) + { + setChanged(TEXTURE); + } + return res; } void LLViewerObject::setNumTEs(const U8 num_tes) { - U32 i; - if (num_tes != getNumTEs()) - { - if (num_tes) - { - LLPointer *new_images; - new_images = new LLPointer[num_tes]; - - LLPointer *new_normmaps; - new_normmaps = new LLPointer[num_tes]; - - LLPointer *new_specmaps; - new_specmaps = new LLPointer[num_tes]; - for (i = 0; i < num_tes; i++) - { - if (i < getNumTEs()) - { - new_images[i] = mTEImages[i]; - new_normmaps[i] = mTENormalMaps[i]; - new_specmaps[i] = mTESpecularMaps[i]; - } - else if (getNumTEs()) - { - new_images[i] = mTEImages[getNumTEs()-1]; - new_normmaps[i] = mTENormalMaps[getNumTEs()-1]; - new_specmaps[i] = mTESpecularMaps[getNumTEs()-1]; - } - else - { - new_images[i] = NULL; - new_normmaps[i] = NULL; - new_specmaps[i] = NULL; - } - } - - deleteTEImages(); - - mTEImages = new_images; - mTENormalMaps = new_normmaps; - mTESpecularMaps = new_specmaps; - } - else - { - deleteTEImages(); - } + U32 i; + if (num_tes != getNumTEs()) + { + if (num_tes) + { + LLPointer *new_images; + new_images = new LLPointer[num_tes]; + + LLPointer *new_normmaps; + new_normmaps = new LLPointer[num_tes]; + + LLPointer *new_specmaps; + new_specmaps = new LLPointer[num_tes]; + for (i = 0; i < num_tes; i++) + { + if (i < getNumTEs()) + { + new_images[i] = mTEImages[i]; + new_normmaps[i] = mTENormalMaps[i]; + new_specmaps[i] = mTESpecularMaps[i]; + } + else if (getNumTEs()) + { + new_images[i] = mTEImages[getNumTEs()-1]; + new_normmaps[i] = mTENormalMaps[getNumTEs()-1]; + new_specmaps[i] = mTESpecularMaps[getNumTEs()-1]; + } + else + { + new_images[i] = NULL; + new_normmaps[i] = NULL; + new_specmaps[i] = NULL; + } + } + + deleteTEImages(); + + mTEImages = new_images; + mTENormalMaps = new_normmaps; + mTESpecularMaps = new_specmaps; + } + else + { + deleteTEImages(); + } S32 original_tes = getNumTEs(); - LLPrimitive::setNumTEs(num_tes); - setChanged(TEXTURE); + LLPrimitive::setNumTEs(num_tes); + setChanged(TEXTURE); // touch up GLTF materials if (original_tes > 0) @@ -5050,124 +5050,124 @@ void LLViewerObject::setNumTEs(const U8 num_tes) } } - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } - } + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } } void LLViewerObject::sendMaterialUpdate() const { - LLViewerRegion* regionp = getRegion(); - if(!regionp) return; - gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); - gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() ); - gMessageSystem->sendReliable( regionp->getHost() ); + LLViewerRegion* regionp = getRegion(); + if(!regionp) return; + gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); + gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() ); + gMessageSystem->sendReliable( regionp->getHost() ); } //formerly send_object_shape(LLViewerObject *object) void LLViewerObject::sendShapeUpdate() { - gMessageSystem->newMessageFast(_PREHASH_ObjectShape); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); + gMessageSystem->newMessageFast(_PREHASH_ObjectShape); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); - LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem); + LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem); - LLViewerRegion *regionp = getRegion(); - gMessageSystem->sendReliable( regionp->getHost() ); + LLViewerRegion *regionp = getRegion(); + gMessageSystem->sendReliable( regionp->getHost() ); } void LLViewerObject::sendTEUpdate() const { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectImage); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ObjectImage); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); - if (mMedia) - { - msg->addString("MediaURL", mMedia->mMediaURL); - } - else - { - msg->addString("MediaURL", NULL); - } + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); + if (mMedia) + { + msg->addString("MediaURL", mMedia->mMediaURL); + } + else + { + msg->addString("MediaURL", NULL); + } - // TODO send media type + // TODO send media type - packTEMessage(msg); + packTEMessage(msg); - LLViewerRegion *regionp = getRegion(); - msg->sendReliable( regionp->getHost() ); + LLViewerRegion *regionp = getRegion(); + msg->sendReliable( regionp->getHost() ); } LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id) { - if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) - { - return NULL; - } - - LLViewerObject *root = getRootEdit(); - if (root && root->isAnimatedObject()) - { - return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } - - LLVOAvatar* avatar = getAvatar(); - if (avatar && !isHUDAttachment()) - { - LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id); - LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex); - if (bakedTexture == NULL || bakedTexture->isMissingAsset()) - { - return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } - else - { - return bakedTexture; - } - } - else - { - return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return NULL; + } + + LLViewerObject *root = getRootEdit(); + if (root && root->isAnimatedObject()) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + + LLVOAvatar* avatar = getAvatar(); + if (avatar && !isHUDAttachment()) + { + LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id); + LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex); + if (bakedTexture == NULL || bakedTexture->isMissingAsset()) + { + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + else + { + return bakedTexture; + } + } + else + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } } void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id) { - if (id == old_id) - { - return; - } + if (id == old_id) + { + return; + } - if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) - { - return; - } + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return; + } - LLVOAvatar* avatar = getAvatar(); - if (avatar) - { - avatar->updateMeshVisibility(); - } + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + avatar->updateMeshVisibility(); + } } @@ -5192,14 +5192,14 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry) void LLViewerObject::updateTEMaterialTextures(U8 te) { - if (getTE(te)->getMaterialParams().notNull()) - { - const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); - mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - - const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); - mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } + if (getTE(te)->getMaterialParams().notNull()) + { + const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); + mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); + mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial(); llassert(mat == nullptr || dynamic_cast(getTE(te)->getGLTFRenderMaterial()) != nullptr); @@ -5259,354 +5259,354 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) void LLViewerObject::refreshBakeTexture() { - for (int face_index = 0; face_index < getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = getTE(face_index); - if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) - { - const LLUUID& image_id = tex_entry->getID(); - LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); - changeTEImage(face_index, bakedTexture); - } - } + for (int face_index = 0; face_index < getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = getTE(face_index); + if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) + { + const LLUUID& image_id = tex_entry->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + changeTEImage(face_index, bakedTexture); + } + } } void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { - if (mTEImages[te] != imagep) - { - LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; - - LLPrimitive::setTETexture(te, imagep->getID()); + if (mTEImages[te] != imagep) + { + LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; - LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); - mTEImages[te] = baked_texture ? baked_texture : imagep; - updateAvatarMeshVisibility(imagep->getID(), old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } - } + LLPrimitive::setTETexture(te, imagep->getID()); + + LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); + mTEImages[te] = baked_texture ? baked_texture : imagep; + updateAvatarMeshVisibility(imagep->getID(), old_image_id); + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } } S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image) { - LLUUID old_image_id = getTE(te)->getID(); - const LLUUID& uuid = image ? image->getID() : LLUUID::null; - S32 retval = 0; - if (uuid != getTE(te)->getID() || - uuid == LLUUID::null) - { - retval = LLPrimitive::setTETexture(te, uuid); - LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); - mTEImages[te] = baked_texture ? baked_texture : image; - updateAvatarMeshVisibility(uuid,old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } - } - return retval; + LLUUID old_image_id = getTE(te)->getID(); + const LLUUID& uuid = image ? image->getID() : LLUUID::null; + S32 retval = 0; + if (uuid != getTE(te)->getID() || + uuid == LLUUID::null) + { + retval = LLPrimitive::setTETexture(te, uuid); + LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); + mTEImages[te] = baked_texture ? baked_texture : image; + updateAvatarMeshVisibility(uuid,old_image_id); + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; } S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image) { - S32 retval = TEM_CHANGE_TEXTURE; - const LLUUID& uuid = image ? image->getID() : LLUUID::null; - if (uuid != getTE(te)->getID() || - uuid == LLUUID::null) - { - LLTextureEntry* tep = getTE(te); - LLMaterial* mat = NULL; - if (tep) - { - mat = tep->getMaterialParams(); - } - - if (mat) - { - mat->setNormalID(uuid); - } - } - changeTENormalMap(te,image); - return retval; + S32 retval = TEM_CHANGE_TEXTURE; + const LLUUID& uuid = image ? image->getID() : LLUUID::null; + if (uuid != getTE(te)->getID() || + uuid == LLUUID::null) + { + LLTextureEntry* tep = getTE(te); + LLMaterial* mat = NULL; + if (tep) + { + mat = tep->getMaterialParams(); + } + + if (mat) + { + mat->setNormalID(uuid); + } + } + changeTENormalMap(te,image); + return retval; } S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image) { - S32 retval = TEM_CHANGE_TEXTURE; - const LLUUID& uuid = image ? image->getID() : LLUUID::null; - if (uuid != getTE(te)->getID() || - uuid == LLUUID::null) - { - LLTextureEntry* tep = getTE(te); - LLMaterial* mat = NULL; - if (tep) - { - mat = tep->getMaterialParams(); - } - - if (mat) - { - mat->setSpecularID(uuid); - } - } - changeTESpecularMap(te, image); - return retval; + S32 retval = TEM_CHANGE_TEXTURE; + const LLUUID& uuid = image ? image->getID() : LLUUID::null; + if (uuid != getTE(te)->getID() || + uuid == LLUUID::null) + { + LLTextureEntry* tep = getTE(te); + LLMaterial* mat = NULL; + if (tep) + { + mat = tep->getMaterialParams(); + } + + if (mat) + { + mat->setSpecularID(uuid); + } + } + changeTESpecularMap(te, image); + return retval; } //virtual -void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) +void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) { - if(index < 0 || index >= getNumTEs()) - { - return ; - } - mTEImages[index] = new_image ; + if(index < 0 || index >= getNumTEs()) + { + return ; + } + mTEImages[index] = new_image ; } void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image) { - if(index < 0 || index >= getNumTEs()) - { - return ; - } - mTENormalMaps[index] = new_image ; - refreshMaterials(); + if(index < 0 || index >= getNumTEs()) + { + return ; + } + mTENormalMaps[index] = new_image ; + refreshMaterials(); } void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image) { - if(index < 0 || index >= getNumTEs()) - { - return ; - } - mTESpecularMaps[index] = new_image ; - refreshMaterials(); + if(index < 0 || index >= getNumTEs()) + { + return ; + } + mTESpecularMaps[index] = new_image ; + refreshMaterials(); } S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) { - // Invalid host == get from the agent's sim - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture( - uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); - return setTETextureCore(te, image); + // Invalid host == get from the agent's sim + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture( + uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); + return setTETextureCore(te, image); } S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid) { - LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( - uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); - return setTENormalMapCore(te, image); + LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( + uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); + return setTENormalMapCore(te, image); } S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid) { - LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( - uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); - return setTESpecularMapCore(te, image); + LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( + uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); + return setTESpecularMapCore(te, image); } S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color) { - return setTEColor(te, LLColor4(color)); + return setTEColor(te, LLColor4(color)); } S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (color != tep->getColor()) - { - retval = LLPrimitive::setTEColor(te, color); - if (mDrawable.notNull() && retval) - { - // These should only happen on updates which are not the initial update. - dirtyMesh(); - } - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (color != tep->getColor()) + { + retval = LLPrimitive::setTEColor(te, color); + if (mDrawable.notNull() && retval) + { + // These should only happen on updates which are not the initial update. + dirtyMesh(); + } + } + return retval; } S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (bump != tep->getBumpmap()) - { - retval = LLPrimitive::setTEBumpmap(te, bump); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); - } - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (bump != tep->getBumpmap()) + { + retval = LLPrimitive::setTEBumpmap(te, bump); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + } + } + return retval; } S32 LLViewerObject::setTETexGen(const U8 te, const U8 texgen) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (texgen != tep->getTexGen()) - { - retval = LLPrimitive::setTETexGen(te, texgen); - setChanged(TEXTURE); - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (texgen != tep->getTexGen()) + { + retval = LLPrimitive::setTETexGen(te, texgen); + setChanged(TEXTURE); + } + return retval; } S32 LLViewerObject::setTEMediaTexGen(const U8 te, const U8 media) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (media != tep->getMediaTexGen()) - { - retval = LLPrimitive::setTEMediaTexGen(te, media); - setChanged(TEXTURE); - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (media != tep->getMediaTexGen()) + { + retval = LLPrimitive::setTEMediaTexGen(te, media); + setChanged(TEXTURE); + } + return retval; } S32 LLViewerObject::setTEShiny(const U8 te, const U8 shiny) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (shiny != tep->getShiny()) - { - retval = LLPrimitive::setTEShiny(te, shiny); - setChanged(TEXTURE); - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (shiny != tep->getShiny()) + { + retval = LLPrimitive::setTEShiny(te, shiny); + setChanged(TEXTURE); + } + return retval; } S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (fullbright != tep->getFullbright()) - { - retval = LLPrimitive::setTEFullbright(te, fullbright); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - gPipeline.markTextured(mDrawable); - } - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (fullbright != tep->getFullbright()) + { + retval = LLPrimitive::setTEFullbright(te, fullbright); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; } S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags) { - // this might need work for media type - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (media_flags != tep->getMediaFlags()) - { - retval = LLPrimitive::setTEMediaFlags(te, media_flags); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - gPipeline.markTextured(mDrawable); - } - } - return retval; + // this might need work for media type + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (media_flags != tep->getMediaFlags()) + { + retval = LLPrimitive::setTEMediaFlags(te, media_flags); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + gPipeline.markTextured(mDrawable); + } + } + return retval; } S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (glow != tep->getGlow()) - { - retval = LLPrimitive::setTEGlow(te, glow); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - gPipeline.markTextured(mDrawable); - } - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (glow != tep->getGlow()) + { + retval = LLPrimitive::setTEGlow(te, glow); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; } S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS("Material") << "No texture entry for te " << (S32)te - << ", object " << mID - << ", material " << pMaterialID - << LL_ENDL; - } - //else if (pMaterialID != tep->getMaterialID()) - { - LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te - << ", object " << mID - << ", material " << pMaterialID - << LL_ENDL; - retval = LLPrimitive::setTEMaterialID(te, pMaterialID); - refreshMaterials(); - } - return retval; + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS("Material") << "No texture entry for te " << (S32)te + << ", object " << mID + << ", material " << pMaterialID + << LL_ENDL; + } + //else if (pMaterialID != tep->getMaterialID()) + { + LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te + << ", object " << mID + << ", material " << pMaterialID + << LL_ENDL; + retval = LLPrimitive::setTEMaterialID(te, pMaterialID); + refreshMaterials(); + } + return retval; } S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - return 0; - } + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + return 0; + } - retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); - LL_DEBUGS("Material") << "Changing material params for te " << (S32)te - << ", object " << mID - << " (" << retval << ")" - << LL_ENDL; - setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); - setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); + retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); + LL_DEBUGS("Material") << "Changing material params for te " << (S32)te + << ", object " << mID + << " (" << retval << ")" + << LL_ENDL; + setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); + setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); - return retval; + return retval; } S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat) @@ -5666,287 +5666,287 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma void LLViewerObject::refreshMaterials() { - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } } S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t) { - S32 retval = 0; - retval = LLPrimitive::setTEScale(te, s, t); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } - return retval; + S32 retval = 0; + retval = LLPrimitive::setTEScale(te, s, t); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } + return retval; } S32 LLViewerObject::setTEScaleS(const U8 te, const F32 s) { - S32 retval = LLPrimitive::setTEScaleS(te, s); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } + S32 retval = LLPrimitive::setTEScaleS(te, s); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } - return retval; + return retval; } S32 LLViewerObject::setTEScaleT(const U8 te, const F32 t) { - S32 retval = LLPrimitive::setTEScaleT(te, t); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } + S32 retval = LLPrimitive::setTEScaleT(te, t); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } - return retval; + return retval; } S32 LLViewerObject::setTEOffset(const U8 te, const F32 s, const F32 t) { - S32 retval = LLPrimitive::setTEOffset(te, s, t); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } - return retval; + S32 retval = LLPrimitive::setTEOffset(te, s, t); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } + return retval; } S32 LLViewerObject::setTEOffsetS(const U8 te, const F32 s) { - S32 retval = LLPrimitive::setTEOffsetS(te, s); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } + S32 retval = LLPrimitive::setTEOffsetS(te, s); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } - return retval; + return retval; } S32 LLViewerObject::setTEOffsetT(const U8 te, const F32 t) { - S32 retval = LLPrimitive::setTEOffsetT(te, t); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } + S32 retval = LLPrimitive::setTEOffsetT(te, t); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } - return retval; + return retval; } S32 LLViewerObject::setTERotation(const U8 te, const F32 r) { - S32 retval = LLPrimitive::setTERotation(te, r); - if (mDrawable.notNull() && retval) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + S32 retval = LLPrimitive::setTERotation(te, r); + if (mDrawable.notNull() && retval) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); shrinkWrap(); - } - return retval; + } + return retval; } LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const { -// llassert(mTEImages); +// llassert(mTEImages); - if (face < getNumTEs()) - { - LLViewerTexture* image = mTEImages[face]; - if (image) - { - return image; - } - else - { - return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); - } - } + if (face < getNumTEs()) + { + LLViewerTexture* image = mTEImages[face]; + if (image) + { + return image; + } + else + { + return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); + } + } - LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; + LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; - return NULL; + return NULL; } bool LLViewerObject::isImageAlphaBlended(const U8 te) const { - LLViewerTexture* image = getTEImage(te); - LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB; - switch (format) - { - case GL_RGBA: - case GL_ALPHA: - { - return true; - } - break; + LLViewerTexture* image = getTEImage(te); + LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB; + switch (format) + { + case GL_RGBA: + case GL_ALPHA: + { + return true; + } + break; - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << LL_ENDL; - } - break; - } + case GL_RGB: break; + default: + { + LL_WARNS() << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << LL_ENDL; + } + break; + } - return false; + return false; } LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const { - // llassert(mTEImages); - - if (face < getNumTEs()) - { - LLViewerTexture* image = mTENormalMaps[face]; - if (image) - { - return image; - } - else - { - return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); - } - } - - LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; - - return NULL; + // llassert(mTEImages); + + if (face < getNumTEs()) + { + LLViewerTexture* image = mTENormalMaps[face]; + if (image) + { + return image; + } + else + { + return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); + } + } + + LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; + + return NULL; } LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const { - // llassert(mTEImages); - - if (face < getNumTEs()) - { - LLViewerTexture* image = mTESpecularMaps[face]; - if (image) - { - return image; - } - else - { - return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); - } - } - - LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; - - return NULL; + // llassert(mTEImages); + + if (face < getNumTEs()) + { + LLViewerTexture* image = mTESpecularMaps[face]; + if (image) + { + return image; + } + else + { + return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); + } + } + + LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL; + + return NULL; } void LLViewerObject::fitFaceTexture(const U8 face) { - LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL; + LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL; } LLBBox LLViewerObject::getBoundingBoxAgent() const { - LLVector3 position_agent; - LLQuaternion rot; - LLViewerObject* avatar_parent = NULL; - LLViewerObject* root_edit = (LLViewerObject*)getRootEdit(); - if (root_edit) - { - avatar_parent = (LLViewerObject*)root_edit->getParent(); - } - - if (avatar_parent && avatar_parent->isAvatar() && - root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent()) - { - LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent(); - position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition(); - rot = getRotationEdit() * parent_xform->getWorldRotation(); - } - else - { - position_agent = getPositionAgent(); - rot = getRotationRegion(); - } - - return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f ); + LLVector3 position_agent; + LLQuaternion rot; + LLViewerObject* avatar_parent = NULL; + LLViewerObject* root_edit = (LLViewerObject*)getRootEdit(); + if (root_edit) + { + avatar_parent = (LLViewerObject*)root_edit->getParent(); + } + + if (avatar_parent && avatar_parent->isAvatar() && + root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent()) + { + LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent(); + position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition(); + rot = getRotationEdit() * parent_xform->getWorldRotation(); + } + else + { + position_agent = getPositionAgent(); + rot = getRotationRegion(); + } + + return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f ); } U32 LLViewerObject::getNumVertices() const { - U32 num_vertices = 0; - if (mDrawable.notNull()) - { - S32 i, num_faces; - num_faces = mDrawable->getNumFaces(); - for (i = 0; i < num_faces; i++) - { - LLFace * facep = mDrawable->getFace(i); - if (facep) - { - num_vertices += facep->getGeomCount(); - } - } - } - return num_vertices; + U32 num_vertices = 0; + if (mDrawable.notNull()) + { + S32 i, num_faces; + num_faces = mDrawable->getNumFaces(); + for (i = 0; i < num_faces; i++) + { + LLFace * facep = mDrawable->getFace(i); + if (facep) + { + num_vertices += facep->getGeomCount(); + } + } + } + return num_vertices; } U32 LLViewerObject::getNumIndices() const { - U32 num_indices = 0; - if (mDrawable.notNull()) - { - S32 i, num_faces; - num_faces = mDrawable->getNumFaces(); - for (i = 0; i < num_faces; i++) - { - LLFace * facep = mDrawable->getFace(i); - if (facep) - { - num_indices += facep->getIndicesCount(); - } - } - } - return num_indices; + U32 num_indices = 0; + if (mDrawable.notNull()) + { + S32 i, num_faces; + num_faces = mDrawable->getNumFaces(); + for (i = 0; i < num_faces; i++) + { + LLFace * facep = mDrawable->getFace(i); + if (facep) + { + num_indices += facep->getIndicesCount(); + } + } + } + return num_indices; } // Find the number of instances of this object's inventory that are of the given type S32 LLViewerObject::countInventoryContents(LLAssetType::EType type) { - S32 count = 0; - if( mInventory ) - { - LLInventoryObject::object_list_t::const_iterator it = mInventory->begin(); - LLInventoryObject::object_list_t::const_iterator end = mInventory->end(); - for( ; it != end ; ++it ) - { - if( (*it)->getType() == type ) - { - ++count; - } - } - } - return count; + S32 count = 0; + if( mInventory ) + { + LLInventoryObject::object_list_t::const_iterator it = mInventory->begin(); + LLInventoryObject::object_list_t::const_iterator end = mInventory->end(); + for( ; it != end ; ++it ) + { + if( (*it)->getType() == type ) + { + ++count; + } + } + } + return count; } void LLViewerObject::setDebugText(const std::string &utf8text, const LLColor4& color) { - if (utf8text.empty() && !mText) - { - return; - } + if (utf8text.empty() && !mText) + { + return; + } - if (!mText) - { - initHudText(); - } - mText->setColor(color); - mText->setString(utf8text); - mText->setZCompare(FALSE); - mText->setDoFade(FALSE); - updateText(); + if (!mText) + { + initHudText(); + } + mText->setColor(color); + mText->setString(utf8text); + mText->setZCompare(FALSE); + mText->setDoFade(FALSE); + updateText(); } void LLViewerObject::appendDebugText(const std::string &utf8text) @@ -6005,98 +6005,98 @@ void LLViewerObject::restoreHudText() void LLViewerObject::setIcon(LLViewerTexture* icon_image) { - if (!mIcon) - { - mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON); - mIcon->setSourceObject(this); - mIcon->setImage(icon_image); - // *TODO: make this user configurable - mIcon->setScale(0.03f); - } - else - { - mIcon->restartLifeTimer(); - } + if (!mIcon) + { + mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON); + mIcon->setSourceObject(this); + mIcon->setImage(icon_image); + // *TODO: make this user configurable + mIcon->setScale(0.03f); + } + else + { + mIcon->restartLifeTimer(); + } } void LLViewerObject::clearIcon() { - if (mIcon) - { - mIcon = NULL; - } + if (mIcon) + { + mIcon = NULL; + } } -LLViewerObject* LLViewerObject::getSubParent() -{ - return (LLViewerObject*) getParent(); +LLViewerObject* LLViewerObject::getSubParent() +{ + return (LLViewerObject*) getParent(); } const LLViewerObject* LLViewerObject::getSubParent() const { - return (const LLViewerObject*) getParent(); + return (const LLViewerObject*) getParent(); } BOOL LLViewerObject::isOnMap() { - return mOnMap; + return mOnMap; } void LLViewerObject::updateText() { - if (!isDead()) - { - if (mText.notNull()) - { - LLVOAvatar* avatar = getAvatar(); - if (avatar) - { - mText->setHidden(avatar->isInMuteList()); - } - - LLVector3 up_offset(0,0,0); - up_offset.mV[2] = getScale().mV[VZ]*0.6f; - - if (mDrawable.notNull()) - { - mText->setPositionAgent(getRenderPosition() + up_offset); - } - else - { - mText->setPositionAgent(getPositionAgent() + up_offset); - } - } - } + if (!isDead()) + { + if (mText.notNull()) + { + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + mText->setHidden(avatar->isInMuteList()); + } + + LLVector3 up_offset(0,0,0); + up_offset.mV[2] = getScale().mV[VZ]*0.6f; + + if (mDrawable.notNull()) + { + mText->setPositionAgent(getRenderPosition() + up_offset); + } + else + { + mText->setPositionAgent(getPositionAgent() + up_offset); + } + } + } } bool LLViewerObject::isOwnerInMuteList(LLUUID id) { - LLUUID owner_id = id.isNull() ? mOwnerID : id; - if (isAvatar() || owner_id.isNull()) - { - return false; - } - bool muted = false; - F64 now = LLFrameTimer::getTotalSeconds(); - if (now < mCachedMuteListUpdateTime) - { - muted = mCachedOwnerInMuteList; - } - else - { - muted = LLMuteList::getInstance()->isMuted(owner_id); - - const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; - mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; - mCachedOwnerInMuteList = muted; - } - return muted; + LLUUID owner_id = id.isNull() ? mOwnerID : id; + if (isAvatar() || owner_id.isNull()) + { + return false; + } + bool muted = false; + F64 now = LLFrameTimer::getTotalSeconds(); + if (now < mCachedMuteListUpdateTime) + { + muted = mCachedOwnerInMuteList; + } + else + { + muted = LLMuteList::getInstance()->isMuted(owner_id); + + const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; + mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; + mCachedOwnerInMuteList = muted; + } + return muted; } LLVOAvatar* LLViewerObject::asAvatar() { - return NULL; + return NULL; } // If this object is directly or indirectly parented by an avatar, @@ -6108,348 +6108,348 @@ LLVOAvatar* LLViewerObject::asAvatar() // attached. LLVOAvatar* LLViewerObject::getAvatarAncestor() { - LLViewerObject *pobj = (LLViewerObject*) getParent(); - while (pobj) - { - LLVOAvatar *av = pobj->asAvatar(); - if (av) - { - return av; - } - pobj = (LLViewerObject*) pobj->getParent(); - } - return NULL; + LLViewerObject *pobj = (LLViewerObject*) getParent(); + while (pobj) + { + LLVOAvatar *av = pobj->asAvatar(); + if (av) + { + return av; + } + pobj = (LLViewerObject*) pobj->getParent(); + } + return NULL; } BOOL LLViewerObject::isParticleSource() const { - return !mPartSourcep.isNull() && !mPartSourcep->isDead(); + return !mPartSourcep.isNull() && !mPartSourcep->isDead(); } void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id) { - if (mPartSourcep) - { - deleteParticleSource(); - } - - LLPointer pss = LLViewerPartSourceScript::createPSS(this, particle_parameters); - mPartSourcep = pss; - - if (mPartSourcep) - { - mPartSourcep->setOwnerUUID(owner_id); - - if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) - { - LLViewerTexture* image; - if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) - { - image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga"); - } - else - { - image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); - } - mPartSourcep->setImage(image); - } - } - LLViewerPartSim::getInstance()->addPartSource(pss); + if (mPartSourcep) + { + deleteParticleSource(); + } + + LLPointer pss = LLViewerPartSourceScript::createPSS(this, particle_parameters); + mPartSourcep = pss; + + if (mPartSourcep) + { + mPartSourcep->setOwnerUUID(owner_id); + + if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) + { + LLViewerTexture* image; + if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) + { + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga"); + } + else + { + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); + } + mPartSourcep->setImage(image); + } + } + LLViewerPartSim::getInstance()->addPartSource(pss); } void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id) { - if (!mPartSourcep.isNull() && mPartSourcep->isDead()) - { - mPartSourcep = NULL; - } - if (mPartSourcep) - { - // If we've got one already, just update the existing source (or remove it) - if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num)) - { - mPartSourcep->setDead(); - mPartSourcep = NULL; - } - } - else - { - LLPointer pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); - //If the owner is muted, don't create the system - if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; - - // We need to be able to deal with a particle source that hasn't changed, but still got an update! - if (pss) - { -// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; - pss->setOwnerUUID(owner_id); - mPartSourcep = pss; - LLViewerPartSim::getInstance()->addPartSource(pss); - } - } - if (mPartSourcep) - { - if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) - { - LLViewerTexture* image; - if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) - { - image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); - } - else - { - image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); - } - mPartSourcep->setImage(image); - } - } + if (!mPartSourcep.isNull() && mPartSourcep->isDead()) + { + mPartSourcep = NULL; + } + if (mPartSourcep) + { + // If we've got one already, just update the existing source (or remove it) + if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num)) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } + } + else + { + LLPointer pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); + //If the owner is muted, don't create the system + if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; + + // We need to be able to deal with a particle source that hasn't changed, but still got an update! + if (pss) + { +// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; + pss->setOwnerUUID(owner_id); + mPartSourcep = pss; + LLViewerPartSim::getInstance()->addPartSource(pss); + } + } + if (mPartSourcep) + { + if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) + { + LLViewerTexture* image; + if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) + { + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); + } + else + { + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); + } + mPartSourcep->setImage(image); + } + } } void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy) { - if (!mPartSourcep.isNull() && mPartSourcep->isDead()) - { - mPartSourcep = NULL; - } - if (mPartSourcep) - { - // If we've got one already, just update the existing source (or remove it) - if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy)) - { - mPartSourcep->setDead(); - mPartSourcep = NULL; - } - } - else - { - LLPointer pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy); - //If the owner is muted, don't create the system - if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; - // We need to be able to deal with a particle source that hasn't changed, but still got an update! - if (pss) - { -// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; - pss->setOwnerUUID(owner_id); - mPartSourcep = pss; - LLViewerPartSim::getInstance()->addPartSource(pss); - } - } - if (mPartSourcep) - { - if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) - { - LLViewerTexture* image; - if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) - { - image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); - } - else - { - image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); - } - mPartSourcep->setImage(image); - } - } + if (!mPartSourcep.isNull() && mPartSourcep->isDead()) + { + mPartSourcep = NULL; + } + if (mPartSourcep) + { + // If we've got one already, just update the existing source (or remove it) + if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy)) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } + } + else + { + LLPointer pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy); + //If the owner is muted, don't create the system + if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; + // We need to be able to deal with a particle source that hasn't changed, but still got an update! + if (pss) + { +// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; + pss->setOwnerUUID(owner_id); + mPartSourcep = pss; + LLViewerPartSim::getInstance()->addPartSource(pss); + } + } + if (mPartSourcep) + { + if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) + { + LLViewerTexture* image; + if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) + { + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); + } + else + { + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); + } + mPartSourcep->setImage(image); + } + } } void LLViewerObject::deleteParticleSource() { - if (mPartSourcep.notNull()) - { - mPartSourcep->setDead(); - mPartSourcep = NULL; - } + if (mPartSourcep.notNull()) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } } // virtual void LLViewerObject::updateDrawable(BOOL force_damped) { - if (!isChanged(MOVED)) - { //most common case, having an empty if case here makes for better branch prediction - } - else if (mDrawable.notNull() && - !mDrawable->isState(LLDrawable::ON_MOVE_LIST)) - { - BOOL damped_motion = - !isChanged(SHIFTED) && // not shifted between regions this frame and... - ( force_damped || // ...forced into damped motion by application logic or... - ( !isSelected() && // ...not selected and... - ( mDrawable->isRoot() || // ... is root or ... - (getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ... - ) && - getPCode() == LL_PCODE_VOLUME && // ...is a volume object and... - getVelocity().isExactlyZero() && // ...is not moving physically and... - mDrawable->getGeneration() != -1 // ...was not created this frame. - ) - ); - gPipeline.markMoved(mDrawable, damped_motion); - } - clearChanged(SHIFTED); + if (!isChanged(MOVED)) + { //most common case, having an empty if case here makes for better branch prediction + } + else if (mDrawable.notNull() && + !mDrawable->isState(LLDrawable::ON_MOVE_LIST)) + { + BOOL damped_motion = + !isChanged(SHIFTED) && // not shifted between regions this frame and... + ( force_damped || // ...forced into damped motion by application logic or... + ( !isSelected() && // ...not selected and... + ( mDrawable->isRoot() || // ... is root or ... + (getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ... + ) && + getPCode() == LL_PCODE_VOLUME && // ...is a volume object and... + getVelocity().isExactlyZero() && // ...is not moving physically and... + mDrawable->getGeneration() != -1 // ...was not created this frame. + ) + ); + gPipeline.markMoved(mDrawable, damped_motion); + } + clearChanged(SHIFTED); } // virtual, overridden by LLVOVolume F32 LLViewerObject::getVObjRadius() const { - return mDrawable.notNull() ? mDrawable->getRadius() : 0.f; + return mDrawable.notNull() ? mDrawable->getRadius() : 0.f; } void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags) { - if (!gAudiop) - { - return; - } - - if (audio_uuid.isNull()) - { - if (!mAudioSourcep) - { - return; - } - if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads()) - { - // We don't clear the sound if it's a loop, it'll go away on its own. - // At least, this appears to be how the scripts work. - // The attached sound ID is set to NULL to avoid it playing back when the - // object rezzes in on non-looping sounds. - //LL_INFOS() << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << LL_ENDL; - gAudiop->cleanupAudioSource(mAudioSourcep); - mAudioSourcep = NULL; - } - else if (flags & LL_SOUND_FLAG_STOP) - { - // Just shut off the sound - mAudioSourcep->stop(); - } - return; - } - if (flags & LL_SOUND_FLAG_LOOP - && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData() - && mAudioSourcep->getCurrentData()->getID() == audio_uuid) - { - //LL_INFOS() << "Already playing this sound on a loop, ignoring" << LL_ENDL; - return; - } - - // don't clean up before previous sound is done. Solves: SL-33486 - if ( mAudioSourcep && mAudioSourcep->isDone() ) - { - gAudiop->cleanupAudioSource(mAudioSourcep); - mAudioSourcep = NULL; - } - - if (mAudioSourcep && mAudioSourcep->isMuted() && - mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) - { - //LL_INFOS() << "Already having this sound as muted sound, ignoring" << LL_ENDL; - return; - } - - getAudioSource(owner_id); - - if (mAudioSourcep) - { - BOOL queue = flags & LL_SOUND_FLAG_QUEUE; - mAudioGain = gain; - mAudioSourcep->setGain(gain); - mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP); - mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER); - mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE); - mAudioSourcep->setQueueSounds(queue); - if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG - { - mAudioSourcep->stop(); - } - - // Play this sound if region maturity permits - if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) ) - { - //LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL; - // recheck cutoff radius in case this update was an object-update with new value - mAudioSourcep->checkCutOffRadius(); - mAudioSourcep->play(audio_uuid); - } - } + if (!gAudiop) + { + return; + } + + if (audio_uuid.isNull()) + { + if (!mAudioSourcep) + { + return; + } + if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads()) + { + // We don't clear the sound if it's a loop, it'll go away on its own. + // At least, this appears to be how the scripts work. + // The attached sound ID is set to NULL to avoid it playing back when the + // object rezzes in on non-looping sounds. + //LL_INFOS() << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << LL_ENDL; + gAudiop->cleanupAudioSource(mAudioSourcep); + mAudioSourcep = NULL; + } + else if (flags & LL_SOUND_FLAG_STOP) + { + // Just shut off the sound + mAudioSourcep->stop(); + } + return; + } + if (flags & LL_SOUND_FLAG_LOOP + && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData() + && mAudioSourcep->getCurrentData()->getID() == audio_uuid) + { + //LL_INFOS() << "Already playing this sound on a loop, ignoring" << LL_ENDL; + return; + } + + // don't clean up before previous sound is done. Solves: SL-33486 + if ( mAudioSourcep && mAudioSourcep->isDone() ) + { + gAudiop->cleanupAudioSource(mAudioSourcep); + mAudioSourcep = NULL; + } + + if (mAudioSourcep && mAudioSourcep->isMuted() && + mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) + { + //LL_INFOS() << "Already having this sound as muted sound, ignoring" << LL_ENDL; + return; + } + + getAudioSource(owner_id); + + if (mAudioSourcep) + { + BOOL queue = flags & LL_SOUND_FLAG_QUEUE; + mAudioGain = gain; + mAudioSourcep->setGain(gain); + mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP); + mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER); + mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE); + mAudioSourcep->setQueueSounds(queue); + if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG + { + mAudioSourcep->stop(); + } + + // Play this sound if region maturity permits + if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) ) + { + //LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL; + // recheck cutoff radius in case this update was an object-update with new value + mAudioSourcep->checkCutOffRadius(); + mAudioSourcep->play(audio_uuid); + } + } } LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id) { - if (!mAudioSourcep) - { - // Arbitrary low gain for a sound that's not playing. - // This is used for sound preloads, for example. - LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this); + if (!mAudioSourcep) + { + // Arbitrary low gain for a sound that's not playing. + // This is used for sound preloads, for example. + LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this); - mAudioSourcep = asvop; - if(gAudiop) - { - gAudiop->addAudioSource(asvop); - } - } + mAudioSourcep = asvop; + if(gAudiop) + { + gAudiop->addAudioSource(asvop); + } + } - return mAudioSourcep; + return mAudioSourcep; } void LLViewerObject::adjustAudioGain(const F32 gain) { - if (mAudioSourcep) - { - mAudioGain = gain; - mAudioSourcep->setGain(mAudioGain); - } + if (mAudioSourcep) + { + mAudioGain = gain; + mAudioSourcep->setGain(mAudioGain); + } } //---------------------------------------------------------------------------- bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp) { - if (LLNetworkData::PARAMS_MESH == param_type) - { - param_type = LLNetworkData::PARAMS_SCULPT; - } - ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param) - { - param->data->unpack(*dp); - param->in_use = TRUE; - parameterChanged(param_type, param->data, TRUE, false); - return true; - } - else - { - return false; - } + if (LLNetworkData::PARAMS_MESH == param_type) + { + param_type = LLNetworkData::PARAMS_SCULPT; + } + ExtraParameter* param = getExtraParameterEntryCreate(param_type); + if (param) + { + param->data->unpack(*dp); + param->in_use = TRUE; + parameterChanged(param_type, param->data, TRUE, false); + return true; + } + else + { + return false; + } } LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type) { - LLNetworkData* new_block = NULL; - switch (param_type) - { - case LLNetworkData::PARAMS_FLEXIBLE: - { - new_block = new LLFlexibleObjectData(); - break; - } - case LLNetworkData::PARAMS_LIGHT: - { - new_block = new LLLightParams(); - break; - } - case LLNetworkData::PARAMS_SCULPT: - { - new_block = new LLSculptParams(); - break; - } - case LLNetworkData::PARAMS_LIGHT_IMAGE: - { - new_block = new LLLightImageParams(); - break; - } + LLNetworkData* new_block = NULL; + switch (param_type) + { + case LLNetworkData::PARAMS_FLEXIBLE: + { + new_block = new LLFlexibleObjectData(); + break; + } + case LLNetworkData::PARAMS_LIGHT: + { + new_block = new LLLightParams(); + break; + } + case LLNetworkData::PARAMS_SCULPT: + { + new_block = new LLSculptParams(); + break; + } + case LLNetworkData::PARAMS_LIGHT_IMAGE: + { + new_block = new LLLightImageParams(); + break; + } case LLNetworkData::PARAMS_EXTENDED_MESH: { - new_block = new LLExtendedMeshParams(); - break; + new_block = new LLExtendedMeshParams(); + break; } case LLNetworkData::PARAMS_RENDER_MATERIAL: { @@ -6461,90 +6461,90 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLReflectionProbeParams(); break; } - default: - { - LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL; - break; - } - }; - - if (new_block) - { - ExtraParameter* new_entry = new ExtraParameter; - new_entry->data = new_block; - new_entry->in_use = false; // not in use yet + default: + { + LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL; + break; + } + }; + + if (new_block) + { + ExtraParameter* new_entry = new ExtraParameter; + new_entry->data = new_block; + new_entry->in_use = false; // not in use yet llassert(mExtraParameterList[param_type] == nullptr); // leak -- redundantly allocated parameter entry - mExtraParameterList[param_type] = new_entry; - return new_entry; - } - return NULL; + mExtraParameterList[param_type] = new_entry; + return new_entry; + } + return NULL; } LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER; - std::unordered_map::const_iterator itor = mExtraParameterList.find(param_type); - if (itor != mExtraParameterList.end()) - { - return itor->second; - } - return NULL; + std::unordered_map::const_iterator itor = mExtraParameterList.find(param_type); + if (itor != mExtraParameterList.end()) + { + return itor->second; + } + return NULL; } LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type) { - ExtraParameter* param = getExtraParameterEntry(param_type); - if (!param) - { - param = createNewParameterEntry(param_type); - } - return param; + ExtraParameter* param = getExtraParameterEntry(param_type); + if (!param) + { + param = createNewParameterEntry(param_type); + } + return param; } LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const { - ExtraParameter* param = getExtraParameterEntry(param_type); - if (param) - { - return param->data; - } - else - { - return NULL; - } + ExtraParameter* param = getExtraParameterEntry(param_type); + if (param) + { + return param->data; + } + else + { + return NULL; + } } BOOL LLViewerObject::getParameterEntryInUse(U16 param_type) const { - ExtraParameter* param = getExtraParameterEntry(param_type); - if (param) - { - return param->in_use; - } - else - { - return FALSE; - } + ExtraParameter* param = getExtraParameterEntry(param_type); + if (param) + { + return param->in_use; + } + else + { + return FALSE; + } } bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin) { - ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param) - { - if (param->in_use && new_value == *(param->data)) - { - return false; - } - param->in_use = true; - param->data->copy(new_value); - parameterChanged(param_type, param->data, TRUE, local_origin); - return true; - } - else - { - return false; - } + ExtraParameter* param = getExtraParameterEntryCreate(param_type); + if (param) + { + if (param->in_use && new_value == *(param->data)) + { + return false; + } + param->in_use = true; + param->data->copy(new_value); + parameterChanged(param_type, param->data, TRUE, local_origin); + return true; + } + else + { + return false; + } } // Assumed to be called locally @@ -6552,65 +6552,65 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_ // Should always return true. bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin) { - ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param && param->in_use != in_use) - { - param->in_use = in_use; - parameterChanged(param_type, param->data, in_use, local_origin); - return true; - } - return false; + ExtraParameter* param = getExtraParameterEntryCreate(param_type); + if (param && param->in_use != in_use) + { + param->in_use = in_use; + parameterChanged(param_type, param->data, in_use, local_origin); + return true; + } + return false; } void LLViewerObject::parameterChanged(U16 param_type, bool local_origin) { - ExtraParameter* param = getExtraParameterEntry(param_type); - if (param) - { - parameterChanged(param_type, param->data, param->in_use, local_origin); - } + ExtraParameter* param = getExtraParameterEntry(param_type); + if (param) + { + parameterChanged(param_type, param->data, param->in_use, local_origin); + } } void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) { - if (local_origin) - { + if (local_origin) + { // *NOTE: Do not send the render material ID in this way as it will get // out-of-sync with other sent client data. // See LLViewerObject::setRenderMaterialID and LLGLTFMaterialList llassert(param_type != LLNetworkData::PARAMS_RENDER_MATERIAL); - LLViewerRegion* regionp = getRegion(); - if(!regionp) return; - - // Change happened on the viewer. Send the change up - U8 tmp[MAX_OBJECT_PARAMS_SIZE]; - LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE); - if (data->pack(dpb)) - { - U32 datasize = (U32)dpb.getCurrentSize(); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectExtraParams); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); - - msg->addU16Fast(_PREHASH_ParamType, param_type); - msg->addBOOLFast(_PREHASH_ParamInUse, in_use); - - msg->addU32Fast(_PREHASH_ParamSize, datasize); - msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize); - - msg->sendReliable( regionp->getHost() ); - } - else - { - LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL; - } - } + LLViewerRegion* regionp = getRegion(); + if(!regionp) return; + + // Change happened on the viewer. Send the change up + U8 tmp[MAX_OBJECT_PARAMS_SIZE]; + LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE); + if (data->pack(dpb)) + { + U32 datasize = (U32)dpb.getCurrentSize(); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ObjectExtraParams); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID ); + + msg->addU16Fast(_PREHASH_ParamType, param_type); + msg->addBOOLFast(_PREHASH_ParamInUse, in_use); + + msg->addU32Fast(_PREHASH_ParamSize, datasize); + msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize); + + msg->sendReliable( regionp->getHost() ); + } + else + { + LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL; + } + } else { if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL) @@ -6623,256 +6623,256 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL void LLViewerObject::setDrawableState(U32 state, BOOL recursive) { - if (mDrawable) - { - mDrawable->setState(state); - } - if (recursive) - { - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - child->setDrawableState(state, recursive); - } - } + if (mDrawable) + { + mDrawable->setState(state); + } + if (recursive) + { + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + child->setDrawableState(state, recursive); + } + } } void LLViewerObject::clearDrawableState(U32 state, BOOL recursive) { - if (mDrawable) - { - mDrawable->clearState(state); - } - if (recursive) - { - for (child_list_t::iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* child = *iter; - child->clearDrawableState(state, recursive); - } - } + if (mDrawable) + { + mDrawable->clearState(state); + } + if (recursive) + { + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + child->clearDrawableState(state, recursive); + } + } } BOOL LLViewerObject::isDrawableState(U32 state, BOOL recursive) const { - BOOL matches = FALSE; - if (mDrawable) - { - matches = mDrawable->isState(state); - } - if (recursive) - { - for (child_list_t::const_iterator iter = mChildList.begin(); - (iter != mChildList.end()) && matches; iter++) - { - LLViewerObject* child = *iter; - matches &= child->isDrawableState(state, recursive); - } - } + BOOL matches = FALSE; + if (mDrawable) + { + matches = mDrawable->isState(state); + } + if (recursive) + { + for (child_list_t::const_iterator iter = mChildList.begin(); + (iter != mChildList.end()) && matches; iter++) + { + LLViewerObject* child = *iter; + matches &= child->isDrawableState(state, recursive); + } + } - return matches; + return matches; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// RN: these functions assume a 2-level hierarchy +// RN: these functions assume a 2-level hierarchy //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Owned by anyone? BOOL LLViewerObject::permAnyOwner() const -{ - if (isRootEdit()) - { - return flagObjectAnyOwner(); - } - else - { - return ((LLViewerObject*)getParent())->permAnyOwner(); - } -} +{ + if (isRootEdit()) + { + return flagObjectAnyOwner(); + } + else + { + return ((LLViewerObject*)getParent())->permAnyOwner(); + } +} // Owned by this viewer? BOOL LLViewerObject::permYouOwner() const -{ - if (isRootEdit()) - { +{ + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectYouOwner(); + return flagObjectYouOwner(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permYouOwner(); - } + } + else + { + return ((LLViewerObject*)getParent())->permYouOwner(); + } } // Owned by a group? -BOOL LLViewerObject::permGroupOwner() const -{ - if (isRootEdit()) - { - return flagObjectGroupOwned(); - } - else - { - return ((LLViewerObject*)getParent())->permGroupOwner(); - } +BOOL LLViewerObject::permGroupOwner() const +{ + if (isRootEdit()) + { + return flagObjectGroupOwned(); + } + else + { + return ((LLViewerObject*)getParent())->permGroupOwner(); + } } // Can the owner edit BOOL LLViewerObject::permOwnerModify() const -{ - if (isRootEdit()) - { +{ + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectOwnerModify(); + return flagObjectOwnerModify(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permOwnerModify(); - } + } + else + { + return ((LLViewerObject*)getParent())->permOwnerModify(); + } } // Can edit BOOL LLViewerObject::permModify() const -{ - if (isRootEdit()) - { +{ + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectModify(); + return flagObjectModify(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permModify(); - } + } + else + { + return ((LLViewerObject*)getParent())->permModify(); + } } // Can copy BOOL LLViewerObject::permCopy() const -{ - if (isRootEdit()) - { +{ + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectCopy(); + return flagObjectCopy(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permCopy(); - } + } + else + { + return ((LLViewerObject*)getParent())->permCopy(); + } } // Can move BOOL LLViewerObject::permMove() const { - if (isRootEdit()) - { + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectMove(); + return flagObjectMove(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permMove(); - } + } + else + { + return ((LLViewerObject*)getParent())->permMove(); + } } // Can be transferred BOOL LLViewerObject::permTransfer() const -{ - if (isRootEdit()) - { +{ + if (isRootEdit()) + { #ifdef HACKED_GODLIKE_VIEWER - return TRUE; + return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstance()->isInProductionGrid() + if (!LLGridManager::getInstance()->isInProductionGrid() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) - { - return TRUE; - } + { + return TRUE; + } # endif - return flagObjectTransfer(); + return flagObjectTransfer(); #endif - } - else - { - return ((LLViewerObject*)getParent())->permTransfer(); - } + } + else + { + return ((LLViewerObject*)getParent())->permTransfer(); + } } // Can only open objects that you own, or that someone has // given you modify rights to. JC BOOL LLViewerObject::allowOpen() const { - return !flagInventoryEmpty() && (permYouOwner() || permModify()); + return !flagInventoryEmpty() && (permYouOwner() || permModify()); } LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo() { - if (mListener) - { - mListener->clearVOInventoryListener(); - } + if (mListener) + { + mListener->clearVOInventoryListener(); + } } void LLViewerObject::updateVolume(const LLVolumeParams& volume_params) { - if (setVolume(volume_params, 1)) // *FIX: magic number, ack! - { - // Transmit the update to the simulator - sendShapeUpdate(); - markForUpdate(); - } + if (setVolume(volume_params, 1)) // *FIX: magic number, ack! + { + // Transmit the update to the simulator + sendShapeUpdate(); + markForUpdate(); + } } void LLViewerObject::recursiveMarkForUpdate() @@ -6888,259 +6888,259 @@ void LLViewerObject::recursiveMarkForUpdate() void LLViewerObject::markForUpdate() { - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); - } + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + } } bool LLViewerObject::isPermanentEnforced() const { - return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike(); + return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike(); } bool LLViewerObject::getIncludeInSearch() const { - return flagIncludeInSearch(); + return flagIncludeInSearch(); } void LLViewerObject::setIncludeInSearch(bool include_in_search) { - setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search); + setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search); } void LLViewerObject::setRegion(LLViewerRegion *regionp) { - if (!regionp) - { - LL_WARNS() << "viewer object set region to NULL" << LL_ENDL; - } - if(regionp != mRegionp) - { - if(mRegionp) - { - mRegionp->removeFromCreatedList(getLocalID()); - } - if(regionp) - { - regionp->addToCreatedList(getLocalID()); - } - } - - mLatestRecvPacketID = 0; - mRegionp = regionp; - - for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) - { - LLViewerObject* child = *i; - child->setRegion(regionp); - } + if (!regionp) + { + LL_WARNS() << "viewer object set region to NULL" << LL_ENDL; + } + if(regionp != mRegionp) + { + if(mRegionp) + { + mRegionp->removeFromCreatedList(getLocalID()); + } + if(regionp) + { + regionp->addToCreatedList(getLocalID()); + } + } + + mLatestRecvPacketID = 0; + mRegionp = regionp; + + for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) + { + LLViewerObject* child = *i; + child->setRegion(regionp); + } if (mControlAvatar) { mControlAvatar->setRegion(regionp); } - setChanged(MOVED | SILHOUETTE); - updateDrawable(FALSE); + setChanged(MOVED | SILHOUETTE); + updateDrawable(FALSE); } // virtual -void LLViewerObject::updateRegion(LLViewerRegion *regionp) +void LLViewerObject::updateRegion(LLViewerRegion *regionp) { -// if (regionp) -// { -// F64 now = LLFrameTimer::getElapsedSeconds(); -// LL_INFOS() << "Updating to region " << regionp->getName() -// << ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0) -// << ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0) -// << LL_ENDL; -// } +// if (regionp) +// { +// F64 now = LLFrameTimer::getElapsedSeconds(); +// LL_INFOS() << "Updating to region " << regionp->getName() +// << ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0) +// << ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0) +// << LL_ENDL; +// } } bool LLViewerObject::specialHoverCursor() const { - return flagUsePhysics() - || flagHandleTouch() - || (mClickAction != 0); + return flagUsePhysics() + || flagHandleTouch() + || (mClickAction != 0); } void LLViewerObject::updateFlags(BOOL physics_changed) { - LLViewerRegion* regionp = getRegion(); - if(!regionp) return; - gMessageSystem->newMessage("ObjectFlagUpdate"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() ); - gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() ); - gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); - gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); - - // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator - // The simulator code does not even unpack this value when the message is received. - // This could be potentially hijacked in the future for another use should the urgent need arise. - gMessageSystem->addBOOL("CastsShadows", FALSE ); - - if (physics_changed) - { - gMessageSystem->nextBlock("ExtraPhysics"); - gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() ); - gMessageSystem->addF32("Density", getPhysicsDensity() ); - gMessageSystem->addF32("Friction", getPhysicsFriction() ); - gMessageSystem->addF32("Restitution", getPhysicsRestitution() ); - gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() ); - } - gMessageSystem->sendReliable( regionp->getHost() ); + LLViewerRegion* regionp = getRegion(); + if(!regionp) return; + gMessageSystem->newMessage("ObjectFlagUpdate"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() ); + gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() ); + gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); + gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); + + // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator + // The simulator code does not even unpack this value when the message is received. + // This could be potentially hijacked in the future for another use should the urgent need arise. + gMessageSystem->addBOOL("CastsShadows", FALSE ); + + if (physics_changed) + { + gMessageSystem->nextBlock("ExtraPhysics"); + gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() ); + gMessageSystem->addF32("Density", getPhysicsDensity() ); + gMessageSystem->addF32("Friction", getPhysicsFriction() ); + gMessageSystem->addF32("Restitution", getPhysicsRestitution() ); + gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() ); + } + gMessageSystem->sendReliable( regionp->getHost() ); } BOOL LLViewerObject::setFlags(U32 flags, BOOL state) { - BOOL setit = setFlagsWithoutUpdate(flags, state); + BOOL setit = setFlagsWithoutUpdate(flags, state); - // BUG: Sometimes viewer physics and simulator physics get - // out of sync. To fix this, always send update to simulator. -// if (setit) - { - updateFlags(); - } - return setit; + // BUG: Sometimes viewer physics and simulator physics get + // out of sync. To fix this, always send update to simulator. +// if (setit) + { + updateFlags(); + } + return setit; } BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state) { - BOOL setit = FALSE; - if (state) - { - if ((mFlags & flags) != flags) - { - mFlags |= flags; - setit = TRUE; - } - } - else - { - if ((mFlags & flags) != 0) - { - mFlags &= ~flags; - setit = TRUE; - } - } - return setit; + BOOL setit = FALSE; + if (state) + { + if ((mFlags & flags) != flags) + { + mFlags |= flags; + setit = TRUE; + } + } + else + { + if ((mFlags & flags) != 0) + { + mFlags &= ~flags; + setit = TRUE; + } + } + return setit; } void LLViewerObject::setPhysicsShapeType(U8 type) { - mPhysicsShapeUnknown = false; - if (type != mPhysicsShapeType) - { - mPhysicsShapeType = type; - setObjectCostStale(); + mPhysicsShapeUnknown = false; + if (type != mPhysicsShapeType) + { + mPhysicsShapeType = type; + setObjectCostStale(); } } void LLViewerObject::setPhysicsGravity(F32 gravity) { - mPhysicsGravity = gravity; + mPhysicsGravity = gravity; } void LLViewerObject::setPhysicsFriction(F32 friction) { - mPhysicsFriction = friction; + mPhysicsFriction = friction; } void LLViewerObject::setPhysicsDensity(F32 density) { - mPhysicsDensity = density; + mPhysicsDensity = density; } void LLViewerObject::setPhysicsRestitution(F32 restitution) { - mPhysicsRestitution = restitution; + mPhysicsRestitution = restitution; } U8 LLViewerObject::getPhysicsShapeType() const -{ - if (mPhysicsShapeUnknown) - { - gObjectList.updatePhysicsFlags(this); - } +{ + if (mPhysicsShapeUnknown) + { + gObjectList.updatePhysicsFlags(this); + } - return mPhysicsShapeType; + return mPhysicsShapeType; } void LLViewerObject::applyAngularVelocity(F32 dt) { - //do target omega here - mRotTime += dt; - LLVector3 ang_vel = getAngularVelocity(); - F32 omega = ang_vel.magVecSquared(); - F32 angle = 0.0f; - LLQuaternion dQ; - if (omega > 0.00001f) - { - omega = sqrt(omega); - angle = omega * dt; - - ang_vel *= 1.f/omega; - - // calculate the delta increment based on the object's angular velocity - dQ.setQuat(angle, ang_vel); - - // accumulate the angular velocity rotations to re-apply in the case of an object update - mAngularVelocityRot *= dQ; - - // Just apply the delta increment to the current rotation - setRotation(getRotation()*dQ); - setChanged(MOVED | SILHOUETTE); - } + //do target omega here + mRotTime += dt; + LLVector3 ang_vel = getAngularVelocity(); + F32 omega = ang_vel.magVecSquared(); + F32 angle = 0.0f; + LLQuaternion dQ; + if (omega > 0.00001f) + { + omega = sqrt(omega); + angle = omega * dt; + + ang_vel *= 1.f/omega; + + // calculate the delta increment based on the object's angular velocity + dQ.setQuat(angle, ang_vel); + + // accumulate the angular velocity rotations to re-apply in the case of an object update + mAngularVelocityRot *= dQ; + + // Just apply the delta increment to the current rotation + setRotation(getRotation()*dQ); + setChanged(MOVED | SILHOUETTE); + } } void LLViewerObject::resetRotTime() { - mRotTime = 0.0f; + mRotTime = 0.0f; } void LLViewerObject::resetRot() { - resetRotTime(); + resetRotTime(); - // Reset the accumulated angular velocity rotation - mAngularVelocityRot.loadIdentity(); + // Reset the accumulated angular velocity rotation + mAngularVelocityRot.loadIdentity(); } U32 LLViewerObject::getPartitionType() const -{ - return LLViewerRegion::PARTITION_NONE; +{ + return LLViewerRegion::PARTITION_NONE; } void LLViewerObject::dirtySpatialGroup() const { - if (mDrawable) - { - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->dirtyGeom(); - gPipeline.markRebuild(group); - } - } + if (mDrawable) + { + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + gPipeline.markRebuild(group); + } + } } void LLViewerObject::dirtyMesh() { - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } + if (mDrawable) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } } F32 LLAlphaObject::getPartSize(S32 idx) { - return 0.f; + return 0.f; } void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst) @@ -7151,235 +7151,235 @@ void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender // virtual void LLStaticViewerObject::updateDrawable(BOOL force_damped) { - // Force an immediate rebuild on any update - if (mDrawable.notNull()) - { - mDrawable->updateXform(TRUE); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - clearChanged(SHIFTED); + // Force an immediate rebuild on any update + if (mDrawable.notNull()) + { + mDrawable->updateXform(TRUE); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + clearChanged(SHIFTED); } void LLViewerObject::saveUnselectedChildrenPosition(std::vector& positions) { - if(mChildList.empty() || !positions.empty()) - { - return ; - } + if(mChildList.empty() || !positions.empty()) + { + return ; + } - for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* childp = *iter; - if (!childp->isSelected() && childp->mDrawable.notNull()) - { - positions.push_back(childp->getPositionEdit()); - } - } + for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* childp = *iter; + if (!childp->isSelected() && childp->mDrawable.notNull()) + { + positions.push_back(childp->getPositionEdit()); + } + } - return ; + return ; } void LLViewerObject::saveUnselectedChildrenRotation(std::vector& rotations) { - if(mChildList.empty()) - { - return ; - } + if(mChildList.empty()) + { + return ; + } - for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* childp = *iter; - if (!childp->isSelected() && childp->mDrawable.notNull()) - { - rotations.push_back(childp->getRotationEdit()); - } - } + for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* childp = *iter; + if (!childp->isSelected() && childp->mDrawable.notNull()) + { + rotations.push_back(childp->getRotationEdit()); + } + } - return ; + return ; } //counter-rotation -void LLViewerObject::resetChildrenRotationAndPosition(const std::vector& rotations, - const std::vector& positions) -{ - if(mChildList.empty()) - { - return ; - } - - S32 index = 0 ; - LLQuaternion inv_rotation = ~getRotationEdit() ; - LLVector3 offset = getPositionEdit() ; - for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* childp = *iter; - if (!childp->isSelected() && childp->mDrawable.notNull()) - { - if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) - { - childp->setRotation(rotations[index] * inv_rotation); - childp->setPosition((positions[index] - offset) * inv_rotation); - LLManip::rebuild(childp); - } - else //avatar - { - LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ; - LLQuaternion reset_rot = rotations[index] * inv_rotation ; - - ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos); - ((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ; - - ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE); - ((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ; - - LLManip::rebuild(childp); - } - index++; - } - } - - return ; +void LLViewerObject::resetChildrenRotationAndPosition(const std::vector& rotations, + const std::vector& positions) +{ + if(mChildList.empty()) + { + return ; + } + + S32 index = 0 ; + LLQuaternion inv_rotation = ~getRotationEdit() ; + LLVector3 offset = getPositionEdit() ; + for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* childp = *iter; + if (!childp->isSelected() && childp->mDrawable.notNull()) + { + if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) + { + childp->setRotation(rotations[index] * inv_rotation); + childp->setPosition((positions[index] - offset) * inv_rotation); + LLManip::rebuild(childp); + } + else //avatar + { + LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ; + LLQuaternion reset_rot = rotations[index] * inv_rotation ; + + ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos); + ((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ; + + ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE); + ((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ; + + LLManip::rebuild(childp); + } + index++; + } + } + + return ; } //counter-translation void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplified, BOOL skip_avatar_child) { - if(mChildList.empty()) - { - return ; - } - - LLVector3 child_offset; - if(simplified) //translation only, rotation matrix does not change - { - child_offset = offset * ~getRotation(); - } - else //rotation matrix might change too. - { - if (isAttachment() && mDrawable.notNull()) - { - LLXform* attachment_point_xform = mDrawable->getXform()->getParent(); - LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation(); - child_offset = offset * ~parent_rotation; - } - else - { - child_offset = offset * ~getRenderRotation(); - } - } - - for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); - iter != mChildList.end(); iter++) - { - LLViewerObject* childp = *iter; - - if (!childp->isSelected() && childp->mDrawable.notNull()) - { - if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) - { - childp->setPosition(childp->getPosition() + child_offset); - LLManip::rebuild(childp); - } - else //avatar - { - if(!skip_avatar_child) - { - LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ; - - ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos); - ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos); - LLManip::rebuild(childp); - } - } - } - } - - return ; -} - -// virtual -BOOL LLViewerObject::isTempAttachment() const -{ - return (mID.notNull() && (mID == mAttachmentItemID)); + if(mChildList.empty()) + { + return ; + } + + LLVector3 child_offset; + if(simplified) //translation only, rotation matrix does not change + { + child_offset = offset * ~getRotation(); + } + else //rotation matrix might change too. + { + if (isAttachment() && mDrawable.notNull()) + { + LLXform* attachment_point_xform = mDrawable->getXform()->getParent(); + LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation(); + child_offset = offset * ~parent_rotation; + } + else + { + child_offset = offset * ~getRenderRotation(); + } + } + + for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* childp = *iter; + + if (!childp->isSelected() && childp->mDrawable.notNull()) + { + if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) + { + childp->setPosition(childp->getPosition() + child_offset); + LLManip::rebuild(childp); + } + else //avatar + { + if(!skip_avatar_child) + { + LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ; + + ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos); + ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos); + LLManip::rebuild(childp); + } + } + } + } + + return ; } -BOOL LLViewerObject::isHiglightedOrBeacon() const +// virtual +BOOL LLViewerObject::isTempAttachment() const { - if (LLFloaterReg::instanceVisible("beacons") && (gPipeline.getRenderBeacons() || gPipeline.getRenderHighlights())) - { - BOOL has_media = (getMediaType() == LLViewerObject::MEDIA_SET); - BOOL is_scripted = !isAvatar() && !getParent() && flagScripted(); - BOOL is_physical = !isAvatar() && flagUsePhysics(); + return (mID.notNull() && (mID == mAttachmentItemID)); +} - return (isParticleSource() && gPipeline.getRenderParticleBeacons()) - || (isAudioSource() && gPipeline.getRenderSoundBeacons()) - || (has_media && gPipeline.getRenderMOAPBeacons()) - || (is_scripted && gPipeline.getRenderScriptedBeacons()) - || (is_scripted && flagHandleTouch() && gPipeline.getRenderScriptedTouchBeacons()) - || (is_physical && gPipeline.getRenderPhysicalBeacons()); - } - return FALSE; +BOOL LLViewerObject::isHiglightedOrBeacon() const +{ + if (LLFloaterReg::instanceVisible("beacons") && (gPipeline.getRenderBeacons() || gPipeline.getRenderHighlights())) + { + BOOL has_media = (getMediaType() == LLViewerObject::MEDIA_SET); + BOOL is_scripted = !isAvatar() && !getParent() && flagScripted(); + BOOL is_physical = !isAvatar() && flagUsePhysics(); + + return (isParticleSource() && gPipeline.getRenderParticleBeacons()) + || (isAudioSource() && gPipeline.getRenderSoundBeacons()) + || (has_media && gPipeline.getRenderMOAPBeacons()) + || (is_scripted && gPipeline.getRenderScriptedBeacons()) + || (is_scripted && flagHandleTouch() && gPipeline.getRenderScriptedTouchBeacons()) + || (is_physical && gPipeline.getRenderPhysicalBeacons()); + } + return FALSE; } const LLUUID &LLViewerObject::getAttachmentItemID() const { - return mAttachmentItemID; + return mAttachmentItemID; } void LLViewerObject::setAttachmentItemID(const LLUUID &id) { - mAttachmentItemID = id; + mAttachmentItemID = id; } EObjectUpdateType LLViewerObject::getLastUpdateType() const { - return mLastUpdateType; + return mLastUpdateType; } void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type) { - mLastUpdateType = last_update_type; + mLastUpdateType = last_update_type; } BOOL LLViewerObject::getLastUpdateCached() const { - return mLastUpdateCached; + return mLastUpdateCached; } void LLViewerObject::setLastUpdateCached(BOOL last_update_cached) { - mLastUpdateCached = last_update_cached; + mLastUpdateCached = last_update_cached; } const LLUUID &LLViewerObject::extractAttachmentItemID() { - LLUUID item_id = LLUUID::null; - LLNameValue* item_id_nv = getNVPair("AttachItemID"); - if( item_id_nv ) - { - const char* s = item_id_nv->getString(); - if( s ) - { - item_id.set(s); - } - } - setAttachmentItemID(item_id); - return getAttachmentItemID(); + LLUUID item_id = LLUUID::null; + LLNameValue* item_id_nv = getNVPair("AttachItemID"); + if( item_id_nv ) + { + const char* s = item_id_nv->getString(); + if( s ) + { + item_id.set(s); + } + } + setAttachmentItemID(item_id); + return getAttachmentItemID(); } const std::string& LLViewerObject::getAttachmentItemName() const { - static std::string empty; - LLInventoryItem *item = gInventory.getItem(getAttachmentItemID()); - if (isAttachment() && item) - { - return item->getName(); - } - return empty; + static std::string empty; + LLInventoryItem *item = gInventory.getItem(getAttachmentItemID()); + if (isAttachment() && item) + { + return item->getName(); + } + return empty; } //virtual @@ -7389,19 +7389,19 @@ LLVOAvatar* LLViewerObject::getAvatar() const { return getControlAvatar(); } - if (isAttachment()) - { - LLViewerObject* vobj = (LLViewerObject*) getParent(); + if (isAttachment()) + { + LLViewerObject* vobj = (LLViewerObject*) getParent(); - while (vobj && !vobj->asAvatar()) - { - vobj = (LLViewerObject*) vobj->getParent(); - } + while (vobj && !vobj->asAvatar()) + { + vobj = (LLViewerObject*) vobj->getParent(); + } - return (LLVOAvatar*) vobj; - } + return (LLVOAvatar*) vobj; + } - return NULL; + return NULL; } bool LLViewerObject::hasRenderMaterialParams() const @@ -7481,12 +7481,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat { new_material = gGLTFMaterialList.getMaterial(id); } - + // update local state for (S32 te = start_idx; te < end_idx; ++te) { LLTextureEntry* tep = getTE(te); - + // If local_origin=false (i.e. it's from the server), we know the // material has updated or been created, because extra params are // checked for equality on unpacking. In that case, checking the @@ -7495,7 +7495,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat bool material_changed = !local_origin || !param_block || id != param_block->getMaterial(te); if (update_server) - { + { // Clear most overrides so the render material better matches the material // ID (preserve transforms). If overrides become passthrough, set the overrides // to nullptr. @@ -7506,7 +7506,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat } if (update_server || material_changed) - { + { tep->setGLTFRenderMaterial(nullptr); } @@ -7623,53 +7623,53 @@ void LLViewerObject::shrinkWrap() class ObjectPhysicsProperties : public LLHTTPNode { public: - virtual void post( - ResponsePtr responder, - const LLSD& context, - const LLSD& input) const - { - LLSD object_data = input["body"]["ObjectData"]; - S32 num_entries = object_data.size(); - - for ( S32 i = 0; i < num_entries; i++ ) - { - LLSD& curr_object_data = object_data[i]; - U32 local_id = curr_object_data["LocalID"].asInteger(); - - // Iterate through nodes at end, since it can be on both the regular AND hover list - struct f : public LLSelectedNodeFunctor - { - U32 mID; - f(const U32& id) : mID(id) {} - virtual bool apply(LLSelectNode* node) - { - return (node->getObject() && node->getObject()->mLocalID == mID ); - } - } func(local_id); - - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); - - if (node) - { - // The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast - U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger(); - F32 density = (F32)curr_object_data["Density"].asReal(); - F32 friction = (F32)curr_object_data["Friction"].asReal(); - F32 restitution = (F32)curr_object_data["Restitution"].asReal(); - F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal(); - - node->getObject()->setPhysicsShapeType(type); - node->getObject()->setPhysicsGravity(gravity); - node->getObject()->setPhysicsFriction(friction); - node->getObject()->setPhysicsDensity(density); - node->getObject()->setPhysicsRestitution(restitution); - } - } - - dialog_refresh_all(); - }; + virtual void post( + ResponsePtr responder, + const LLSD& context, + const LLSD& input) const + { + LLSD object_data = input["body"]["ObjectData"]; + S32 num_entries = object_data.size(); + + for ( S32 i = 0; i < num_entries; i++ ) + { + LLSD& curr_object_data = object_data[i]; + U32 local_id = curr_object_data["LocalID"].asInteger(); + + // Iterate through nodes at end, since it can be on both the regular AND hover list + struct f : public LLSelectedNodeFunctor + { + U32 mID; + f(const U32& id) : mID(id) {} + virtual bool apply(LLSelectNode* node) + { + return (node->getObject() && node->getObject()->mLocalID == mID ); + } + } func(local_id); + + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); + + if (node) + { + // The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast + U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger(); + F32 density = (F32)curr_object_data["Density"].asReal(); + F32 friction = (F32)curr_object_data["Friction"].asReal(); + F32 restitution = (F32)curr_object_data["Restitution"].asReal(); + F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal(); + + node->getObject()->setPhysicsShapeType(type); + node->getObject()->setPhysicsGravity(gravity); + node->getObject()->setPhysicsFriction(friction); + node->getObject()->setPhysicsDensity(density); + node->getObject()->setPhysicsRestitution(restitution); + } + } + + dialog_refresh_all(); + }; }; LLHTTPRegistration - gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); + gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 64c1ee6633..a01e0b435f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,7 +47,7 @@ #include "llreflectionmap.h" #include "gltf/asset.h" -class LLAgent; // TODO: Get rid of this. +class LLAgent; // TODO: Get rid of this. class LLAudioSource; class LLAudioSourceVO; class LLColor4; @@ -76,112 +76,112 @@ class LLMeshCostData; typedef enum e_object_update_type { - OUT_FULL, - OUT_TERSE_IMPROVED, - OUT_FULL_COMPRESSED, - OUT_FULL_CACHED, - OUT_UNKNOWN, + OUT_FULL, + OUT_TERSE_IMPROVED, + OUT_FULL_COMPRESSED, + OUT_FULL_CACHED, + OUT_UNKNOWN, } EObjectUpdateType; // callback typedef for inventory typedef void (*inventory_callback)(LLViewerObject*, - LLInventoryObject::object_list_t*, - S32 serial_num, - void*); + LLInventoryObject::object_list_t*, + S32 serial_num, + void*); // for exporting textured materials from SL struct LLMaterialExportInfo { public: - LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) : - mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {}; + LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) : + mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {}; - S32 mMaterialIndex; - S32 mTextureIndex; - LLColor4 mColor; + S32 mMaterialIndex; + S32 mTextureIndex; + LLColor4 mColor; }; struct PotentialReturnableObject { - LLBBox box; - LLViewerRegion* pRegion; + LLBBox box; + LLViewerRegion* pRegion; }; //============================================================================ -class LLViewerObject -: public LLPrimitive, - public LLRefCount, - public LLGLUpdate +class LLViewerObject +: public LLPrimitive, + public LLRefCount, + public LLGLUpdate { protected: - virtual ~LLViewerObject(); // use unref() + virtual ~LLViewerObject(); // use unref() - // TomY: Provide for a list of extra parameter structures, mapped by structure name - struct ExtraParameter - { - BOOL in_use; - LLNetworkData *data; - }; - std::unordered_map mExtraParameterList; + // TomY: Provide for a list of extra parameter structures, mapped by structure name + struct ExtraParameter + { + BOOL in_use; + LLNetworkData *data; + }; + std::unordered_map mExtraParameterList; public: - typedef std::list > child_list_t; - typedef std::list > vobj_list_t; + typedef std::list > child_list_t; + typedef std::list > vobj_list_t; - typedef const child_list_t const_child_list_t; + typedef const child_list_t const_child_list_t; - LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE); + LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE); - virtual void markDead(); // Mark this object as dead, and clean up its references - BOOL isDead() const {return mDead;} - BOOL isOrphaned() const { return mOrphaned; } - BOOL isParticleSource() const; + virtual void markDead(); // Mark this object as dead, and clean up its references + BOOL isDead() const {return mDead;} + BOOL isOrphaned() const { return mOrphaned; } + BOOL isParticleSource() const; - virtual LLVOAvatar* asAvatar(); + virtual LLVOAvatar* asAvatar(); - LLVOAvatar* getAvatarAncestor(); + LLVOAvatar* getAvatarAncestor(); - static void initVOClasses(); - static void cleanupVOClasses(); + static void initVOClasses(); + static void cleanupVOClasses(); - void addNVPair(const std::string& data); - BOOL removeNVPair(const std::string& name); - LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name + void addNVPair(const std::string& data); + BOOL removeNVPair(const std::string& name); + LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name - // Object create and update functions - virtual void idleUpdate(LLAgent &agent, const F64 &time); + // Object create and update functions + virtual void idleUpdate(LLAgent &agent, const F64 &time); - // Types of media we can associate - enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; + // Types of media we can associate + enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; - // Return codes for processUpdateMessage - enum { - MEDIA_URL_REMOVED = 0x1, - MEDIA_URL_ADDED = 0x2, - MEDIA_URL_UPDATED = 0x4, + // Return codes for processUpdateMessage + enum { + MEDIA_URL_REMOVED = 0x1, + MEDIA_URL_ADDED = 0x2, + MEDIA_URL_UPDATED = 0x4, MEDIA_FLAGS_CHANGED = 0x8, INVALID_UPDATE = 0x80000000 }; - static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot); - virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, - const EObjectUpdateType update_type, - LLDataPacker *dp); + static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot); + virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp); + + virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate. + BOOL onActiveList() const {return mOnActiveList;} + void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; } - virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL onActiveList() const {return mOnActiveList;} - void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; } + virtual BOOL isAttachment() const { return FALSE; } + const std::string& getAttachmentItemName() const; - virtual BOOL isAttachment() const { return FALSE; } - const std::string& getAttachmentItemName() const; + virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment - virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment - bool hasRenderMaterialParams() const; void setHasRenderMaterialParams(bool has_params); @@ -194,431 +194,431 @@ public: void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true); void setRenderMaterialIDs(const LLUUID& id); - virtual BOOL isHUDAttachment() const { return FALSE; } - virtual BOOL isTempAttachment() const; + virtual BOOL isHUDAttachment() const { return FALSE; } + virtual BOOL isTempAttachment() const; + + virtual BOOL isHiglightedOrBeacon() const; - virtual BOOL isHiglightedOrBeacon() const; + virtual void updateRadius() {}; + virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() - virtual void updateRadius() {}; - virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() - - // for jointed and other parent-relative hacks - LLViewerObject* getSubParent(); - const LLViewerObject* getSubParent() const; - - // Object visiblility and GPW functions - virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area + // for jointed and other parent-relative hacks + LLViewerObject* getSubParent(); + const LLViewerObject* getSubParent() const; - virtual U32 getNumVertices() const; - virtual U32 getNumIndices() const; - S32 getNumFaces() const { return mNumFaces; } + // Object visiblility and GPW functions + virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area - // Graphical stuff for objects - maybe broken out into render class later? - virtual void updateTextures(); + virtual U32 getNumVertices() const; + virtual U32 getNumIndices() const; + S32 getNumFaces() const { return mNumFaces; } + + // Graphical stuff for objects - maybe broken out into render class later? + virtual void updateTextures(); virtual void faceMappingChanged() {} - virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object - - virtual LLDrawable* createDrawable(LLPipeline *pipeline); - virtual BOOL updateGeometry(LLDrawable *drawable); - virtual void updateGL(); - virtual void updateFaceSize(S32 idx); - virtual BOOL updateLOD(); - virtual BOOL setDrawableParent(LLDrawable* parentp); - F32 getRotTime() { return mRotTime; } + virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object + + virtual LLDrawable* createDrawable(LLPipeline *pipeline); + virtual BOOL updateGeometry(LLDrawable *drawable); + virtual void updateGL(); + virtual void updateFaceSize(S32 idx); + virtual BOOL updateLOD(); + virtual BOOL setDrawableParent(LLDrawable* parentp); + F32 getRotTime() { return mRotTime; } private: - void resetRotTime(); - void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin); + void resetRotTime(); + void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin); void rebuildMaterial(); public: - void resetRot(); - void applyAngularVelocity(F32 dt); + void resetRot(); + void applyAngularVelocity(F32 dt); - void setLineWidthForWindowSize(S32 window_width); + void setLineWidthForWindowSize(S32 window_width); - static void increaseArrowLength(); // makes axis arrows for selections longer - static void decreaseArrowLength(); // makes axis arrows for selections shorter + static void increaseArrowLength(); // makes axis arrows for selections longer + static void decreaseArrowLength(); // makes axis arrows for selections shorter - // Accessor functions - LLViewerRegion* getRegion() const { return mRegionp; } + // Accessor functions + LLViewerRegion* getRegion() const { return mRegionp; } - BOOL isSelected() const { return mUserSelected; } + BOOL isSelected() const { return mUserSelected; } // Check whole linkset BOOL isAnySelected() const; - virtual void setSelected(BOOL sel); - - const LLUUID &getID() const { return mID; } - U32 getLocalID() const { return mLocalID; } - U32 getCRC() const { return mTotalCRC; } - S32 getListIndex() const { return mListIndex; } - void setListIndex(S32 idx) { mListIndex = idx; } - - virtual BOOL isFlexible() const { return FALSE; } - virtual BOOL isSculpted() const { return FALSE; } - virtual BOOL isMesh() const { return FALSE; } - virtual BOOL isRiggedMesh() const { return FALSE; } - virtual BOOL hasLightTexture() const { return FALSE; } + virtual void setSelected(BOOL sel); + + const LLUUID &getID() const { return mID; } + U32 getLocalID() const { return mLocalID; } + U32 getCRC() const { return mTotalCRC; } + S32 getListIndex() const { return mListIndex; } + void setListIndex(S32 idx) { mListIndex = idx; } + + virtual BOOL isFlexible() const { return FALSE; } + virtual BOOL isSculpted() const { return FALSE; } + virtual BOOL isMesh() const { return FALSE; } + virtual BOOL isRiggedMesh() const { return FALSE; } + virtual BOOL hasLightTexture() const { return FALSE; } virtual BOOL isReflectionProbe() const { return FALSE; } - // This method returns true if the object is over land owned by - // the agent, one of its groups, or it encroaches and - // anti-encroachment is enabled - bool isReturnable(); + // This method returns true if the object is over land owned by + // the agent, one of its groups, or it encroaches and + // anti-encroachment is enabled + bool isReturnable(); - void buildReturnablesForChildrenVO( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); - void constructAndAddReturnable( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); + void buildReturnablesForChildrenVO( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); + void constructAndAddReturnable( std::vector& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); - // This method returns true if the object crosses - // any parcel bounds in the region. - bool crossesParcelBounds(); + // This method returns true if the object crosses + // any parcel bounds in the region. + bool crossesParcelBounds(); - /* - // This method will scan through this object, and then query the - // selection manager to see if the local agent probably has the - // ability to modify the object. Since this calls into the - // selection manager, you should avoid calling this method from - // there. - BOOL isProbablyModifiable() const; - */ + /* + // This method will scan through this object, and then query the + // selection manager to see if the local agent probably has the + // ability to modify the object. Since this calls into the + // selection manager, you should avoid calling this method from + // there. + BOOL isProbablyModifiable() const; + */ - virtual BOOL setParent(LLViewerObject* parent); + virtual BOOL setParent(LLViewerObject* parent); virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent); virtual void afterReparent(); - virtual void addChild(LLViewerObject *childp); - virtual void removeChild(LLViewerObject *childp); - const_child_list_t& getChildren() const { return mChildList; } - S32 numChildren() const { return mChildList.size(); } - void addThisAndAllChildren(std::vector& objects); - void addThisAndNonJointChildren(std::vector& objects); - BOOL isChild(LLViewerObject *childp) const; - BOOL isSeat() const; - - - //detect if given line segment (in agent space) intersects with this viewer object. - //returns TRUE if intersection detected and returns information about intersection - virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face = -1, // which face to check, -1 = ALL_SIDES - BOOL pick_transparent = FALSE, - BOOL pick_rigged = FALSE, + virtual void addChild(LLViewerObject *childp); + virtual void removeChild(LLViewerObject *childp); + const_child_list_t& getChildren() const { return mChildList; } + S32 numChildren() const { return mChildList.size(); } + void addThisAndAllChildren(std::vector& objects); + void addThisAndNonJointChildren(std::vector& objects); + BOOL isChild(LLViewerObject *childp) const; + BOOL isSeat() const; + + + //detect if given line segment (in agent space) intersects with this viewer object. + //returns TRUE if intersection detected and returns information about intersection + virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + BOOL pick_transparent = FALSE, + BOOL pick_rigged = FALSE, BOOL pick_unselectable = TRUE, - S32* face_hit = NULL, // which face was hit - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ); - - virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end); - - virtual const LLVector3d getPositionGlobal() const; - virtual const LLVector3 &getPositionRegion() const; - virtual const LLVector3 getPositionEdit() const; - virtual const LLVector3 &getPositionAgent() const; - virtual const LLVector3 getRenderPosition() const; + S32* face_hit = NULL, // which face was hit + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ); + + virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end); + + virtual const LLVector3d getPositionGlobal() const; + virtual const LLVector3 &getPositionRegion() const; + virtual const LLVector3 getPositionEdit() const; + virtual const LLVector3 &getPositionAgent() const; + virtual const LLVector3 getRenderPosition() const; LLMatrix4a getAgentToGLTFAssetTransform() const; LLMatrix4a getGLTFAssetToAgentTransform() const; LLVector3 getGLTFNodePositionAgent(S32 node_index) const; LLMatrix4a getGLTFNodeTransformAgent(S32 node_index) const; void getGLTFNodeTransformAgent(S32 node_index, LLVector3* position, LLQuaternion* rotation, LLVector3* scale) const; - + // move the node at the given index by the given offset in agent space void moveGLTFNode(S32 node_index, const LLVector3& offset); // set the rotation in agent space of the given node void setGLTFNodeRotationAgent(S32 node_index, const LLQuaternion& rotation); - virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not + virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not - LLViewerObject* getRootEdit() const; + LLViewerObject* getRootEdit() const; - const LLQuaternion getRotationRegion() const; - const LLQuaternion getRotationEdit() const; - const LLQuaternion getRenderRotation() const; - virtual const LLMatrix4 getRenderMatrix() const; + const LLQuaternion getRotationRegion() const; + const LLQuaternion getRotationEdit() const; + const LLQuaternion getRenderRotation() const; + virtual const LLMatrix4 getRenderMatrix() const; - void setPosition(const LLVector3 &pos, BOOL damped = FALSE); - void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE); - void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE); - void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE); - void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE); - void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE); - void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE ); + void setPosition(const LLVector3 &pos, BOOL damped = FALSE); + void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE); + void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE); + void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE); + void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE); + void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE); + void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE ); - virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); } + virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); } - inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE); - inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE); + inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE); + inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE); - /*virtual*/ void setNumTEs(const U8 num_tes); - /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); + /*virtual*/ void setNumTEs(const U8 num_tes); + /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); void updateTEMaterialTextures(U8 te); - /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); - /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid); - /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid); - S32 setTETextureCore(const U8 te, LLViewerTexture *image); - S32 setTENormalMapCore(const U8 te, LLViewerTexture *image); - S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image); - /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); - /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); - /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); - /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); - /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); - /*virtual*/ S32 setTEOffset(const U8 te, const F32 s, const F32 t); - /*virtual*/ S32 setTEOffsetS(const U8 te, const F32 s); - /*virtual*/ S32 setTEOffsetT(const U8 te, const F32 t); - /*virtual*/ S32 setTERotation(const U8 te, const F32 r); - /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump ); - /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen ); - /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics - /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny ); - /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright ); - /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); - /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); - /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); - /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); + /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); + /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid); + /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid); + S32 setTETextureCore(const U8 te, LLViewerTexture *image); + S32 setTENormalMapCore(const U8 te, LLViewerTexture *image); + S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image); + /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); + /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); + /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); + /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); + /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); + /*virtual*/ S32 setTEOffset(const U8 te, const F32 s, const F32 t); + /*virtual*/ S32 setTEOffsetS(const U8 te, const F32 s); + /*virtual*/ S32 setTEOffsetT(const U8 te, const F32 t); + /*virtual*/ S32 setTERotation(const U8 te, const F32 r); + /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump ); + /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen ); + /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics + /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny ); + /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright ); + /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); + /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); + /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); + /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat); - // Used by Materials update functions to properly kick off rebuilds - // of VBs etc when materials updates require changes. - // - void refreshMaterials(); + // Used by Materials update functions to properly kick off rebuilds + // of VBs etc when materials updates require changes. + // + void refreshMaterials(); + + /*virtual*/ BOOL setMaterial(const U8 material); + virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive + virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ; + virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ; + virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ; + LLViewerTexture *getTEImage(const U8 te) const; + LLViewerTexture *getTENormalMap(const U8 te) const; + LLViewerTexture *getTESpecularMap(const U8 te) const; - /*virtual*/ BOOL setMaterial(const U8 material); - virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive - virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ; - virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ; - virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ; - LLViewerTexture *getTEImage(const U8 te) const; - LLViewerTexture *getTENormalMap(const U8 te) const; - LLViewerTexture *getTESpecularMap(const U8 te) const; + bool isImageAlphaBlended(const U8 te) const; - bool isImageAlphaBlended(const U8 te) const; + void fitFaceTexture(const U8 face); + void sendTEUpdate() const; // Sends packed representation of all texture entry information - void fitFaceTexture(const U8 face); - void sendTEUpdate() const; // Sends packed representation of all texture entry information - - virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); + virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); S32 getAnimatedObjectMaxTris() const; F32 recursiveGetEstTrianglesMax() const; virtual F32 getEstTrianglesMax() const; virtual F32 getEstTrianglesStreamingCost() const; - virtual F32 getStreamingCost() const; + virtual F32 getStreamingCost() const; virtual bool getCostData(LLMeshCostData& costs) const; - virtual U32 getTriangleCount(S32* vcount = NULL) const; - virtual U32 getHighLODTriangleCount(); + virtual U32 getTriangleCount(S32* vcount = NULL) const; + virtual U32 getHighLODTriangleCount(); F32 recursiveGetScaledSurfaceArea() const; U32 recursiveGetTriangleCount(S32* vcount = NULL) const; - void setObjectCost(F32 cost); - F32 getObjectCost(); - - void setLinksetCost(F32 cost); - F32 getLinksetCost(); - - void setPhysicsCost(F32 cost); - F32 getPhysicsCost(); - - void setLinksetPhysicsCost(F32 cost); - F32 getLinksetPhysicsCost(); - - void sendShapeUpdate(); - - U8 getAttachmentState() { return mAttachmentState; } - - F32 getAppAngle() const { return mAppAngle; } - F32 getPixelArea() const { return mPixelArea; } - void setPixelArea(F32 area) { mPixelArea = area; } - F32 getMaxScale() const; - F32 getMidScale() const; - F32 getMinScale() const; - - // Owner id is this object's owner - void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags); - void adjustAudioGain(const F32 gain); - F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; } - void clearAttachedSound() { mAudioSourcep = NULL; } - - // Create if necessary - LLAudioSource *getAudioSource(const LLUUID& owner_id); - BOOL isAudioSource() const {return mAudioSourcep != NULL;} - - U8 getMediaType() const; - void setMediaType(U8 media_type); - - std::string getMediaURL() const; - void setMediaURL(const std::string& media_url); - - BOOL getMediaPassedWhitelist() const; - void setMediaPassedWhitelist(BOOL passed); - - void sendMaterialUpdate() const; - - void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white); - void appendDebugText(const std::string &utf8text); - void initHudText(); - void restoreHudText(); - void setIcon(LLViewerTexture* icon_image); - void clearIcon(); + void setObjectCost(F32 cost); + F32 getObjectCost(); + + void setLinksetCost(F32 cost); + F32 getLinksetCost(); + + void setPhysicsCost(F32 cost); + F32 getPhysicsCost(); + + void setLinksetPhysicsCost(F32 cost); + F32 getLinksetPhysicsCost(); + + void sendShapeUpdate(); + + U8 getAttachmentState() { return mAttachmentState; } + + F32 getAppAngle() const { return mAppAngle; } + F32 getPixelArea() const { return mPixelArea; } + void setPixelArea(F32 area) { mPixelArea = area; } + F32 getMaxScale() const; + F32 getMidScale() const; + F32 getMinScale() const; + + // Owner id is this object's owner + void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags); + void adjustAudioGain(const F32 gain); + F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; } + void clearAttachedSound() { mAudioSourcep = NULL; } + + // Create if necessary + LLAudioSource *getAudioSource(const LLUUID& owner_id); + BOOL isAudioSource() const {return mAudioSourcep != NULL;} + + U8 getMediaType() const; + void setMediaType(U8 media_type); + + std::string getMediaURL() const; + void setMediaURL(const std::string& media_url); + + BOOL getMediaPassedWhitelist() const; + void setMediaPassedWhitelist(BOOL passed); + + void sendMaterialUpdate() const; + + void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white); + void appendDebugText(const std::string &utf8text); + void initHudText(); + void restoreHudText(); + void setIcon(LLViewerTexture* icon_image); + void clearIcon(); void recursiveMarkForUpdate(); - virtual void markForUpdate(); - void updateVolume(const LLVolumeParams& volume_params); - virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); - virtual F32 getBinRadius(); - - LLBBox getBoundingBoxAgent() const; - - void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform. - void updateText(); // update text label position - virtual void updateDrawable(BOOL force_damped); // force updates on static objects - - bool isOwnerInMuteList(LLUUID item_id = LLUUID()); - - void setDrawableState(U32 state, BOOL recursive = TRUE); - void clearDrawableState(U32 state, BOOL recursive = TRUE); - BOOL isDrawableState(U32 state, BOOL recursive = TRUE) const; - - // Called when the drawable shifts - virtual void onShift(const LLVector4a &shift_vector) { } - - ////////////////////////////////////// - // - // Inventory methods - // - - // This function is called when someone is interested in a viewer - // object's inventory. The callback is called as soon as the - // viewer object has the inventory stored locally. - void registerInventoryListener(LLVOInventoryListener* listener, void* user_data); - void removeInventoryListener(LLVOInventoryListener* listener); - BOOL isInventoryPending(); - void clearInventoryListeners(); - bool hasInventoryListeners(); - void requestInventory(); - static void processTaskInv(LLMessageSystem* msg, void** user_data); - void removeInventory(const LLUUID& item_id); - - // The updateInventory() call potentially calls into the selection - // manager, so do no call updateInventory() from the selection - // manager until we have better iterators. - void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new); - void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging. - void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new); - LLInventoryObject* getInventoryObject(const LLUUID& item_id); - LLInventoryItem* getInventoryItem(const LLUUID& item_id); - - // Get content except for root category - void getInventoryContents(LLInventoryObject::object_list_t& objects); - LLInventoryObject* getInventoryRoot(); - LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id); + virtual void markForUpdate(); + void updateVolume(const LLVolumeParams& volume_params); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); + virtual F32 getBinRadius(); + + LLBBox getBoundingBoxAgent() const; + + void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform. + void updateText(); // update text label position + virtual void updateDrawable(BOOL force_damped); // force updates on static objects + + bool isOwnerInMuteList(LLUUID item_id = LLUUID()); + + void setDrawableState(U32 state, BOOL recursive = TRUE); + void clearDrawableState(U32 state, BOOL recursive = TRUE); + BOOL isDrawableState(U32 state, BOOL recursive = TRUE) const; + + // Called when the drawable shifts + virtual void onShift(const LLVector4a &shift_vector) { } + + ////////////////////////////////////// + // + // Inventory methods + // + + // This function is called when someone is interested in a viewer + // object's inventory. The callback is called as soon as the + // viewer object has the inventory stored locally. + void registerInventoryListener(LLVOInventoryListener* listener, void* user_data); + void removeInventoryListener(LLVOInventoryListener* listener); + BOOL isInventoryPending(); + void clearInventoryListeners(); + bool hasInventoryListeners(); + void requestInventory(); + static void processTaskInv(LLMessageSystem* msg, void** user_data); + void removeInventory(const LLUUID& item_id); + + // The updateInventory() call potentially calls into the selection + // manager, so do no call updateInventory() from the selection + // manager until we have better iterators. + void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new); + void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging. + void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new); + LLInventoryObject* getInventoryObject(const LLUUID& item_id); + LLInventoryItem* getInventoryItem(const LLUUID& item_id); + + // Get content except for root category + void getInventoryContents(LLInventoryObject::object_list_t& objects); + LLInventoryObject* getInventoryRoot(); + LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id); LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type); - S16 getInventorySerial() const { return mInventorySerialNum; } - - // These functions does viewer-side only object inventory modifications - void updateViewerInventoryAsset( - const LLViewerInventoryItem* item, - const LLUUID& new_asset); - - // This function will make sure that we refresh the inventory. - void dirtyInventory(); - BOOL isInventoryDirty() { return mInventoryDirty; } - - // save a script, which involves removing the old one, and rezzing - // in the new one. This method should be called with the asset id - // of the new and old script AFTER the bytecode has been saved. - void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new); - - // move an inventory item out of the task and into agent - // inventory. This operation is based on messaging. No permissions - // checks are made on the viewer - the server will double check. - void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id); - - // Find the number of instances of this object's inventory that are of the given type - S32 countInventoryContents( LLAssetType::EType type ); - - BOOL permAnyOwner() const; - BOOL permYouOwner() const; - BOOL permGroupOwner() const; - BOOL permOwnerModify() const; - BOOL permModify() const; - BOOL permCopy() const; - BOOL permMove() const; - BOOL permTransfer() const; - inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); } - inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); } - inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); } - inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); } - inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); } - inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); } - inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); } - inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } - inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); } - inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); } - inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); } - inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); } - inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); } - inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); } - inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); } - inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); } - inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); } - inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); } - inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); } - inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); } - inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); } - inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); } - inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } - - U8 getPhysicsShapeType() const; - inline F32 getPhysicsGravity() const { return mPhysicsGravity; } - inline F32 getPhysicsFriction() const { return mPhysicsFriction; } - inline F32 getPhysicsDensity() const { return mPhysicsDensity; } - inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; } - - bool isPermanentEnforced() const; - - bool getIncludeInSearch() const; - void setIncludeInSearch(bool include_in_search); - - // Does "open" object menu item apply? - BOOL allowOpen() const; - - void setClickAction(U8 action) { mClickAction = action; } - U8 getClickAction() const { return mClickAction; } - bool specialHoverCursor() const; // does it have a special hover cursor? - - void setRegion(LLViewerRegion *regionp); - virtual void updateRegion(LLViewerRegion *regionp); - - void updateFlags(BOOL physics_changed = FALSE); - void loadFlags(U32 flags); //load flags from cache or from message - BOOL setFlags(U32 flag, BOOL state); - BOOL setFlagsWithoutUpdate(U32 flag, BOOL state); - void setPhysicsShapeType(U8 type); - void setPhysicsGravity(F32 gravity); - void setPhysicsFriction(F32 friction); - void setPhysicsDensity(F32 density); - void setPhysicsRestitution(F32 restitution); - - virtual void dump() const; - static U32 getNumZombieObjects() { return sNumZombieObjects; } - - void printNameValuePairs() const; - - virtual S32 getLOD() const { return 3; } - virtual U32 getPartitionType() const; - void dirtySpatialGroup() const; - virtual void dirtyMesh(); - - virtual LLNetworkData* getParameterEntry(U16 param_type) const; - virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin); - virtual BOOL getParameterEntryInUse(U16 param_type) const; - virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin); - // Called when a parameter is changed - virtual void parameterChanged(U16 param_type, bool local_origin); - virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); - + S16 getInventorySerial() const { return mInventorySerialNum; } + + // These functions does viewer-side only object inventory modifications + void updateViewerInventoryAsset( + const LLViewerInventoryItem* item, + const LLUUID& new_asset); + + // This function will make sure that we refresh the inventory. + void dirtyInventory(); + BOOL isInventoryDirty() { return mInventoryDirty; } + + // save a script, which involves removing the old one, and rezzing + // in the new one. This method should be called with the asset id + // of the new and old script AFTER the bytecode has been saved. + void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new); + + // move an inventory item out of the task and into agent + // inventory. This operation is based on messaging. No permissions + // checks are made on the viewer - the server will double check. + void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id); + + // Find the number of instances of this object's inventory that are of the given type + S32 countInventoryContents( LLAssetType::EType type ); + + BOOL permAnyOwner() const; + BOOL permYouOwner() const; + BOOL permGroupOwner() const; + BOOL permOwnerModify() const; + BOOL permModify() const; + BOOL permCopy() const; + BOOL permMove() const; + BOOL permTransfer() const; + inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); } + inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); } + inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); } + inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); } + inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); } + inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); } + inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); } + inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } + inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); } + inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); } + inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); } + inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); } + inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); } + inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); } + inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); } + inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); } + inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); } + inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); } + inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); } + inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); } + inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); } + inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); } + inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } + + U8 getPhysicsShapeType() const; + inline F32 getPhysicsGravity() const { return mPhysicsGravity; } + inline F32 getPhysicsFriction() const { return mPhysicsFriction; } + inline F32 getPhysicsDensity() const { return mPhysicsDensity; } + inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; } + + bool isPermanentEnforced() const; + + bool getIncludeInSearch() const; + void setIncludeInSearch(bool include_in_search); + + // Does "open" object menu item apply? + BOOL allowOpen() const; + + void setClickAction(U8 action) { mClickAction = action; } + U8 getClickAction() const { return mClickAction; } + bool specialHoverCursor() const; // does it have a special hover cursor? + + void setRegion(LLViewerRegion *regionp); + virtual void updateRegion(LLViewerRegion *regionp); + + void updateFlags(BOOL physics_changed = FALSE); + void loadFlags(U32 flags); //load flags from cache or from message + BOOL setFlags(U32 flag, BOOL state); + BOOL setFlagsWithoutUpdate(U32 flag, BOOL state); + void setPhysicsShapeType(U8 type); + void setPhysicsGravity(F32 gravity); + void setPhysicsFriction(F32 friction); + void setPhysicsDensity(F32 density); + void setPhysicsRestitution(F32 restitution); + + virtual void dump() const; + static U32 getNumZombieObjects() { return sNumZombieObjects; } + + void printNameValuePairs() const; + + virtual S32 getLOD() const { return 3; } + virtual U32 getPartitionType() const; + void dirtySpatialGroup() const; + virtual void dirtyMesh(); + + virtual LLNetworkData* getParameterEntry(U16 param_type) const; + virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin); + virtual BOOL getParameterEntryInUse(U16 param_type) const; + virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin); + // Called when a parameter is changed + virtual void parameterChanged(U16 param_type, bool local_origin); + virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); + bool isShrinkWrapped() const { return mShouldShrinkWrap; } // Used to improve performance. If an object is likely to rebuild its vertex buffer often @@ -627,139 +627,139 @@ public: // so that nearby objects won't attempt to share a vertex buffer with this object. void shrinkWrap(); - friend class LLViewerObjectList; - friend class LLViewerMediaList; + friend class LLViewerObjectList; + friend class LLViewerMediaList; public: - LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id); - void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id); - void refreshBakeTexture(); + LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id); + void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id); + void refreshBakeTexture(); public: - static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); - static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); - static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); - static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name); - static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id); + static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); + static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); + static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); + static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name); + static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id); public: - //counter-translation - void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE, BOOL skip_avatar_child = FALSE) ; - //counter-rotation - void resetChildrenRotationAndPosition(const std::vector& rotations, - const std::vector& positions) ; - void saveUnselectedChildrenRotation(std::vector& rotations) ; - void saveUnselectedChildrenPosition(std::vector& positions) ; - std::vector mUnselectedChildrenPositions ; + //counter-translation + void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE, BOOL skip_avatar_child = FALSE) ; + //counter-rotation + void resetChildrenRotationAndPosition(const std::vector& rotations, + const std::vector& positions) ; + void saveUnselectedChildrenRotation(std::vector& rotations) ; + void saveUnselectedChildrenPosition(std::vector& positions) ; + std::vector mUnselectedChildrenPositions ; private: void setObjectCostStale(); bool isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type); - ExtraParameter* createNewParameterEntry(U16 param_type); - ExtraParameter* getExtraParameterEntry(U16 param_type) const; - ExtraParameter* getExtraParameterEntryCreate(U16 param_type); - bool unpackParameterEntry(U16 param_type, LLDataPacker *dp); + ExtraParameter* createNewParameterEntry(U16 param_type); + ExtraParameter* getExtraParameterEntry(U16 param_type) const; + ExtraParameter* getExtraParameterEntryCreate(U16 param_type); + bool unpackParameterEntry(U16 param_type, LLDataPacker *dp); // This function checks to see if the given media URL has changed its version // and the update wasn't due to this agent's last action. U32 checkMediaURL(const std::string &media_url); - - // Motion prediction between updates - void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt); - static void initObjectDataMap(); + // Motion prediction between updates + void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt); + + static void initObjectDataMap(); - // forms task inventory request if none are pending, marks request as pending - void fetchInventoryFromServer(); + // forms task inventory request if none are pending, marks request as pending + void fetchInventoryFromServer(); - // forms task inventory request after some time passed, marks request as pending - void fetchInventoryDelayed(const F64 &time_seconds); - static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds); + // forms task inventory request after some time passed, marks request as pending + void fetchInventoryDelayed(const F64 &time_seconds); + static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds); public: - // - // Viewer-side only types - use the LL_PCODE_APP mask. - // - typedef enum e_vo_types - { - LL_VO_CLOUDS = LL_PCODE_APP | 0x20, // no longer used - LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30, - LL_VO_WL_SKY = LL_PCODE_APP | 0x40, - LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50, - LL_VO_SKY = LL_PCODE_APP | 0x60, - LL_VO_VOID_WATER = LL_PCODE_APP | 0x70, - LL_VO_WATER = LL_PCODE_APP | 0x80, - LL_VO_PART_GROUP = LL_PCODE_APP | 0xa0, - LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xb0, - LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0, - } EVOType; - - typedef enum e_physics_shape_types - { - PHYSICS_SHAPE_PRIM = 0, - PHYSICS_SHAPE_NONE, - PHYSICS_SHAPE_CONVEX_HULL, - } EPhysicsShapeType; - - LLUUID mID; - LLUUID mOwnerID; //null if unknown - - // unique within region, not unique across regions - // Local ID = 0 is not used - U32 mLocalID; - - // Last total CRC received from sim, used for caching - U32 mTotalCRC; - - // index into LLViewerObjectList::mActiveObjects or -1 if not in list - S32 mListIndex; - - LLPointer *mTEImages; - LLPointer *mTENormalMaps; - LLPointer *mTESpecularMaps; - + // + // Viewer-side only types - use the LL_PCODE_APP mask. + // + typedef enum e_vo_types + { + LL_VO_CLOUDS = LL_PCODE_APP | 0x20, // no longer used + LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30, + LL_VO_WL_SKY = LL_PCODE_APP | 0x40, + LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50, + LL_VO_SKY = LL_PCODE_APP | 0x60, + LL_VO_VOID_WATER = LL_PCODE_APP | 0x70, + LL_VO_WATER = LL_PCODE_APP | 0x80, + LL_VO_PART_GROUP = LL_PCODE_APP | 0xa0, + LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xb0, + LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0, + } EVOType; + + typedef enum e_physics_shape_types + { + PHYSICS_SHAPE_PRIM = 0, + PHYSICS_SHAPE_NONE, + PHYSICS_SHAPE_CONVEX_HULL, + } EPhysicsShapeType; + + LLUUID mID; + LLUUID mOwnerID; //null if unknown + + // unique within region, not unique across regions + // Local ID = 0 is not used + U32 mLocalID; + + // Last total CRC received from sim, used for caching + U32 mTotalCRC; + + // index into LLViewerObjectList::mActiveObjects or -1 if not in list + S32 mListIndex; + + LLPointer *mTEImages; + LLPointer *mTENormalMaps; + LLPointer *mTESpecularMaps; + // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out - BOOL mbCanSelect; + BOOL mbCanSelect; private: - // Grabbed from UPDATE_FLAGS - U32 mFlags; + // Grabbed from UPDATE_FLAGS + U32 mFlags; - static std::map sObjectDataMap; + static std::map sObjectDataMap; public: - // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties - U8 mPhysicsShapeType; - F32 mPhysicsGravity; - F32 mPhysicsFriction; - F32 mPhysicsDensity; - F32 mPhysicsRestitution; - + // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties + U8 mPhysicsShapeType; + F32 mPhysicsGravity; + F32 mPhysicsFriction; + F32 mPhysicsDensity; + F32 mPhysicsRestitution; + // Associated GLTF Asset LLPointer mGLTFAsset; - // Pipeline classes - LLPointer mDrawable; + // Pipeline classes + LLPointer mDrawable; - // Band-aid to select object after all creation initialization is done - BOOL mCreateSelected; + // Band-aid to select object after all creation initialization is done + BOOL mCreateSelected; - // Replace textures with web pages on this object while drawing - BOOL mRenderMedia; + // Replace textures with web pages on this object while drawing + BOOL mRenderMedia; bool mRiggedAttachedWarned; - // In bits - S32 mBestUpdatePrecision; + // In bits + S32 mBestUpdatePrecision; - // TODO: Make all this stuff private. JC - LLPointer mText; - LLPointer mIcon; + // TODO: Make all this stuff private. JC + LLPointer mText; + LLPointer mIcon; - std::string mHudText; - LLColor4 mHudTextColor; + std::string mHudText; + LLColor4 mHudTextColor; - static BOOL sUseSharedDrawables; + static BOOL sUseSharedDrawables; public: // Returns mControlAvatar for the edit root prim of this linkset @@ -783,177 +783,177 @@ protected: LLPointer mControlAvatar; protected: - // delete an item in the inventory, but don't tell the - // server. This is used internally by remove, update, and - // savescript. - void deleteInventoryItem(const LLUUID& item_id); - - // do the update/caching logic. called by saveScript and - // updateInventory. - void doUpdateInventory(LLPointer& item, U8 key, bool is_new); - - static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); - - BOOL setData(const U8 *datap, const U32 data_size); - - // Hide or show HUD, icon and particles - void hideExtraDisplayItems( BOOL hidden ); - - ////////////////////////// - // - // inventory functionality - // - - static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status); - BOOL loadTaskInvFile(const std::string& filename); - void doInventoryCallback(); - - BOOL isOnMap(); - - void unpackParticleSource(const S32 block_num, const LLUUID& owner_id); - void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy); - void deleteParticleSource(); - void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); - + // delete an item in the inventory, but don't tell the + // server. This is used internally by remove, update, and + // savescript. + void deleteInventoryItem(const LLUUID& item_id); + + // do the update/caching logic. called by saveScript and + // updateInventory. + void doUpdateInventory(LLPointer& item, U8 key, bool is_new); + + static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); + + BOOL setData(const U8 *datap, const U32 data_size); + + // Hide or show HUD, icon and particles + void hideExtraDisplayItems( BOOL hidden ); + + ////////////////////////// + // + // inventory functionality + // + + static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status); + BOOL loadTaskInvFile(const std::string& filename); + void doInventoryCallback(); + + BOOL isOnMap(); + + void unpackParticleSource(const S32 block_num, const LLUUID& owner_id); + void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy); + void deleteParticleSource(); + void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); + private: - void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string - void deleteTEImages(); // correctly deletes list of images - + void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string + void deleteTEImages(); // correctly deletes list of images + protected: - typedef std::map name_value_map_t; - name_value_map_t mNameValuePairs; // Any name-value pairs stored by script - - child_list_t mChildList; - - F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation - F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator - TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator - F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time - - // extra data sent from the sim...currently only used for tree species info - U8* mData; - - LLPointer mPartSourcep; // Particle source associated with this object. - LLAudioSourceVO* mAudioSourcep; - F32 mAudioGain; - F32 mSoundCutOffRadius; - - F32 mAppAngle; // Apparent visual arc in degrees - F32 mPixelArea; // Apparent area in pixels - - // IDs of of all items in the object's content which are added to the object's content, - // but not updated on the server yet. After item was updated, its ID will be removed from this list. - std::list mPendingInventoryItemsIDs; - - // This is the object's inventory from the viewer's perspective. - LLInventoryObject::object_list_t* mInventory; - class LLInventoryCallbackInfo - { - public: - ~LLInventoryCallbackInfo(); - LLVOInventoryListener* mListener; - void* mInventoryData; - }; - typedef std::list callback_list_t; - callback_list_t mInventoryCallbacks; - S16 mInventorySerialNum; - S16 mExpectedInventorySerialNum; - - enum EInventoryRequestState - { - INVENTORY_REQUEST_STOPPED, - INVENTORY_REQUEST_WAIT, // delay before requesting - INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer() - INVENTORY_XFER // processed response from 'fetch', now doing an xfer - }; - EInventoryRequestState mInvRequestState; - U64 mInvRequestXFerId; - BOOL mInventoryDirty; - - LLViewerRegion *mRegionp; // Region that this object belongs to. - BOOL mDead; - BOOL mOrphaned; // This is an orphaned child - BOOL mUserSelected; // Cached user select information - BOOL mOnActiveList; - BOOL mOnMap; // On the map. - BOOL mStatic; // Object doesn't move. - S32 mSeatCount; - S32 mNumFaces; - - F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) - LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations - LLQuaternion mPreviousRotation; - - U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment. - LLViewerObjectMedia* mMedia; // NULL if no media associated - U8 mClickAction; - F32 mObjectCost; //resource cost of this object or -1 if unknown - F32 mLinksetCost; - F32 mPhysicsCost; - F32 mLinksetPhysicsCost; - + typedef std::map name_value_map_t; + name_value_map_t mNameValuePairs; // Any name-value pairs stored by script + + child_list_t mChildList; + + F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation + F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator + TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator + F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time + + // extra data sent from the sim...currently only used for tree species info + U8* mData; + + LLPointer mPartSourcep; // Particle source associated with this object. + LLAudioSourceVO* mAudioSourcep; + F32 mAudioGain; + F32 mSoundCutOffRadius; + + F32 mAppAngle; // Apparent visual arc in degrees + F32 mPixelArea; // Apparent area in pixels + + // IDs of of all items in the object's content which are added to the object's content, + // but not updated on the server yet. After item was updated, its ID will be removed from this list. + std::list mPendingInventoryItemsIDs; + + // This is the object's inventory from the viewer's perspective. + LLInventoryObject::object_list_t* mInventory; + class LLInventoryCallbackInfo + { + public: + ~LLInventoryCallbackInfo(); + LLVOInventoryListener* mListener; + void* mInventoryData; + }; + typedef std::list callback_list_t; + callback_list_t mInventoryCallbacks; + S16 mInventorySerialNum; + S16 mExpectedInventorySerialNum; + + enum EInventoryRequestState + { + INVENTORY_REQUEST_STOPPED, + INVENTORY_REQUEST_WAIT, // delay before requesting + INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer() + INVENTORY_XFER // processed response from 'fetch', now doing an xfer + }; + EInventoryRequestState mInvRequestState; + U64 mInvRequestXFerId; + BOOL mInventoryDirty; + + LLViewerRegion *mRegionp; // Region that this object belongs to. + BOOL mDead; + BOOL mOrphaned; // This is an orphaned child + BOOL mUserSelected; // Cached user select information + BOOL mOnActiveList; + BOOL mOnMap; // On the map. + BOOL mStatic; // Object doesn't move. + S32 mSeatCount; + S32 mNumFaces; + + F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) + LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations + LLQuaternion mPreviousRotation; + + U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment. + LLViewerObjectMedia* mMedia; // NULL if no media associated + U8 mClickAction; + F32 mObjectCost; //resource cost of this object or -1 if unknown + F32 mLinksetCost; + F32 mPhysicsCost; + F32 mLinksetPhysicsCost; + // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap" bool mShouldShrinkWrap = false; - bool mCostStale; - mutable bool mPhysicsShapeUnknown; + bool mCostStale; + mutable bool mPhysicsShapeUnknown; - static U32 sNumZombieObjects; // Objects which are dead, but not deleted + static U32 sNumZombieObjects; // Objects which are dead, but not deleted - static BOOL sMapDebug; // Map render mode - static LLColor4 sEditSelectColor; - static LLColor4 sNoEditSelectColor; - static F32 sCurrentPulse; - static BOOL sPulseEnabled; + static BOOL sMapDebug; // Map render mode + static LLColor4 sEditSelectColor; + static LLColor4 sNoEditSelectColor; + static F32 sCurrentPulse; + static BOOL sPulseEnabled; - static S32 sAxisArrowLength; + static S32 sAxisArrowLength; - // These two caches are only correct for non-parented objects right now! - mutable LLVector3 mPositionRegion; - mutable LLVector3 mPositionAgent; + // These two caches are only correct for non-parented objects right now! + mutable LLVector3 mPositionRegion; + mutable LLVector3 mPositionAgent; - static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; } - static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; } - static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; } + static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; } + static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; } + static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; } - static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; } - static void setPingInterpolate(BOOL value) { sPingInterpolate = value; } + static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; } + static void setPingInterpolate(BOOL value) { sPingInterpolate = value; } -private: - static S32 sNumObjects; +private: + static S32 sNumObjects; - static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation - static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation - static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation + static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation + static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation + static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation - static BOOL sVelocityInterpolate; - static BOOL sPingInterpolate; + static BOOL sVelocityInterpolate; + static BOOL sPingInterpolate; - bool mCachedOwnerInMuteList; - F64 mCachedMuteListUpdateTime; + bool mCachedOwnerInMuteList; + F64 mCachedMuteListUpdateTime; - //-------------------------------------------------------------------- - // For objects that are attachments - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // For objects that are attachments + //-------------------------------------------------------------------- public: - const LLUUID &getAttachmentItemID() const; - void setAttachmentItemID(const LLUUID &id); - const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object - EObjectUpdateType getLastUpdateType() const; - void setLastUpdateType(EObjectUpdateType last_update_type); - BOOL getLastUpdateCached() const; - void setLastUpdateCached(BOOL last_update_cached); + const LLUUID &getAttachmentItemID() const; + void setAttachmentItemID(const LLUUID &id); + const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object + EObjectUpdateType getLastUpdateType() const; + void setLastUpdateType(EObjectUpdateType last_update_type); + BOOL getLastUpdateCached() const; + void setLastUpdateCached(BOOL last_update_cached); virtual void updateRiggingInfo() {} LLJointRiggingInfoTab mJointRiggingInfoTab; private: - LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. - EObjectUpdateType mLastUpdateType; - BOOL mLastUpdateCached; + LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. + EObjectUpdateType mLastUpdateType; + BOOL mLastUpdateCached; public: // reflection probe state @@ -974,58 +974,58 @@ public: inline void LLViewerObject::setRotation(const LLQuaternion& quat, BOOL damped) { - LLPrimitive::setRotation(quat); - setChanged(ROTATED | SILHOUETTE); - updateDrawable(damped); + LLPrimitive::setRotation(quat); + setChanged(ROTATED | SILHOUETTE); + updateDrawable(damped); } inline void LLViewerObject::setRotation(const F32 x, const F32 y, const F32 z, BOOL damped) { - LLPrimitive::setRotation(x, y, z); - setChanged(ROTATED | SILHOUETTE); - updateDrawable(damped); + LLPrimitive::setRotation(x, y, z); + setChanged(ROTATED | SILHOUETTE); + updateDrawable(damped); } class LLViewerObjectMedia { public: - LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { } + LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { } - std::string mMediaURL; // for web pages on surfaces, one per prim - BOOL mPassedWhitelist; // user has OK'd display - U8 mMediaType; // see LLTextureEntry::WEB_PAGE, etc. + std::string mMediaURL; // for web pages on surfaces, one per prim + BOOL mPassedWhitelist; // user has OK'd display + U8 mMediaType; // see LLTextureEntry::WEB_PAGE, etc. }; // subclass of viewer object that can be added to particle partitions class LLAlphaObject : public LLViewerObject { public: - LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) - : LLViewerObject(id,pcode,regionp) - { mDepth = 0.f; } - - virtual F32 getPartSize(S32 idx); - virtual void getGeometry(S32 idx, - LLStrider& verticesp, - LLStrider& normalsp, - LLStrider& texcoordsp, - LLStrider& colorsp, - LLStrider& emissivep, - LLStrider& indicesp) = 0; - - virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst); - - F32 mDepth; + LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) + : LLViewerObject(id,pcode,regionp) + { mDepth = 0.f; } + + virtual F32 getPartSize(S32 idx); + virtual void getGeometry(S32 idx, + LLStrider& verticesp, + LLStrider& normalsp, + LLStrider& texcoordsp, + LLStrider& colorsp, + LLStrider& emissivep, + LLStrider& indicesp) = 0; + + virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst); + + F32 mDepth; }; class LLStaticViewerObject : public LLViewerObject { public: - LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE) - : LLViewerObject(id,pcode,regionp, is_global) - { } + LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE) + : LLViewerObject(id,pcode,regionp, is_global) + { } - virtual void updateDrawable(BOOL force_damped); + virtual void updateDrawable(BOOL force_damped); }; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 61ab2791fb..0231442316 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewerregion.cpp * @brief Implementation of the LLViewerRegion class. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010-2013, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,7 +31,7 @@ // linden libraries #include "indra_constants.h" #include "llaisapi.h" -#include "llavatarnamecache.h" // name lookup cap url +#include "llavatarnamecache.h" // name lookup cap url #include "llfloaterreg.h" #include "llmath.h" #include "llregionflags.h" @@ -86,11 +86,11 @@ #include #ifdef LL_WINDOWS - #pragma warning(disable:4355) + #pragma warning(disable:4355) #endif -// When we receive a base grant of capabilities that has a different number of -// capabilities than the original base grant received for the region, print +// When we receive a base grant of capabilities that has a different number of +// capabilities than the original base grant received for the region, print // out the two lists of capabilities for analysis. //#define DEBUG_CAPS_GRANTS @@ -144,25 +144,25 @@ public: { return false; } - + // build a secondlife://{PLACE} SLurl from this SLapp std::string url = "secondlife://"; if (!grid.empty()) { url += grid + "/secondlife/"; } - boost::regex name_rx("[A-Za-z0-9()_%]+"); - boost::regex coord_rx("[0-9]+"); + boost::regex name_rx("[A-Za-z0-9()_%]+"); + boost::regex coord_rx("[0-9]+"); for (int i = 0; i < num_params; i++) { if (i > 0) { url += "/"; } - if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx)) - { - return false; - } + if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx)) + { + return false; + } url += params[i].asString(); } @@ -171,15 +171,15 @@ public: LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_CLICKED, web, true); return true; } - + }; LLRegionHandler gRegionHandler; -class LLViewerRegionImpl +class LLViewerRegionImpl { public: - LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host): + LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host): mHost(host), mCompositionp(NULL), mEventPoll(NULL), @@ -190,62 +190,62 @@ public: mLastCameraOrigin(), mVOCachePartition(NULL), mLandp(NULL) - {} + {} - static void buildCapabilityNames(LLSD& capabilityNames); + static void buildCapabilityNames(LLSD& capabilityNames); - // The surfaces and other layers - LLSurface* mLandp; + // The surfaces and other layers + LLSurface* mLandp; - // Region geometry data - LLVector3d mOriginGlobal; // Location of southwest corner of region (meters) - LLVector3d mCenterGlobal; // Location of center in world space (meters) - LLHost mHost; + // Region geometry data + LLVector3d mOriginGlobal; // Location of southwest corner of region (meters) + LLVector3d mCenterGlobal; // Location of center in world space (meters) + LLHost mHost; - // The unique ID for this region. - LLUUID mRegionID; + // The unique ID for this region. + LLUUID mRegionID; - // region/estate owner - usually null. - LLUUID mOwnerID; + // region/estate owner - usually null. + LLUUID mOwnerID; - // Network statistics for the region's circuit... - LLTimer mLastNetUpdate; + // Network statistics for the region's circuit... + LLTimer mLastNetUpdate; - // Misc - LLVLComposition *mCompositionp; // Composition layer for the surface + // Misc + LLVLComposition *mCompositionp; // Composition layer for the surface - LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries - LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; - LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. - std::set< LLPointer > mVisibleGroups; //visible groupa - LLVOCachePartition* mVOCachePartition; - LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. - LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. - std::set mNonCacheableCreatedList; //list of local ids of all non-cacheable objects + LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries + LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; + LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. + std::set< LLPointer > mVisibleGroups; //visible groupa + LLVOCachePartition* mVOCachePartition; + LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. + LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. + std::set mNonCacheableCreatedList; //list of local ids of all non-cacheable objects LLVOCacheEntry::vocache_gltf_overrides_map_t mGLTFOverridesLLSD; // for materials - // time? - // LRU info? + // time? + // LRU info? - // Cache ID is unique per-region, across renames, moving locations, - // etc. - LLUUID mCacheID; + // Cache ID is unique per-region, across renames, moving locations, + // etc. + LLUUID mCacheID; - CapabilityMap mCapabilities; - CapabilityMap mSecondCapabilitiesTracker; + CapabilityMap mCapabilities; + CapabilityMap mSecondCapabilitiesTracker; - LLEventPoll* mEventPoll; + LLEventPoll* mEventPoll; - S32 mSeedCapMaxAttempts; - S32 mSeedCapAttempts; + S32 mSeedCapMaxAttempts; + S32 mSeedCapAttempts; - S32 mHttpResponderID; + S32 mHttpResponderID; - //spatial partitions for objects in this region - std::vector mObjectPartition; + //spatial partitions for objects in this region + std::vector mObjectPartition; - LLVector3 mLastCameraOrigin; - U32 mLastCameraUpdate; + LLVector3 mLastCameraOrigin; + U32 mLastCameraUpdate; static void requestBaseCapabilitiesCoro(U64 regionHandle); static void requestBaseCapabilitiesCompleteCoro(U64 regionHandle); @@ -255,7 +255,7 @@ public: void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); @@ -284,7 +284,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) return; // this error condition is not recoverable. } LLViewerRegionImpl* impl = regionp->getRegionImplNC(); - LL_DEBUGS("AppInit", "Capabilities") << "requesting seed caps for handle " << regionHandle + LL_DEBUGS("AppInit", "Capabilities") << "requesting seed caps for handle " << regionHandle << " name " << regionp->getName() << LL_ENDL; std::string url = regionp->getCapability("Seed"); @@ -310,12 +310,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) LLSD capabilityNames = LLSD::emptyArray(); impl->buildCapabilityNames(capabilityNames); - LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url + LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url << " region name " << regionp->getName() << " region id " << regionp->getRegionID() << " handle " << regionp->getHandle() << " (attempt #" << impl->mSeedCapAttempts + 1 << ")" << LL_ENDL; - LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL; + LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL; regionp = NULL; impl = NULL; @@ -389,12 +389,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) log_capabilities(mCapabilities); #endif - LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle - << " region name " << regionp->getName() << LL_ENDL; + LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle + << " region name " << regionp->getName() << LL_ENDL; regionp->setCapabilitiesReceived(true); break; - } + } while (true); if (regionp && regionp->isCapabilityAvailable("ServerReleaseNotes") && @@ -535,7 +535,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL; } impl->mSecondCapabilitiesTracker.clear(); - } + } while (false); } @@ -555,7 +555,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region if (attemptNumber > MAX_CAP_REQUEST_ATTEMPTS) { - LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from " + LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from " << url << LL_ENDL; break; } @@ -583,7 +583,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region if (!status) { LL_WARNS("AppInit", "SimulatorFeatures") << "HttpStatus error retrying" << LL_ENDL; - continue; + continue; } if (LLApp::isExiting() || gDisconnected) @@ -617,218 +617,218 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region } LLViewerRegion::LLViewerRegion(const U64 &handle, - const LLHost &host, - const U32 grids_per_region_edge, - const U32 grids_per_patch_edge, - const F32 region_width_meters) -: mImpl(new LLViewerRegionImpl(this, host)), - mHandle(handle), - mTimeDilation(1.0f), - mName(""), - mZoning(""), - mIsEstateManager(FALSE), - mRegionFlags( REGION_FLAGS_DEFAULT ), - mRegionProtocols( 0 ), - mSimAccess( SIM_ACCESS_MIN ), - mBillableFactor(1.0), - mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT), - mCentralBakeVersion(1), - mClassID(0), - mCPURatio(0), - mColoName("unknown"), - mProductSKU("unknown"), - mProductName("unknown"), - mViewerAssetUrl(""), - mCacheLoaded(FALSE), - mCacheDirty(FALSE), - mReleaseNotesRequested(FALSE), - mCapabilitiesState(CAPABILITIES_STATE_INIT), - mSimulatorFeaturesReceived(false), - mBitsReceived(0.f), - mPacketsReceived(0.f), - mDead(FALSE), - mLastVisitedEntry(NULL), - mInvisibilityCheckHistory(-1), - mPaused(FALSE), - mRegionCacheHitCount(0), - mRegionCacheMissCount(0), + const LLHost &host, + const U32 grids_per_region_edge, + const U32 grids_per_patch_edge, + const F32 region_width_meters) +: mImpl(new LLViewerRegionImpl(this, host)), + mHandle(handle), + mTimeDilation(1.0f), + mName(""), + mZoning(""), + mIsEstateManager(FALSE), + mRegionFlags( REGION_FLAGS_DEFAULT ), + mRegionProtocols( 0 ), + mSimAccess( SIM_ACCESS_MIN ), + mBillableFactor(1.0), + mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT), + mCentralBakeVersion(1), + mClassID(0), + mCPURatio(0), + mColoName("unknown"), + mProductSKU("unknown"), + mProductName("unknown"), + mViewerAssetUrl(""), + mCacheLoaded(FALSE), + mCacheDirty(FALSE), + mReleaseNotesRequested(FALSE), + mCapabilitiesState(CAPABILITIES_STATE_INIT), + mSimulatorFeaturesReceived(false), + mBitsReceived(0.f), + mPacketsReceived(0.f), + mDead(FALSE), + mLastVisitedEntry(NULL), + mInvisibilityCheckHistory(-1), + mPaused(FALSE), + mRegionCacheHitCount(0), + mRegionCacheMissCount(0), mInterestListMode(IL_MODE_DEFAULT) { - mWidth = region_width_meters; - mImpl->mOriginGlobal = from_region_handle(handle); - updateRenderMatrix(); + mWidth = region_width_meters; + mImpl->mOriginGlobal = from_region_handle(handle); + updateRenderMatrix(); - mImpl->mLandp = new LLSurface('l', NULL); + mImpl->mLandp = new LLSurface('l', NULL); - // Create the composition layer for the surface - mImpl->mCompositionp = - new LLVLComposition(mImpl->mLandp, - grids_per_region_edge, - region_width_meters / grids_per_region_edge); - mImpl->mCompositionp->setSurface(mImpl->mLandp); + // Create the composition layer for the surface + mImpl->mCompositionp = + new LLVLComposition(mImpl->mLandp, + grids_per_region_edge, + region_width_meters / grids_per_region_edge); + mImpl->mCompositionp->setSurface(mImpl->mLandp); - // Create the surfaces - mImpl->mLandp->setRegion(this); - mImpl->mLandp->create(grids_per_region_edge, - grids_per_patch_edge, - mImpl->mOriginGlobal, - mWidth); + // Create the surfaces + mImpl->mLandp->setRegion(this); + mImpl->mLandp->create(grids_per_region_edge, + grids_per_patch_edge, + mImpl->mOriginGlobal, + mWidth); - mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); + mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); - setOriginGlobal(from_region_handle(handle)); - calculateCenterGlobal(); + setOriginGlobal(from_region_handle(handle)); + calculateCenterGlobal(); - // Create the object lists - initStats(); + // Create the object lists + initStats(); - //create object partitions - //MUST MATCH declaration of eObjectPartitions - mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD - mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN - mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER - mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER - mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE - mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE - mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS - mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME - mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE - mImpl->mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR - mImpl->mObjectPartition.push_back(new LLControlAVPartition(this)); //PARTITION_CONTROL_AV - mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE - mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE - mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE - mImpl->mVOCachePartition = getVOCachePartition(); + //create object partitions + //MUST MATCH declaration of eObjectPartitions + mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD + mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN + mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER + mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER + mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE + mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE + mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS + mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME + mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE + mImpl->mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR + mImpl->mObjectPartition.push_back(new LLControlAVPartition(this)); //PARTITION_CONTROL_AV + mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE + mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE + mImpl->mVOCachePartition = getVOCachePartition(); - setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::scanNewRegion, _1)); + setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::scanNewRegion, _1)); } void LLViewerRegion::initStats() { - mImpl->mLastNetUpdate.reset(); - mPacketsIn = 0; - mBitsIn = (U32Bits)0; - mLastBitsIn = (U32Bits)0; - mLastPacketsIn = 0; - mPacketsOut = 0; - mLastPacketsOut = 0; - mPacketsLost = 0; - mLastPacketsLost = 0; - mPingDelay = (U32Seconds)0; - mAlive = false; // can become false if circuit disconnects + mImpl->mLastNetUpdate.reset(); + mPacketsIn = 0; + mBitsIn = (U32Bits)0; + mLastBitsIn = (U32Bits)0; + mLastPacketsIn = 0; + mPacketsOut = 0; + mLastPacketsOut = 0; + mPacketsLost = 0; + mLastPacketsLost = 0; + mPingDelay = (U32Seconds)0; + mAlive = false; // can become false if circuit disconnects } static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects"); static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); -LLViewerRegion::~LLViewerRegion() +LLViewerRegion::~LLViewerRegion() { LL_PROFILE_ZONE_SCOPED; - mDead = TRUE; - mImpl->mActiveSet.clear(); - mImpl->mVisibleEntries.clear(); - mImpl->mVisibleGroups.clear(); - mImpl->mWaitingSet.clear(); - - gVLManager.cleanupData(this); - // Can't do this on destruction, because the neighbor pointers might be invalid. - // This should be reference counted... - disconnectAllNeighbors(); - LLViewerPartSim::getInstance()->cleanupRegion(this); + mDead = TRUE; + mImpl->mActiveSet.clear(); + mImpl->mVisibleEntries.clear(); + mImpl->mVisibleGroups.clear(); + mImpl->mWaitingSet.clear(); + + gVLManager.cleanupData(this); + // Can't do this on destruction, because the neighbor pointers might be invalid. + // This should be reference counted... + disconnectAllNeighbors(); + LLViewerPartSim::getInstance()->cleanupRegion(this); { LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS); gObjectList.killObjects(this); } - delete mImpl->mCompositionp; - delete mParcelOverlay; - delete mImpl->mLandp; - delete mImpl->mEventPoll; + delete mImpl->mCompositionp; + delete mParcelOverlay; + delete mImpl->mLandp; + delete mImpl->mEventPoll; #if 0 - LLHTTPSender::clearSender(mImpl->mHost); -#endif - std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + LLHTTPSender::clearSender(mImpl->mHost); +#endif + std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); { LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE); saveObjectCache(); } - delete mImpl; - mImpl = NULL; + delete mImpl; + mImpl = NULL; } -/*virtual*/ -const LLHost& LLViewerRegion::getHost() const -{ - return mImpl->mHost; +/*virtual*/ +const LLHost& LLViewerRegion::getHost() const +{ + return mImpl->mHost; } LLSurface & LLViewerRegion::getLand() const { - return *mImpl->mLandp; + return *mImpl->mLandp; } const LLUUID& LLViewerRegion::getRegionID() const { - return mImpl->mRegionID; + return mImpl->mRegionID; } void LLViewerRegion::setRegionID(const LLUUID& region_id) { - mImpl->mRegionID = region_id; + mImpl->mRegionID = region_id; } void LLViewerRegion::loadObjectCache() { - if (mCacheLoaded) - { - return; - } + if (mCacheLoaded) + { + return; + } - // Presume success. If it fails, we don't want to try again. - mCacheLoaded = TRUE; + // Presume success. If it fails, we don't want to try again. + mCacheLoaded = TRUE; - if(LLVOCache::instanceExists()) - { + if(LLVOCache::instanceExists()) + { LLVOCache & vocache = LLVOCache::instance(); - // Without this a "corrupted" vocache persists until a cache clear or other rewrite. Mark as dirty hereif read fails to force a rewrite. - mCacheDirty = !vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap); - vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mImpl->mCacheMap); + // Without this a "corrupted" vocache persists until a cache clear or other rewrite. Mark as dirty hereif read fails to force a rewrite. + mCacheDirty = !vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap); + vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mImpl->mCacheMap); - if (mImpl->mCacheMap.empty()) - { - mCacheDirty = TRUE; - } - } + if (mImpl->mCacheMap.empty()) + { + mCacheDirty = TRUE; + } + } } void LLViewerRegion::saveObjectCache() { - if (!mCacheLoaded) - { - return; - } + if (!mCacheLoaded) + { + return; + } - if (mImpl->mCacheMap.empty()) - { - return; - } + if (mImpl->mCacheMap.empty()) + { + return; + } - if(LLVOCache::instanceExists()) - { - const F32 start_time_threshold = 600.0f; //seconds - bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. + if(LLVOCache::instanceExists()) + { + const F32 start_time_threshold = 600.0f; //seconds + bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. LLVOCache & instance = LLVOCache::instance(); instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled); instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mCacheDirty, removal_enabled); - mCacheDirty = FALSE; - } + mCacheDirty = FALSE; + } if (LLAppViewer::instance()->isQuitting()) { @@ -845,253 +845,253 @@ void LLViewerRegion::saveObjectCache() void LLViewerRegion::sendMessage() { - gMessageSystem->sendMessage(mImpl->mHost); + gMessageSystem->sendMessage(mImpl->mHost); } void LLViewerRegion::sendReliableMessage() { - gMessageSystem->sendReliable(mImpl->mHost); + gMessageSystem->sendReliable(mImpl->mHost); } void LLViewerRegion::setWaterHeight(F32 water_level) { - mImpl->mLandp->setWaterHeight(water_level); + mImpl->mLandp->setWaterHeight(water_level); } F32 LLViewerRegion::getWaterHeight() const { - return mImpl->mLandp->getWaterHeight(); + return mImpl->mLandp->getWaterHeight(); } BOOL LLViewerRegion::isVoiceEnabled() const { - return getRegionFlag(REGION_FLAGS_ALLOW_VOICE); + return getRegionFlag(REGION_FLAGS_ALLOW_VOICE); } void LLViewerRegion::setRegionFlags(U64 flags) { - mRegionFlags = flags; + mRegionFlags = flags; } -void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) -{ - mImpl->mOriginGlobal = origin_global; - updateRenderMatrix(); - mImpl->mLandp->setOriginGlobal(origin_global); - mWind.setOriginGlobal(origin_global); - calculateCenterGlobal(); +void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) +{ + mImpl->mOriginGlobal = origin_global; + updateRenderMatrix(); + mImpl->mLandp->setOriginGlobal(origin_global); + mWind.setOriginGlobal(origin_global); + calculateCenterGlobal(); } void LLViewerRegion::updateRenderMatrix() { - mRenderMatrix.setTranslation(getOriginAgent()); + mRenderMatrix.setTranslation(getOriginAgent()); } void LLViewerRegion::setTimeDilation(F32 time_dilation) { - mTimeDilation = time_dilation; + mTimeDilation = time_dilation; } const LLVector3d & LLViewerRegion::getOriginGlobal() const { - return mImpl->mOriginGlobal; + return mImpl->mOriginGlobal; } LLVector3 LLViewerRegion::getOriginAgent() const { - return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal); + return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal); } const LLVector3d & LLViewerRegion::getCenterGlobal() const { - return mImpl->mCenterGlobal; + return mImpl->mCenterGlobal; } LLVector3 LLViewerRegion::getCenterAgent() const { - return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal); + return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal); } void LLViewerRegion::setOwner(const LLUUID& owner_id) { - mImpl->mOwnerID = owner_id; + mImpl->mOwnerID = owner_id; } const LLUUID& LLViewerRegion::getOwner() const { - return mImpl->mOwnerID; + return mImpl->mOwnerID; } -void LLViewerRegion::setRegionNameAndZone (const std::string& name_zone) +void LLViewerRegion::setRegionNameAndZone (const std::string& name_zone) { - std::string::size_type pipe_pos = name_zone.find('|'); - S32 length = name_zone.size(); - if (pipe_pos != std::string::npos) - { - mName = name_zone.substr(0, pipe_pos); - mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1)); - } - else - { - mName = name_zone; - mZoning = ""; - } + std::string::size_type pipe_pos = name_zone.find('|'); + S32 length = name_zone.size(); + if (pipe_pos != std::string::npos) + { + mName = name_zone.substr(0, pipe_pos); + mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1)); + } + else + { + mName = name_zone; + mZoning = ""; + } - LLStringUtil::stripNonprintable(mName); - LLStringUtil::stripNonprintable(mZoning); + LLStringUtil::stripNonprintable(mName); + LLStringUtil::stripNonprintable(mZoning); } BOOL LLViewerRegion::canManageEstate() const { - return gAgent.isGodlike() - || isEstateManager() - || gAgent.getID() == getOwner(); + return gAgent.isGodlike() + || isEstateManager() + || gAgent.getID() == getOwner(); } const std::string LLViewerRegion::getSimAccessString() const { - return accessToString(mSimAccess); + return accessToString(mSimAccess); } std::string LLViewerRegion::getLocalizedSimProductName() const { - std::string localized_spn; - return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName; + std::string localized_spn; + return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName; } // static std::string LLViewerRegion::regionFlagsToString(U64 flags) { - std::string result; + std::string result; - if (flags & REGION_FLAGS_SANDBOX) - { - result += "Sandbox"; - } + if (flags & REGION_FLAGS_SANDBOX) + { + result += "Sandbox"; + } - if (flags & REGION_FLAGS_ALLOW_DAMAGE) - { - result += " Not Safe"; - } + if (flags & REGION_FLAGS_ALLOW_DAMAGE) + { + result += " Not Safe"; + } - return result; + return result; } // static std::string LLViewerRegion::accessToString(U8 sim_access) { - switch(sim_access) - { - case SIM_ACCESS_PG: - return LLTrans::getString("SIM_ACCESS_PG"); + switch(sim_access) + { + case SIM_ACCESS_PG: + return LLTrans::getString("SIM_ACCESS_PG"); - case SIM_ACCESS_MATURE: - return LLTrans::getString("SIM_ACCESS_MATURE"); + case SIM_ACCESS_MATURE: + return LLTrans::getString("SIM_ACCESS_MATURE"); - case SIM_ACCESS_ADULT: - return LLTrans::getString("SIM_ACCESS_ADULT"); + case SIM_ACCESS_ADULT: + return LLTrans::getString("SIM_ACCESS_ADULT"); - case SIM_ACCESS_DOWN: - return LLTrans::getString("SIM_ACCESS_DOWN"); + case SIM_ACCESS_DOWN: + return LLTrans::getString("SIM_ACCESS_DOWN"); - case SIM_ACCESS_MIN: - default: - return LLTrans::getString("SIM_ACCESS_MIN"); - } + case SIM_ACCESS_MIN: + default: + return LLTrans::getString("SIM_ACCESS_MIN"); + } } // static std::string LLViewerRegion::getAccessIcon(U8 sim_access) { - switch(sim_access) - { - case SIM_ACCESS_MATURE: - return "Parcel_M_Dark"; + switch(sim_access) + { + case SIM_ACCESS_MATURE: + return "Parcel_M_Dark"; - case SIM_ACCESS_ADULT: - return "Parcel_R_Light"; + case SIM_ACCESS_ADULT: + return "Parcel_R_Light"; - case SIM_ACCESS_PG: - return "Parcel_PG_Light"; + case SIM_ACCESS_PG: + return "Parcel_PG_Light"; - case SIM_ACCESS_MIN: - default: - return ""; - } + case SIM_ACCESS_MIN: + default: + return ""; + } } // static std::string LLViewerRegion::accessToShortString(U8 sim_access) { - switch(sim_access) /* Flawfinder: ignore */ - { - case SIM_ACCESS_PG: - return "PG"; + switch(sim_access) /* Flawfinder: ignore */ + { + case SIM_ACCESS_PG: + return "PG"; - case SIM_ACCESS_MATURE: - return "M"; + case SIM_ACCESS_MATURE: + return "M"; - case SIM_ACCESS_ADULT: - return "A"; + case SIM_ACCESS_ADULT: + return "A"; - case SIM_ACCESS_MIN: - default: - return "U"; - } + case SIM_ACCESS_MIN: + default: + return "U"; + } } // static U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access) { - U8 accessValue; + U8 accessValue; - if (LLStringUtil::compareStrings(sim_access, "PG") == 0) - { - accessValue = SIM_ACCESS_PG; - } - else if (LLStringUtil::compareStrings(sim_access, "M") == 0) - { - accessValue = SIM_ACCESS_MATURE; - } - else if (LLStringUtil::compareStrings(sim_access, "A") == 0) - { - accessValue = SIM_ACCESS_ADULT; - } - else - { - accessValue = SIM_ACCESS_MIN; - } + if (LLStringUtil::compareStrings(sim_access, "PG") == 0) + { + accessValue = SIM_ACCESS_PG; + } + else if (LLStringUtil::compareStrings(sim_access, "M") == 0) + { + accessValue = SIM_ACCESS_MATURE; + } + else if (LLStringUtil::compareStrings(sim_access, "A") == 0) + { + accessValue = SIM_ACCESS_ADULT; + } + else + { + accessValue = SIM_ACCESS_MIN; + } - return accessValue; + return accessValue; } // static void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { - // send it to 'observers' - // *TODO: switch the floaters to using LLRegionInfoModel - LL_INFOS() << "Processing region info" << LL_ENDL; - LLRegionInfoModel::instance().update(msg); - LLFloaterGodTools::processRegionInfo(msg); - LLFloaterRegionInfo::processRegionInfo(msg); + // send it to 'observers' + // *TODO: switch the floaters to using LLRegionInfoModel + LL_INFOS() << "Processing region info" << LL_ENDL; + LLRegionInfoModel::instance().update(msg); + LLFloaterGodTools::processRegionInfo(msg); + LLFloaterRegionInfo::processRegionInfo(msg); } void LLViewerRegion::setCacheID(const LLUUID& id) { - mImpl->mCacheID = id; + mImpl->mCacheID = id; } S32 LLViewerRegion::renderPropertyLines() { - if (mParcelOverlay) - { - return mParcelOverlay->renderPropertyLines(); - } - else - { - return 0; - } + if (mParcelOverlay) + { + return mParcelOverlay->renderPropertyLines(); + } + else + { + return 0; + } } void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) @@ -1106,11 +1106,11 @@ void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, co // This gets called when the height field changes. void LLViewerRegion::dirtyHeights() { - // Property lines need to be reconstructed when the land changes. - if (mParcelOverlay) - { - mParcelOverlay->setDirty(); - } + // Property lines need to be reconstructed when the land changes. + if (mParcelOverlay) + { + mParcelOverlay->setDirty(); + } } void LLViewerRegion::dirtyAllPatches() @@ -1120,159 +1120,159 @@ void LLViewerRegion::dirtyAllPatches() //physically delete the cache entry void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering) -{ - if(!entry || !entry->isValid()) - { - return; - } - - if(for_rendering && !entry->isState(LLVOCacheEntry::ACTIVE)) - { - addNewObject(entry); //force to add to rendering pipeline - } - - //remove from active list and waiting list - if(entry->isState(LLVOCacheEntry::ACTIVE)) - { - mImpl->mActiveSet.erase(entry); - } - else - { - if(entry->isState(LLVOCacheEntry::WAITING)) - { - mImpl->mWaitingSet.erase(entry); - } - - //remove from mVOCachePartition - removeFromVOCacheTree(entry); - } - - //remove from the forced visible list - mImpl->mVisibleEntries.erase(entry); - - //disconnect from parent if it is a child - if(entry->getParentID() > 0) - { - LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); - if(parent) - { - parent->removeChild(entry); - } - } - else if(entry->getNumOfChildren() > 0)//remove children from cache if has any - { - LLVOCacheEntry* child = entry->getChild(); - while(child != NULL) - { - killCacheEntry(child, for_rendering); - child = entry->getChild(); - } - } - // Kill the assocaited overrides - mImpl->mGLTFOverridesLLSD.erase(entry->getLocalID()); - //will remove it from the object cache, real deletion - entry->setState(LLVOCacheEntry::INACTIVE); - entry->removeOctreeEntry(); - entry->setValid(FALSE); - -} - -//physically delete the cache entry -void LLViewerRegion::killCacheEntry(U32 local_id) -{ - killCacheEntry(getCacheEntry(local_id)); +{ + if(!entry || !entry->isValid()) + { + return; + } + + if(for_rendering && !entry->isState(LLVOCacheEntry::ACTIVE)) + { + addNewObject(entry); //force to add to rendering pipeline + } + + //remove from active list and waiting list + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mActiveSet.erase(entry); + } + else + { + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + //remove from mVOCachePartition + removeFromVOCacheTree(entry); + } + + //remove from the forced visible list + mImpl->mVisibleEntries.erase(entry); + + //disconnect from parent if it is a child + if(entry->getParentID() > 0) + { + LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); + if(parent) + { + parent->removeChild(entry); + } + } + else if(entry->getNumOfChildren() > 0)//remove children from cache if has any + { + LLVOCacheEntry* child = entry->getChild(); + while(child != NULL) + { + killCacheEntry(child, for_rendering); + child = entry->getChild(); + } + } + // Kill the assocaited overrides + mImpl->mGLTFOverridesLLSD.erase(entry->getLocalID()); + //will remove it from the object cache, real deletion + entry->setState(LLVOCacheEntry::INACTIVE); + entry->removeOctreeEntry(); + entry->setValid(FALSE); + +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(U32 local_id) +{ + killCacheEntry(getCacheEntry(local_id)); } U32 LLViewerRegion::getNumOfActiveCachedObjects() const { - return mImpl->mActiveSet.size(); + return mImpl->mActiveSet.size(); } void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry) { - if(!entry || mDead) - { - return; - } - if(entry->isState(LLVOCacheEntry::ACTIVE)) - { - return; //already inserted. - } + if(!entry || mDead) + { + return; + } + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + return; //already inserted. + } - if(entry->isState(LLVOCacheEntry::WAITING)) - { - mImpl->mWaitingSet.erase(entry); - } + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } - entry->setState(LLVOCacheEntry::ACTIVE); - entry->setVisible(); + entry->setState(LLVOCacheEntry::ACTIVE); + entry->setVisible(); - llassert(entry->getEntry()->hasDrawable()); - mImpl->mActiveSet.insert(entry); + llassert(entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(entry); } void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep) { - if(mDead || !entry || !entry->isValid()) - { - return; - } - if(!entry->isState(LLVOCacheEntry::ACTIVE)) - { - return; //not an active entry. - } - - //shift to the local regional space from agent space - if(drawablep != NULL && drawablep->getVObj().notNull()) - { - const LLVector3& pos = drawablep->getVObj()->getPositionRegion(); - LLVector4a shift; - shift.load3(pos.mV); - shift.sub(entry->getPositionGroup()); - entry->shift(shift); - } - - if(entry->getParentID() > 0) //is a child - { - LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); - if(parent) - { - parent->addChild(entry); - } - else //parent not in cache. - { - //this happens only when parent is not cacheable. - mOrphanMap[entry->getParentID()].push_back(entry->getLocalID()); - } - } - else //insert to vo cache tree. - { - entry->updateParentBoundingInfo(); - entry->saveBoundingSphere(); - addToVOCacheTree(entry); - } - - mImpl->mVisibleEntries.erase(entry); - mImpl->mActiveSet.erase(entry); - mImpl->mWaitingSet.erase(entry); - entry->setState(LLVOCacheEntry::INACTIVE); + if(mDead || !entry || !entry->isValid()) + { + return; + } + if(!entry->isState(LLVOCacheEntry::ACTIVE)) + { + return; //not an active entry. + } + + //shift to the local regional space from agent space + if(drawablep != NULL && drawablep->getVObj().notNull()) + { + const LLVector3& pos = drawablep->getVObj()->getPositionRegion(); + LLVector4a shift; + shift.load3(pos.mV); + shift.sub(entry->getPositionGroup()); + entry->shift(shift); + } + + if(entry->getParentID() > 0) //is a child + { + LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); + if(parent) + { + parent->addChild(entry); + } + else //parent not in cache. + { + //this happens only when parent is not cacheable. + mOrphanMap[entry->getParentID()].push_back(entry->getLocalID()); + } + } + else //insert to vo cache tree. + { + entry->updateParentBoundingInfo(); + entry->saveBoundingSphere(); + addToVOCacheTree(entry); + } + + mImpl->mVisibleEntries.erase(entry); + mImpl->mActiveSet.erase(entry); + mImpl->mWaitingSet.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); } bool LLViewerRegion::addVisibleGroup(LLViewerOctreeGroup* group) { - if(mDead || group->isEmpty()) - { - return false; - } - - mImpl->mVisibleGroups.insert(group); + if(mDead || group->isEmpty()) + { + return false; + } - return true; + mImpl->mVisibleGroups.insert(group); + + return true; } U32 LLViewerRegion::getNumOfVisibleGroups() const { - return mImpl ? mImpl->mVisibleGroups.size() : 0; + return mImpl ? mImpl->mVisibleGroups.size() : 0; } void LLViewerRegion::updateReflectionProbes() @@ -1317,306 +1317,306 @@ void LLViewerRegion::updateReflectionProbes() void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { - if(!sVOCacheCullingEnabled) - { - return; - } + if(!sVOCacheCullingEnabled) + { + return; + } - if(mDead || !entry || !entry->getEntry() || !entry->isValid()) - { - return; - } - if(entry->getParentID() > 0) - { - return; //no child prim in cache octree. - } + if(mDead || !entry || !entry->getEntry() || !entry->isValid()) + { + return; + } + if(entry->getParentID() > 0) + { + return; //no child prim in cache octree. + } - if(entry->hasState(LLVOCacheEntry::IN_VO_TREE)) - { - return; //already in the tree. - } + if(entry->hasState(LLVOCacheEntry::IN_VO_TREE)) + { + return; //already in the tree. + } - llassert_always(!entry->getGroup()); //not in octree. - llassert(!entry->getEntry()->hasDrawable()); //not have drawables + llassert_always(!entry->getGroup()); //not in octree. + llassert(!entry->getEntry()->hasDrawable()); //not have drawables - if(mImpl->mVOCachePartition->addEntry(entry->getEntry())) - { - entry->setState(LLVOCacheEntry::IN_VO_TREE); - } + if(mImpl->mVOCachePartition->addEntry(entry->getEntry())) + { + entry->setState(LLVOCacheEntry::IN_VO_TREE); + } } void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) { - if(mDead || !entry || !entry->getEntry()) - { - return; - } - - if(!entry->hasState(LLVOCacheEntry::IN_VO_TREE)) - { - return; //not in the tree. - } - entry->clearState(LLVOCacheEntry::IN_VO_TREE); + if(mDead || !entry || !entry->getEntry()) + { + return; + } - mImpl->mVOCachePartition->removeEntry(entry->getEntry()); + if(!entry->hasState(LLVOCacheEntry::IN_VO_TREE)) + { + return; //not in the tree. + } + entry->clearState(LLVOCacheEntry::IN_VO_TREE); + + mImpl->mVOCachePartition->removeEntry(entry->getEntry()); } //add child objects as visible entries void LLViewerRegion::addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child) { - if(mDead) - { - return; - } - - if(parent && (!parent->isValid() || !parent->isState(LLVOCacheEntry::ACTIVE))) - { - return; //parent must be valid and in rendering pipeline - } - - if(child && (!child->getEntry() || !child->isValid() || !child->isState(LLVOCacheEntry::INACTIVE))) - { - return; //child must be valid and not in the rendering pipeline - } - - if(child) - { - child->setState(LLVOCacheEntry::IN_QUEUE); - mImpl->mVisibleEntries.insert(child); - } - else if(parent && parent->getNumOfChildren() > 0) //add all children - { - child = parent->getChild(); - while(child != NULL) - { - addVisibleChildCacheEntry(NULL, child); - child = parent->getChild(); - } - } + if(mDead) + { + return; + } + + if(parent && (!parent->isValid() || !parent->isState(LLVOCacheEntry::ACTIVE))) + { + return; //parent must be valid and in rendering pipeline + } + + if(child && (!child->getEntry() || !child->isValid() || !child->isState(LLVOCacheEntry::INACTIVE))) + { + return; //child must be valid and not in the rendering pipeline + } + + if(child) + { + child->setState(LLVOCacheEntry::IN_QUEUE); + mImpl->mVisibleEntries.insert(child); + } + else if(parent && parent->getNumOfChildren() > 0) //add all children + { + child = parent->getChild(); + while(child != NULL) + { + addVisibleChildCacheEntry(NULL, child); + child = parent->getChild(); + } + } } void LLViewerRegion::updateVisibleEntries(F32 max_time) { - if(mDead) - { - return; - } - - if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) - { - return; - } - - if(!sNewObjectCreationThrottle) - { - return; - } - - const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. - const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); - const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); - bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); - U32 last_update = mImpl->mLastCameraUpdate; - LLVector4a local_origin; - local_origin.load3((camera_origin - getOriginAgent()).mV); - - //process visible entries - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) - { - LLVOCacheEntry* vo_entry = *iter; - - if(vo_entry->isValid() && vo_entry->getState() < LLVOCacheEntry::WAITING) - { - //set a large number to force to load this object. - vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION); - - mImpl->mWaitingList.insert(vo_entry); - ++iter; - } - else - { - LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; - ++next_iter; - mImpl->mVisibleEntries.erase(iter); - iter = next_iter; - } - } - - // - //process visible groups - // - //object projected area threshold - F32 projection_threshold = LLVOCacheEntry::getSquaredPixelThreshold(mImpl->mVOCachePartition->isFrontCull()); - F32 dist_threshold = mImpl->mVOCachePartition->isFrontCull() ? gAgentCamera.mDrawDistance : LLVOCacheEntry::sRearFarRadius; - - std::set< LLPointer >::iterator group_iter = mImpl->mVisibleGroups.begin(); - for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) - { - LLPointer group = *group_iter; - if(group->getNumRefs() < 3 || //group to be deleted - !group->getOctreeNode() || group->isEmpty()) //group empty - { - continue; - } - - for (LLViewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - if((*i)->hasVOCacheEntry()) - { - LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); - - if(vo_entry->getParentID() > 0) //is a child - { - //child visibility depends on its parent. - continue; - } - if(!vo_entry->isValid()) - { - continue; //skip invalid entry. - } - - vo_entry->calcSceneContribution(local_origin, needs_update, last_update, dist_threshold); - if(vo_entry->getSceneContribution() > projection_threshold) - { - mImpl->mWaitingList.insert(vo_entry); - } - } - } - } - - if(needs_update) - { - mImpl->mLastCameraOrigin = camera_origin; - mImpl->mLastCameraUpdate = cur_frame; - } - - return; + if(mDead) + { + return; + } + + if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) + { + return; + } + + if(!sNewObjectCreationThrottle) + { + return; + } + + const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. + const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); + const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); + bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); + U32 last_update = mImpl->mLastCameraUpdate; + LLVector4a local_origin; + local_origin.load3((camera_origin - getOriginAgent()).mV); + + //process visible entries + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) + { + LLVOCacheEntry* vo_entry = *iter; + + if(vo_entry->isValid() && vo_entry->getState() < LLVOCacheEntry::WAITING) + { + //set a large number to force to load this object. + vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION); + + mImpl->mWaitingList.insert(vo_entry); + ++iter; + } + else + { + LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; + ++next_iter; + mImpl->mVisibleEntries.erase(iter); + iter = next_iter; + } + } + + // + //process visible groups + // + //object projected area threshold + F32 projection_threshold = LLVOCacheEntry::getSquaredPixelThreshold(mImpl->mVOCachePartition->isFrontCull()); + F32 dist_threshold = mImpl->mVOCachePartition->isFrontCull() ? gAgentCamera.mDrawDistance : LLVOCacheEntry::sRearFarRadius; + + std::set< LLPointer >::iterator group_iter = mImpl->mVisibleGroups.begin(); + for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) + { + LLPointer group = *group_iter; + if(group->getNumRefs() < 3 || //group to be deleted + !group->getOctreeNode() || group->isEmpty()) //group empty + { + continue; + } + + for (LLViewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + if((*i)->hasVOCacheEntry()) + { + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); + + if(vo_entry->getParentID() > 0) //is a child + { + //child visibility depends on its parent. + continue; + } + if(!vo_entry->isValid()) + { + continue; //skip invalid entry. + } + + vo_entry->calcSceneContribution(local_origin, needs_update, last_update, dist_threshold); + if(vo_entry->getSceneContribution() > projection_threshold) + { + mImpl->mWaitingList.insert(vo_entry); + } + } + } + } + + if(needs_update) + { + mImpl->mLastCameraOrigin = camera_origin; + mImpl->mLastCameraUpdate = cur_frame; + } + + return; } void LLViewerRegion::createVisibleObjects(F32 max_time) { - if(mDead) - { - return; - } - if(mImpl->mWaitingList.empty()) - { - mImpl->mVOCachePartition->setCullHistory(FALSE); - return; - } - - S32 throttle = sNewObjectCreationThrottle; - BOOL has_new_obj = FALSE; - LLTimer update_timer; - for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin(); - iter != mImpl->mWaitingList.end(); ++iter) - { - LLVOCacheEntry* vo_entry = *iter; - - if(vo_entry->getState() < LLVOCacheEntry::WAITING) - { - addNewObject(vo_entry); - has_new_obj = TRUE; - if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time) - { - break; - } - } - } - - mImpl->mVOCachePartition->setCullHistory(has_new_obj); - - return; + if(mDead) + { + return; + } + if(mImpl->mWaitingList.empty()) + { + mImpl->mVOCachePartition->setCullHistory(FALSE); + return; + } + + S32 throttle = sNewObjectCreationThrottle; + BOOL has_new_obj = FALSE; + LLTimer update_timer; + for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin(); + iter != mImpl->mWaitingList.end(); ++iter) + { + LLVOCacheEntry* vo_entry = *iter; + + if(vo_entry->getState() < LLVOCacheEntry::WAITING) + { + addNewObject(vo_entry); + has_new_obj = TRUE; + if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time) + { + break; + } + } + } + + mImpl->mVOCachePartition->setCullHistory(has_new_obj); + + return; } void LLViewerRegion::clearCachedVisibleObjects() { - mImpl->mWaitingList.clear(); - mImpl->mVisibleGroups.clear(); - - //reset all occluders - mImpl->mVOCachePartition->resetOccluders(); - mPaused = TRUE; - - //clean visible entries - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) - { - LLVOCacheEntry* entry = *iter; - LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); - - if(!entry->getParentID() || parent) //no child or parent is cache-able - { - if(parent) //has a cache-able parent - { - parent->addChild(entry); - } - - LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; - ++next_iter; - mImpl->mVisibleEntries.erase(iter); - iter = next_iter; - } - else //parent is not cache-able, leave it. - { - ++iter; - } - } - - //remove all visible entries. - mLastVisitedEntry = NULL; - std::vector delete_list; - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); - iter != mImpl->mActiveSet.end(); ++iter) - { + mImpl->mWaitingList.clear(); + mImpl->mVisibleGroups.clear(); + + //reset all occluders + mImpl->mVOCachePartition->resetOccluders(); + mPaused = TRUE; + + //clean visible entries + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) + { + LLVOCacheEntry* entry = *iter; + LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); + + if(!entry->getParentID() || parent) //no child or parent is cache-able + { + if(parent) //has a cache-able parent + { + parent->addChild(entry); + } + + LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; + ++next_iter; + mImpl->mVisibleEntries.erase(iter); + iter = next_iter; + } + else //parent is not cache-able, leave it. + { + ++iter; + } + } + + //remove all visible entries. + mLastVisitedEntry = NULL; + std::vector delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { LLVOCacheEntry* vo_entry = *iter; if (!vo_entry || !vo_entry->getEntry()) { continue; } LLDrawable* drawablep = (LLDrawable*)vo_entry->getEntry()->getDrawable(); - - if(drawablep && !drawablep->getParent()) - { - delete_list.push_back(drawablep); - } - } - if(!delete_list.empty()) - { - for(S32 i = 0; i < delete_list.size(); i++) - { - gObjectList.killObject(delete_list[i]->getVObj()); - } - delete_list.clear(); - } + if(drawablep && !drawablep->getParent()) + { + delete_list.push_back(drawablep); + } + } + + if(!delete_list.empty()) + { + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + } - return; + return; } //perform some necessary but very light updates. //to replace the function idleUpdate(...) in case there is no enough time. void LLViewerRegion::lightIdleUpdate() { - if(!sVOCacheCullingEnabled) - { - return; - } - if(mImpl->mCacheMap.empty()) - { - return; - } + if(!sVOCacheCullingEnabled) + { + return; + } + if(mImpl->mCacheMap.empty()) + { + return; + } - //reset all occluders - mImpl->mVOCachePartition->resetOccluders(); + //reset all occluders + mImpl->mVOCachePartition->resetOccluders(); } void LLViewerRegion::idleUpdate(F32 max_update_time) -{ +{ LL_PROFILE_ZONE_SCOPED; - LLTimer update_timer; - F32 max_time; + LLTimer update_timer; + F32 max_time; - mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame(); + mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame(); static LLCachedControl pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false); @@ -1631,48 +1631,48 @@ void LLViewerRegion::idleUpdate(F32 max_update_time) { mImpl->mLandp->idleUpdate(max_update_time); } - - if (mParcelOverlay) - { - // Hopefully not a significant time sink... - mParcelOverlay->idleUpdate(); - } - if(!sVOCacheCullingEnabled) - { - return; - } - if(mImpl->mCacheMap.empty()) - { - return; - } - if(mPaused) - { - mPaused = FALSE; //unpause. - } + if (mParcelOverlay) + { + // Hopefully not a significant time sink... + mParcelOverlay->idleUpdate(); + } + + if(!sVOCacheCullingEnabled) + { + return; + } + if(mImpl->mCacheMap.empty()) + { + return; + } + if(mPaused) + { + mPaused = FALSE; //unpause. + } - LLViewerCamera::eCameraID old_camera_id = LLViewerCamera::sCurCameraID; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + LLViewerCamera::eCameraID old_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - //reset all occluders - mImpl->mVOCachePartition->resetOccluders(); + //reset all occluders + mImpl->mVOCachePartition->resetOccluders(); - max_time = max_update_time - update_timer.getElapsedTimeF32(); + max_time = max_update_time - update_timer.getElapsedTimeF32(); - //kill invisible objects - killInvisibleObjects(max_time * 0.4f); - max_time = max_update_time - update_timer.getElapsedTimeF32(); + //kill invisible objects + killInvisibleObjects(max_time * 0.4f); + max_time = max_update_time - update_timer.getElapsedTimeF32(); - updateVisibleEntries(max_time); - max_time = max_update_time - update_timer.getElapsedTimeF32(); + updateVisibleEntries(max_time); + max_time = max_update_time - update_timer.getElapsedTimeF32(); - createVisibleObjects(max_time); + createVisibleObjects(max_time); - mImpl->mWaitingList.clear(); - mImpl->mVisibleGroups.clear(); + mImpl->mWaitingList.clear(); + mImpl->mVisibleGroups.clear(); - LLViewerCamera::sCurCameraID = old_camera_id; - return; + LLViewerCamera::sCurCameraID = old_camera_id; + return; } // static @@ -1688,395 +1688,395 @@ void LLViewerRegion::idleCleanup(F32 max_update_time) //update the throttling number for new object creation void LLViewerRegion::calcNewObjectCreationThrottle() { - static LLCachedControl new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle"); - static LLCachedControl throttle_delay_time(gSavedSettings,"NewObjectCreationThrottleDelayTime"); - static LLFrameTimer timer; - - // - //sNewObjectCreationThrottle = - //-2: throttle is disabled because either the screen is showing progress view, or immediate after the screen is not black - //-1: throttle is disabled by the debug setting - //0: no new object creation is allowed - //>0: valid throttling number - // - - if(gViewerWindow->getProgressView()->getVisible() && throttle_delay_time > 0.f) - { - sNewObjectCreationThrottle = -2; //cancel the throttling - timer.reset(); - } - else if(sNewObjectCreationThrottle < -1) //just recoved from the login/teleport screen - { - if(timer.getElapsedTimeF32() > throttle_delay_time) //wait for throttle_delay_time to reset the throttle - { - sNewObjectCreationThrottle = new_object_creation_throttle; //reset - if(sNewObjectCreationThrottle < -1) - { - sNewObjectCreationThrottle = -1; - } - } - } - - //update some LLVOCacheEntry debug setting factors. - LLVOCacheEntry::updateDebugSettings(); + static LLCachedControl new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle"); + static LLCachedControl throttle_delay_time(gSavedSettings,"NewObjectCreationThrottleDelayTime"); + static LLFrameTimer timer; + + // + //sNewObjectCreationThrottle = + //-2: throttle is disabled because either the screen is showing progress view, or immediate after the screen is not black + //-1: throttle is disabled by the debug setting + //0: no new object creation is allowed + //>0: valid throttling number + // + + if(gViewerWindow->getProgressView()->getVisible() && throttle_delay_time > 0.f) + { + sNewObjectCreationThrottle = -2; //cancel the throttling + timer.reset(); + } + else if(sNewObjectCreationThrottle < -1) //just recoved from the login/teleport screen + { + if(timer.getElapsedTimeF32() > throttle_delay_time) //wait for throttle_delay_time to reset the throttle + { + sNewObjectCreationThrottle = new_object_creation_throttle; //reset + if(sNewObjectCreationThrottle < -1) + { + sNewObjectCreationThrottle = -1; + } + } + } + + //update some LLVOCacheEntry debug setting factors. + LLVOCacheEntry::updateDebugSettings(); } BOOL LLViewerRegion::isViewerCameraStatic() { - return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame(); + return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame(); } void LLViewerRegion::killInvisibleObjects(F32 max_time) { #if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory. // because of this, every time you turn around the simulator sends a swarm of full object update messages from cache - // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to + // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to // appear in the scene when flying back and forth between regions - if(!sVOCacheCullingEnabled) - { - return; - } - if(mImpl->mActiveSet.empty()) - { - return; - } - if(sNewObjectCreationThrottle < 0) - { - return; - } - - LLTimer update_timer; - LLVector4a camera_origin; - camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); - LLVector4a local_origin; - local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV); - F32 back_threshold = LLVOCacheEntry::sRearFarRadius; - - size_t max_update = 64; - if(!mInvisibilityCheckHistory && isViewerCameraStatic()) - { - //history is clean, reduce number of checking - max_update /= 2; - } - - std::vector delete_list; - S32 update_counter = llmin(max_update, mImpl->mActiveSet.size()); - LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(mLastVisitedEntry); - - for(; update_counter > 0; --update_counter, ++iter) - { - if(iter == mImpl->mActiveSet.end()) - { - iter = mImpl->mActiveSet.begin(); - } - if((*iter)->getParentID() > 0) - { - continue; //skip child objects, they are removed with their parent. - } - - LLVOCacheEntry* vo_entry = *iter; - if(!vo_entry->isAnyVisible(camera_origin, local_origin, back_threshold) && vo_entry->mLastCameraUpdated < sLastCameraUpdated) - { - killObject(vo_entry, delete_list); - } - - if(max_time < update_timer.getElapsedTimeF32()) //time out - { - break; - } - } - - if(iter == mImpl->mActiveSet.end()) - { - mLastVisitedEntry = NULL; - } - else - { - mLastVisitedEntry = *iter; - } - - mInvisibilityCheckHistory <<= 1; - if(!delete_list.empty()) - { - mInvisibilityCheckHistory |= 1; - S32 count = delete_list.size(); - for(S32 i = 0; i < count; i++) - { - gObjectList.killObject(delete_list[i]->getVObj()); - } - delete_list.clear(); - } - - return; -#endif -} - -void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) -{ - //kill the object. - LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); - llassert(drawablep); - llassert(drawablep->getRegion() == this); - - if(drawablep && !drawablep->getParent()) - { - LLViewerObject* v_obj = drawablep->getVObj(); - if (v_obj->isSelected() - || (v_obj->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(v_obj->getID()))) - { - // do not remove objects user is interacting with - ((LLViewerOctreeEntryData*)drawablep)->setVisible(); - return; - } - LLViewerObject::const_child_list_t& child_list = v_obj->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - if(child->mDrawable) - { - if( !child->mDrawable->getEntry() - || !child->mDrawable->getEntry()->hasVOCacheEntry() - || child->isSelected() - || (child->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(child->getID()))) - { - //do not remove parent if any of its children non-cacheable, animating or selected - //especially for the case that an avatar sits on a cache-able object - ((LLViewerOctreeEntryData*)drawablep)->setVisible(); - return; - } - - LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)child->mDrawable->getGroup(); - if(group && group->isAnyRecentlyVisible()) - { - //set the parent visible if any of its children visible. - ((LLViewerOctreeEntryData*)drawablep)->setVisible(); - return; - } - } - } - delete_list.push_back(drawablep); - } + if(!sVOCacheCullingEnabled) + { + return; + } + if(mImpl->mActiveSet.empty()) + { + return; + } + if(sNewObjectCreationThrottle < 0) + { + return; + } + + LLTimer update_timer; + LLVector4a camera_origin; + camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); + LLVector4a local_origin; + local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV); + F32 back_threshold = LLVOCacheEntry::sRearFarRadius; + + size_t max_update = 64; + if(!mInvisibilityCheckHistory && isViewerCameraStatic()) + { + //history is clean, reduce number of checking + max_update /= 2; + } + + std::vector delete_list; + S32 update_counter = llmin(max_update, mImpl->mActiveSet.size()); + LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(mLastVisitedEntry); + + for(; update_counter > 0; --update_counter, ++iter) + { + if(iter == mImpl->mActiveSet.end()) + { + iter = mImpl->mActiveSet.begin(); + } + if((*iter)->getParentID() > 0) + { + continue; //skip child objects, they are removed with their parent. + } + + LLVOCacheEntry* vo_entry = *iter; + if(!vo_entry->isAnyVisible(camera_origin, local_origin, back_threshold) && vo_entry->mLastCameraUpdated < sLastCameraUpdated) + { + killObject(vo_entry, delete_list); + } + + if(max_time < update_timer.getElapsedTimeF32()) //time out + { + break; + } + } + + if(iter == mImpl->mActiveSet.end()) + { + mLastVisitedEntry = NULL; + } + else + { + mLastVisitedEntry = *iter; + } + + mInvisibilityCheckHistory <<= 1; + if(!delete_list.empty()) + { + mInvisibilityCheckHistory |= 1; + S32 count = delete_list.size(); + for(S32 i = 0; i < count; i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + } + + return; +#endif +} + +void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) +{ + //kill the object. + LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); + llassert(drawablep); + llassert(drawablep->getRegion() == this); + + if(drawablep && !drawablep->getParent()) + { + LLViewerObject* v_obj = drawablep->getVObj(); + if (v_obj->isSelected() + || (v_obj->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(v_obj->getID()))) + { + // do not remove objects user is interacting with + ((LLViewerOctreeEntryData*)drawablep)->setVisible(); + return; + } + LLViewerObject::const_child_list_t& child_list = v_obj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if(child->mDrawable) + { + if( !child->mDrawable->getEntry() + || !child->mDrawable->getEntry()->hasVOCacheEntry() + || child->isSelected() + || (child->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(child->getID()))) + { + //do not remove parent if any of its children non-cacheable, animating or selected + //especially for the case that an avatar sits on a cache-able object + ((LLViewerOctreeEntryData*)drawablep)->setVisible(); + return; + } + + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)child->mDrawable->getGroup(); + if(group && group->isAnyRecentlyVisible()) + { + //set the parent visible if any of its children visible. + ((LLViewerOctreeEntryData*)drawablep)->setVisible(); + return; + } + } + } + delete_list.push_back(drawablep); + } } LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) { - if(!entry || !entry->getEntry()) - { - if(entry) - { - mImpl->mVisibleEntries.erase(entry); - entry->setState(LLVOCacheEntry::INACTIVE); - } - return NULL; - } - - LLViewerObject* obj = NULL; - if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet - { - //add the object - obj = gObjectList.processObjectUpdateFromCache(entry, this); - if(obj) - { - if(!entry->isState(LLVOCacheEntry::ACTIVE)) - { - mImpl->mWaitingSet.insert(entry); - entry->setState(LLVOCacheEntry::WAITING); - } - } - } - else - { - LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion(); - if(old_regionp != this) - { - //this object exists in two regions at the same time; - //this case can be safely ignored here because - //server should soon send update message to remove one region for this object. - - LL_WARNS() << "Entry: " << entry->getLocalID() << " exists in two regions at the same time." << LL_ENDL; - return NULL; - } - - LL_WARNS() << "Entry: " << entry->getLocalID() << " in rendering pipeline but not set to be active." << LL_ENDL; - - //should not hit here any more, but does not hurt either, just put it back to active list - addActiveCacheEntry(entry); - } - - return obj; + if(!entry || !entry->getEntry()) + { + if(entry) + { + mImpl->mVisibleEntries.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); + } + return NULL; + } + + LLViewerObject* obj = NULL; + if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet + { + //add the object + obj = gObjectList.processObjectUpdateFromCache(entry, this); + if(obj) + { + if(!entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mWaitingSet.insert(entry); + entry->setState(LLVOCacheEntry::WAITING); + } + } + } + else + { + LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion(); + if(old_regionp != this) + { + //this object exists in two regions at the same time; + //this case can be safely ignored here because + //server should soon send update message to remove one region for this object. + + LL_WARNS() << "Entry: " << entry->getLocalID() << " exists in two regions at the same time." << LL_ENDL; + return NULL; + } + + LL_WARNS() << "Entry: " << entry->getLocalID() << " in rendering pipeline but not set to be active." << LL_ENDL; + + //should not hit here any more, but does not hurt either, just put it back to active list + addActiveCacheEntry(entry); + } + + return obj; } //update object cache if the object receives a full-update or terse update //update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp) { - LLVOCacheEntry* entry = getCacheEntry(local_id); - if (!entry) - { - return objectp; //not in the cache, do nothing. - } - if(!objectp) //object not created - { - //create a new object from cache. - objectp = addNewObject(entry); - } + LLVOCacheEntry* entry = getCacheEntry(local_id); + if (!entry) + { + return objectp; //not in the cache, do nothing. + } + if(!objectp) //object not created + { + //create a new object from cache. + objectp = addNewObject(entry); + } //remove from cache. killCacheEntry(entry, true); - return objectp; + return objectp; } // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() { - constexpr F32 max_update_time = 0.f; + constexpr F32 max_update_time = 0.f; static LLCachedControl pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false); - bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); - bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; + bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); + bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; - if (!pbr_land) - { - mImpl->mLandp->idleUpdate(max_update_time); - } - else - { - mImpl->mLandp->idleUpdate(max_update_time); - } + if (!pbr_land) + { + mImpl->mLandp->idleUpdate(max_update_time); + } + else + { + mImpl->mLandp->idleUpdate(max_update_time); + } - if (mParcelOverlay) - { - mParcelOverlay->idleUpdate(true); - } + if (mParcelOverlay) + { + mParcelOverlay->idleUpdate(true); + } } void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction) { - mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction); + mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction); } void LLViewerRegion::disconnectAllNeighbors() { - mImpl->mLandp->disconnectAllNeighbors(); + mImpl->mLandp->disconnectAllNeighbors(); } LLVLComposition * LLViewerRegion::getComposition() const { - return mImpl->mCompositionp; + return mImpl->mCompositionp; } F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const { - if (x >= 256) - { - if (y >= 256) - { - LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f); - LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); - if (regionp) - { - // OK, we need to do some hackery here - different simulators no longer use - // the same composition values, necessarily. - // If we're attempting to blend, then we want to make the fractional part of - // this region match the fractional of the adjacent. For now, just minimize - // the delta. - F32 our_comp = getComposition()->getValueScaled(255, 255); - F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f); - while (llabs(our_comp - adj_comp) >= 1.f) - { - if (our_comp > adj_comp) - { - adj_comp += 1.f; - } - else - { - adj_comp -= 1.f; - } - } - return adj_comp; - } - } - else - { - LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f); - LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); - if (regionp) - { - // OK, we need to do some hackery here - different simulators no longer use - // the same composition values, necessarily. - // If we're attempting to blend, then we want to make the fractional part of - // this region match the fractional of the adjacent. For now, just minimize - // the delta. - F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y); - F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y); - while (llabs(our_comp - adj_comp) >= 1.f) - { - if (our_comp > adj_comp) - { - adj_comp += 1.f; - } - else - { - adj_comp -= 1.f; - } - } - return adj_comp; - } - } - } - else if (y >= 256) - { - LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f); - LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); - if (regionp) - { - // OK, we need to do some hackery here - different simulators no longer use - // the same composition values, necessarily. - // If we're attempting to blend, then we want to make the fractional part of - // this region match the fractional of the adjacent. For now, just minimize - // the delta. - F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f); - F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f); - while (llabs(our_comp - adj_comp) >= 1.f) - { - if (our_comp > adj_comp) - { - adj_comp += 1.f; - } - else - { - adj_comp -= 1.f; - } - } - return adj_comp; - } - } - - return getComposition()->getValueScaled((F32)x, (F32)y); -} - -void LLViewerRegion::calculateCenterGlobal() -{ - mImpl->mCenterGlobal = mImpl->mOriginGlobal; - mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth; - mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth; - mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ(); + if (x >= 256) + { + if (y >= 256) + { + LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); + if (regionp) + { + // OK, we need to do some hackery here - different simulators no longer use + // the same composition values, necessarily. + // If we're attempting to blend, then we want to make the fractional part of + // this region match the fractional of the adjacent. For now, just minimize + // the delta. + F32 our_comp = getComposition()->getValueScaled(255, 255); + F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f); + while (llabs(our_comp - adj_comp) >= 1.f) + { + if (our_comp > adj_comp) + { + adj_comp += 1.f; + } + else + { + adj_comp -= 1.f; + } + } + return adj_comp; + } + } + else + { + LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); + if (regionp) + { + // OK, we need to do some hackery here - different simulators no longer use + // the same composition values, necessarily. + // If we're attempting to blend, then we want to make the fractional part of + // this region match the fractional of the adjacent. For now, just minimize + // the delta. + F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y); + F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y); + while (llabs(our_comp - adj_comp) >= 1.f) + { + if (our_comp > adj_comp) + { + adj_comp += 1.f; + } + else + { + adj_comp -= 1.f; + } + } + return adj_comp; + } + } + } + else if (y >= 256) + { + LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); + if (regionp) + { + // OK, we need to do some hackery here - different simulators no longer use + // the same composition values, necessarily. + // If we're attempting to blend, then we want to make the fractional part of + // this region match the fractional of the adjacent. For now, just minimize + // the delta. + F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f); + F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f); + while (llabs(our_comp - adj_comp) >= 1.f) + { + if (our_comp > adj_comp) + { + adj_comp += 1.f; + } + else + { + adj_comp -= 1.f; + } + } + return adj_comp; + } + } + + return getComposition()->getValueScaled((F32)x, (F32)y); +} + +void LLViewerRegion::calculateCenterGlobal() +{ + mImpl->mCenterGlobal = mImpl->mOriginGlobal; + mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth; + mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth; + mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ(); } void LLViewerRegion::calculateCameraDistance() { - mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared(); + mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared(); } std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion) { - s << "{ "; - s << region.mImpl->mHost; - s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n"; + s << "{ "; + s << region.mImpl->mHost; + s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n"; std::string name(region.getName()), zone(region.getZoning()); if (! name.empty()) { @@ -2086,8 +2086,8 @@ std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion) { s << " mZoning = " << zone << '\n'; } - s << "}"; - return s; + s << "}"; + return s; } @@ -2095,143 +2095,143 @@ std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion) void LLViewerRegion::updateNetStats() { - F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32(); + F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32(); - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost); - if (!cdp) - { - mAlive = false; - return; - } + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost); + if (!cdp) + { + mAlive = false; + return; + } - mAlive = true; - mDeltaTime = dt; + mAlive = true; + mDeltaTime = dt; - mLastPacketsIn = mPacketsIn; - mLastBitsIn = mBitsIn; - mLastPacketsOut = mPacketsOut; - mLastPacketsLost = mPacketsLost; + mLastPacketsIn = mPacketsIn; + mLastBitsIn = mBitsIn; + mLastPacketsOut = mPacketsOut; + mLastPacketsLost = mPacketsLost; - mPacketsIn = cdp->getPacketsIn(); - mBitsIn = 8 * cdp->getBytesIn(); - mPacketsOut = cdp->getPacketsOut(); - mPacketsLost = cdp->getPacketsLost(); - mPingDelay = cdp->getPingDelay(); + mPacketsIn = cdp->getPacketsIn(); + mBitsIn = 8 * cdp->getBytesIn(); + mPacketsOut = cdp->getPacketsOut(); + mPacketsLost = cdp->getPacketsLost(); + mPingDelay = cdp->getPingDelay(); - mBitsReceived += mBitsIn - mLastBitsIn; - mPacketsReceived += mPacketsIn - mLastPacketsIn; + mBitsReceived += mBitsIn - mLastBitsIn; + mPacketsReceived += mPacketsIn - mLastPacketsIn; } U32 LLViewerRegion::getPacketsLost() const { - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost); - if (!cdp) - { - LL_INFOS() << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << LL_ENDL; - return 0; - } - else - { - return cdp->getPacketsLost(); - } + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost); + if (!cdp) + { + LL_INFOS() << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << LL_ENDL; + return 0; + } + else + { + return cdp->getPacketsLost(); + } } S32 LLViewerRegion::getHttpResponderID() const { - return mImpl->mHttpResponderID; + return mImpl->mHttpResponderID; } BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const { - LLVector3 pos_region = getPosRegionFromGlobal(point_global); - - if (pos_region.mV[VX] < 0) - { - return FALSE; - } - if (pos_region.mV[VX] >= mWidth) - { - return FALSE; - } - if (pos_region.mV[VY] < 0) - { - return FALSE; - } - if (pos_region.mV[VY] >= mWidth) - { - return FALSE; - } - return TRUE; + LLVector3 pos_region = getPosRegionFromGlobal(point_global); + + if (pos_region.mV[VX] < 0) + { + return FALSE; + } + if (pos_region.mV[VX] >= mWidth) + { + return FALSE; + } + if (pos_region.mV[VY] < 0) + { + return FALSE; + } + if (pos_region.mV[VY] >= mWidth) + { + return FALSE; + } + return TRUE; } LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const { - LLVector3 pos_region; - pos_region.setVec(point_global - mImpl->mOriginGlobal); - return pos_region; + LLVector3 pos_region; + pos_region.setVec(point_global - mImpl->mOriginGlobal); + return pos_region; } LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const { - LLVector3d pos_region_d; - pos_region_d.setVec(pos_region); - return pos_region_d + mImpl->mOriginGlobal; + LLVector3d pos_region_d; + pos_region_d.setVec(pos_region); + return pos_region_d + mImpl->mOriginGlobal; } LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const { - LLVector3d pos_global = getPosGlobalFromRegion(pos_region); + LLVector3d pos_global = getPosGlobalFromRegion(pos_region); - return gAgent.getPosAgentFromGlobal(pos_global); + return gAgent.getPosAgentFromGlobal(pos_global); } LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const { - return pos_agent - getOriginAgent(); + return pos_agent - getOriginAgent(); } F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos) { - return mImpl->mLandp->resolveHeightRegion( region_pos ); + return mImpl->mLandp->resolveHeightRegion( region_pos ); } bool LLViewerRegion::isAlive() { - return mAlive; + return mAlive; } BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos) { - if (mParcelOverlay) - { - return mParcelOverlay->isOwnedSelf(pos); - } else { - return FALSE; - } + if (mParcelOverlay) + { + return mParcelOverlay->isOwnedSelf(pos); + } else { + return FALSE; + } } // Owned by a group you belong to? (officer or member) BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos) { - if (mParcelOverlay) - { - return mParcelOverlay->isOwnedGroup(pos); - } else { - return FALSE; - } + if (mParcelOverlay) + { + return mParcelOverlay->isOwnedGroup(pos); + } else { + return FALSE; + } } // the new TCP coarse location handler node class CoarseLocationUpdate : public LLHTTPNode { public: - virtual void post( - ResponsePtr responder, - const LLSD& context, - const LLSD& input) const - { - LLHost host(input["sender"].asString()); + virtual void post( + ResponsePtr responder, + const LLSD& context, + const LLSD& input) const + { + LLHost host(input["sender"].asString()); LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton! if (!world_inst) @@ -2239,151 +2239,151 @@ public: return; } - LLViewerRegion* region = world_inst->getRegion(host); - if( !region ) - { - return; - } - - S32 target_index = input["body"]["Index"][0]["Prey"].asInteger(); - S32 you_index = input["body"]["Index"][0]["You" ].asInteger(); - - std::vector* avatar_locs = ®ion->mMapAvatars; - std::vector* avatar_ids = ®ion->mMapAvatarIDs; - avatar_locs->clear(); - avatar_ids->clear(); - - //LL_INFOS() << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << LL_ENDL; - //LL_INFOS() << "my agent id = " << gAgent.getID() << LL_ENDL; - //LL_INFOS() << ll_pretty_print_sd(input) << LL_ENDL; - - LLSD - locs = input["body"]["Location"], - agents = input["body"]["AgentData"]; - LLSD::array_iterator - locs_it = locs.beginArray(), - agents_it = agents.beginArray(); - BOOL has_agent_data = input["body"].has("AgentData"); - - for(int i=0; - locs_it != locs.endArray(); - i++, locs_it++) - { - U8 - x = locs_it->get("X").asInteger(), - y = locs_it->get("Y").asInteger(), - z = locs_it->get("Z").asInteger(); - // treat the target specially for the map, and don't add you or the target - if(i == target_index) - { - LLVector3d global_pos(region->getOriginGlobal()); - global_pos.mdV[VX] += (F64)x; - global_pos.mdV[VY] += (F64)y; - global_pos.mdV[VZ] += (F64)z * 4.0; - LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); - } - else if( i != you_index) - { - U32 pos = 0x0; - pos |= x; - pos <<= 8; - pos |= y; - pos <<= 8; - pos |= z; - avatar_locs->push_back(pos); - //LL_INFOS() << "next pos: " << x << "," << y << "," << z << ": " << pos << LL_ENDL; - if(has_agent_data) // for backwards compatibility with old message format - { - LLUUID agent_id(agents_it->get("AgentID").asUUID()); - //LL_INFOS() << "next agent: " << agent_id.asString() << LL_ENDL; - avatar_ids->push_back(agent_id); - } - } - if (has_agent_data) - { - agents_it++; - } - } - } + LLViewerRegion* region = world_inst->getRegion(host); + if( !region ) + { + return; + } + + S32 target_index = input["body"]["Index"][0]["Prey"].asInteger(); + S32 you_index = input["body"]["Index"][0]["You" ].asInteger(); + + std::vector* avatar_locs = ®ion->mMapAvatars; + std::vector* avatar_ids = ®ion->mMapAvatarIDs; + avatar_locs->clear(); + avatar_ids->clear(); + + //LL_INFOS() << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << LL_ENDL; + //LL_INFOS() << "my agent id = " << gAgent.getID() << LL_ENDL; + //LL_INFOS() << ll_pretty_print_sd(input) << LL_ENDL; + + LLSD + locs = input["body"]["Location"], + agents = input["body"]["AgentData"]; + LLSD::array_iterator + locs_it = locs.beginArray(), + agents_it = agents.beginArray(); + BOOL has_agent_data = input["body"].has("AgentData"); + + for(int i=0; + locs_it != locs.endArray(); + i++, locs_it++) + { + U8 + x = locs_it->get("X").asInteger(), + y = locs_it->get("Y").asInteger(), + z = locs_it->get("Z").asInteger(); + // treat the target specially for the map, and don't add you or the target + if(i == target_index) + { + LLVector3d global_pos(region->getOriginGlobal()); + global_pos.mdV[VX] += (F64)x; + global_pos.mdV[VY] += (F64)y; + global_pos.mdV[VZ] += (F64)z * 4.0; + LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); + } + else if( i != you_index) + { + U32 pos = 0x0; + pos |= x; + pos <<= 8; + pos |= y; + pos <<= 8; + pos |= z; + avatar_locs->push_back(pos); + //LL_INFOS() << "next pos: " << x << "," << y << "," << z << ": " << pos << LL_ENDL; + if(has_agent_data) // for backwards compatibility with old message format + { + LLUUID agent_id(agents_it->get("AgentID").asUUID()); + //LL_INFOS() << "next agent: " << agent_id.asString() << LL_ENDL; + avatar_ids->push_back(agent_id); + } + } + if (has_agent_data) + { + agents_it++; + } + } + } }; // build the coarse location HTTP node under the "/message" URL LLHTTPRegistration gHTTPRegistrationCoarseLocationUpdate( - "/message/CoarseLocationUpdate"); + "/message/CoarseLocationUpdate"); // the deprecated coarse location handler void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg) { - //LL_INFOS() << "CoarseLocationUpdate" << LL_ENDL; - mMapAvatars.clear(); - mMapAvatarIDs.clear(); // only matters in a rare case but it's good to be safe. - - U8 x_pos = 0; - U8 y_pos = 0; - U8 z_pos = 0; - - U32 pos = 0x0; - - S16 agent_index; - S16 target_index; - msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index); - msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index); - - BOOL has_agent_data = msg->has(_PREHASH_AgentData); - S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location); - for(S32 i = 0; i < count; i++) - { - msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i); - msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i); - msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i); - LLUUID agent_id = LLUUID::null; - if(has_agent_data) - { - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i); - } - - //LL_INFOS() << " object X: " << (S32)x_pos << " Y: " << (S32)y_pos - // << " Z: " << (S32)(z_pos * 4) - // << LL_ENDL; - - // treat the target specially for the map - if(i == target_index) - { - LLVector3d global_pos(mImpl->mOriginGlobal); - global_pos.mdV[VX] += (F64)(x_pos); - global_pos.mdV[VY] += (F64)(y_pos); - global_pos.mdV[VZ] += (F64)(z_pos) * 4.0; - LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); - } - - //don't add you - if( i != agent_index) - { - pos = 0x0; - pos |= x_pos; - pos <<= 8; - pos |= y_pos; - pos <<= 8; - pos |= z_pos; - mMapAvatars.push_back(pos); - if(has_agent_data) - { - mMapAvatarIDs.push_back(agent_id); - } - } - } + //LL_INFOS() << "CoarseLocationUpdate" << LL_ENDL; + mMapAvatars.clear(); + mMapAvatarIDs.clear(); // only matters in a rare case but it's good to be safe. + + U8 x_pos = 0; + U8 y_pos = 0; + U8 z_pos = 0; + + U32 pos = 0x0; + + S16 agent_index; + S16 target_index; + msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index); + msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index); + + BOOL has_agent_data = msg->has(_PREHASH_AgentData); + S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location); + for(S32 i = 0; i < count; i++) + { + msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i); + msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i); + msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i); + LLUUID agent_id = LLUUID::null; + if(has_agent_data) + { + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i); + } + + //LL_INFOS() << " object X: " << (S32)x_pos << " Y: " << (S32)y_pos + // << " Z: " << (S32)(z_pos * 4) + // << LL_ENDL; + + // treat the target specially for the map + if(i == target_index) + { + LLVector3d global_pos(mImpl->mOriginGlobal); + global_pos.mdV[VX] += (F64)(x_pos); + global_pos.mdV[VY] += (F64)(y_pos); + global_pos.mdV[VZ] += (F64)(z_pos) * 4.0; + LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); + } + + //don't add you + if( i != agent_index) + { + pos = 0x0; + pos |= x_pos; + pos <<= 8; + pos |= y_pos; + pos <<= 8; + pos |= z_pos; + mMapAvatars.push_back(pos); + if(has_agent_data) + { + mMapAvatarIDs.push_back(agent_id); + } + } + } } void LLViewerRegion::getInfo(LLSD& info) { - info["Region"]["Host"] = getHost().getIPandPort(); - info["Region"]["Name"] = getName(); - U32 x, y; - from_region_handle(getHandle(), &x, &y); - info["Region"]["Handle"]["x"] = (LLSD::Integer)x; - info["Region"]["Handle"]["y"] = (LLSD::Integer)y; + info["Region"]["Host"] = getHost().getIPandPort(); + info["Region"]["Name"] = getName(); + U32 x, y; + from_region_handle(getHandle(), &x, &y); + info["Region"]["Handle"]["x"] = (LLSD::Integer)x; + info["Region"]["Handle"]["y"] = (LLSD::Integer)y; } void LLViewerRegion::requestSimulatorFeatures() @@ -2402,7 +2402,7 @@ void LLViewerRegion::requestSimulatorFeatures() // launch() acts like a suspend() // Make sure we are still good to do LLCoros::checkStop(); - + LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL; } else @@ -2413,44 +2413,44 @@ void LLViewerRegion::requestSimulatorFeatures() boost::signals2::connection LLViewerRegion::setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb) { - return mSimulatorFeaturesReceivedSignal.connect(cb); + return mSimulatorFeaturesReceivedSignal.connect(cb); } void LLViewerRegion::setSimulatorFeaturesReceived(bool received) { - mSimulatorFeaturesReceived = received; - if (received) - { - mSimulatorFeaturesReceivedSignal(getRegionID(), this); - mSimulatorFeaturesReceivedSignal.disconnect_all_slots(); - } + mSimulatorFeaturesReceived = received; + if (received) + { + mSimulatorFeaturesReceivedSignal(getRegionID(), this); + mSimulatorFeaturesReceivedSignal.disconnect_all_slots(); + } } bool LLViewerRegion::simulatorFeaturesReceived() const { - return mSimulatorFeaturesReceived; + return mSimulatorFeaturesReceived; } void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const { - sim_features = mSimulatorFeatures; + sim_features = mSimulatorFeatures; } void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) { - std::stringstream str; - - LLSDSerialize::toPrettyXML(sim_features, str); - LL_INFOS() << "region " << getName() << " " << str.str() << LL_ENDL; - mSimulatorFeatures = sim_features; + std::stringstream str; - setSimulatorFeaturesReceived(true); + LLSDSerialize::toPrettyXML(sim_features, str); + LL_INFOS() << "region " << getName() << " " << str.str() << LL_ENDL; + mSimulatorFeatures = sim_features; - // WARNING: this is called from a coroutine, and flipping saved settings has a LOT of side effects, shuttle + setSimulatorFeaturesReceived(true); + + // WARNING: this is called from a coroutine, and flipping saved settings has a LOT of side effects, shuttle // the work below back to the main loop - // - + // + // copy features to lambda in case the region is deleted before the lambda is executed LLSD features = mSimulatorFeatures; @@ -2501,252 +2501,252 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) //move all orphan children out of cache and insert to rendering octree. void LLViewerRegion::findOrphans(U32 parent_id) { - orphan_list_t::iterator iter = mOrphanMap.find(parent_id); - if(iter != mOrphanMap.end()) - { - std::vector* children = &mOrphanMap[parent_id]; - for(S32 i = 0; i < children->size(); i++) - { - //parent is visible, so is the child. - addVisibleChildCacheEntry(NULL, getCacheEntry((*children)[i])); - } - children->clear(); - mOrphanMap.erase(parent_id); - } + orphan_list_t::iterator iter = mOrphanMap.find(parent_id); + if(iter != mOrphanMap.end()) + { + std::vector* children = &mOrphanMap[parent_id]; + for(S32 i = 0; i < children->size(); i++) + { + //parent is visible, so is the child. + addVisibleChildCacheEntry(NULL, getCacheEntry((*children)[i])); + } + children->clear(); + mOrphanMap.erase(parent_id); + } } void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) { - if(!sVOCacheCullingEnabled) - { - gObjectList.processObjectUpdateFromCache(entry, this); - return; - } - if(!entry || !entry->isValid()) - { - return; - } - - if(!entry->getEntry()) - { - entry->setOctreeEntry(NULL); - } - - if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline - { - LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion(); - if(old_regionp != this && old_regionp) - { - LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj(); - if(obj) - { - //remove from old region - old_regionp->killCacheEntry(obj->getLocalID()); - - //change region - obj->setRegion(this); - } - } - - addActiveCacheEntry(entry); - - //set parent id - U32 parent_id = 0; + if(!sVOCacheCullingEnabled) + { + gObjectList.processObjectUpdateFromCache(entry, this); + return; + } + if(!entry || !entry->isValid()) + { + return; + } + + if(!entry->getEntry()) + { + entry->setOctreeEntry(NULL); + } + + if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline + { + LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion(); + if(old_regionp != this && old_regionp) + { + LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj(); + if(obj) + { + //remove from old region + old_regionp->killCacheEntry(obj->getLocalID()); + + //change region + obj->setRegion(this); + } + } + + addActiveCacheEntry(entry); + + //set parent id + U32 parent_id = 0; if (entry->getDP()) // NULL if nothing cached { LLViewerObject::unpackParentID(entry->getDP(), parent_id); } - if(parent_id != entry->getParentID()) - { - entry->setParentID(parent_id); - } - - //update the object - gObjectList.processObjectUpdateFromCache(entry, this); - return; //done - } - - //must not be active. - llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE)); - removeFromVOCacheTree(entry); //remove from cache octree if it is in. - - LLVector3 pos; - LLVector3 scale; - LLQuaternion rot; - - //decode spatial info and parent info - U32 parent_id = entry->getDP() ? LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot) : entry->getParentID(); - - U32 old_parent_id = entry->getParentID(); - bool same_old_parent = false; - if(parent_id != old_parent_id) //parent changed. - { - if(old_parent_id > 0) //has an old parent, disconnect it - { - LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id); - if(old_parent) - { - old_parent->removeChild(entry); - if(!old_parent->isState(LLVOCacheEntry::INACTIVE)) - { - mImpl->mVisibleEntries.erase(entry); - entry->setState(LLVOCacheEntry::INACTIVE); - } - } - } - entry->setParentID(parent_id); - } - else - { - same_old_parent = true; - } - - if(parent_id > 0) //has a new parent - { - //1, find the parent in cache - LLVOCacheEntry* parent = getCacheEntry(parent_id); - - //2, parent is not in the cache, put into the orphan list. - if(!parent) - { - if(!same_old_parent) - { - //check if parent is non-cacheable and already created - if(isNonCacheableObjectCreated(parent_id)) - { - //parent is visible, so is the child. - addVisibleChildCacheEntry(NULL, entry); - } - else - { - entry->setBoundingInfo(pos, scale); - mOrphanMap[parent_id].push_back(entry->getLocalID()); - } - } - else - { - entry->setBoundingInfo(pos, scale); - } - } - else //parent in cache. - { - if(!parent->isState(LLVOCacheEntry::INACTIVE)) - { - //parent is visible, so is the child. - addVisibleChildCacheEntry(parent, entry); - } - else - { - entry->setBoundingInfo(pos, scale); - parent->addChild(entry); - - if(parent->getGroup()) //re-insert parent to vo-cache tree because its bounding info changed. - { - removeFromVOCacheTree(parent); - addToVOCacheTree(parent); - } - } - } - - return; - } - - // - //no parent - // - entry->setBoundingInfo(pos, scale); - - if(!parent_id) //a potential parent - { - //find all children and update their bounding info - orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID()); - if(iter != mOrphanMap.end()) - { - std::vector* orphans = &mOrphanMap[entry->getLocalID()]; - S32 size = orphans->size(); - for(S32 i = 0; i < size; i++) - { - LLVOCacheEntry* child = getCacheEntry((*orphans)[i]); - if(child) - { - entry->addChild(child); - } - } - orphans->clear(); - mOrphanMap.erase(entry->getLocalID()); - } - } - - if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) - { - addToVOCacheTree(entry); - } - return ; + if(parent_id != entry->getParentID()) + { + entry->setParentID(parent_id); + } + + //update the object + gObjectList.processObjectUpdateFromCache(entry, this); + return; //done + } + + //must not be active. + llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE)); + removeFromVOCacheTree(entry); //remove from cache octree if it is in. + + LLVector3 pos; + LLVector3 scale; + LLQuaternion rot; + + //decode spatial info and parent info + U32 parent_id = entry->getDP() ? LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot) : entry->getParentID(); + + U32 old_parent_id = entry->getParentID(); + bool same_old_parent = false; + if(parent_id != old_parent_id) //parent changed. + { + if(old_parent_id > 0) //has an old parent, disconnect it + { + LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id); + if(old_parent) + { + old_parent->removeChild(entry); + if(!old_parent->isState(LLVOCacheEntry::INACTIVE)) + { + mImpl->mVisibleEntries.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); + } + } + } + entry->setParentID(parent_id); + } + else + { + same_old_parent = true; + } + + if(parent_id > 0) //has a new parent + { + //1, find the parent in cache + LLVOCacheEntry* parent = getCacheEntry(parent_id); + + //2, parent is not in the cache, put into the orphan list. + if(!parent) + { + if(!same_old_parent) + { + //check if parent is non-cacheable and already created + if(isNonCacheableObjectCreated(parent_id)) + { + //parent is visible, so is the child. + addVisibleChildCacheEntry(NULL, entry); + } + else + { + entry->setBoundingInfo(pos, scale); + mOrphanMap[parent_id].push_back(entry->getLocalID()); + } + } + else + { + entry->setBoundingInfo(pos, scale); + } + } + else //parent in cache. + { + if(!parent->isState(LLVOCacheEntry::INACTIVE)) + { + //parent is visible, so is the child. + addVisibleChildCacheEntry(parent, entry); + } + else + { + entry->setBoundingInfo(pos, scale); + parent->addChild(entry); + + if(parent->getGroup()) //re-insert parent to vo-cache tree because its bounding info changed. + { + removeFromVOCacheTree(parent); + addToVOCacheTree(parent); + } + } + } + + return; + } + + // + //no parent + // + entry->setBoundingInfo(pos, scale); + + if(!parent_id) //a potential parent + { + //find all children and update their bounding info + orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID()); + if(iter != mOrphanMap.end()) + { + std::vector* orphans = &mOrphanMap[entry->getLocalID()]; + S32 size = orphans->size(); + for(S32 i = 0; i < size; i++) + { + LLVOCacheEntry* child = getCacheEntry((*orphans)[i]); + if(child) + { + entry->addChild(child); + } + } + orphans->clear(); + mOrphanMap.erase(entry->getLocalID()); + } + } + + if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addToVOCacheTree(entry); + } + return ; } LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags) { - eCacheUpdateResult result; - U32 crc; - U32 local_id; + eCacheUpdateResult result; + U32 crc; + U32 local_id; - LLViewerObject::unpackU32(&dp, local_id, "LocalID"); - LLViewerObject::unpackU32(&dp, crc, "CRC"); + LLViewerObject::unpackU32(&dp, local_id, "LocalID"); + LLViewerObject::unpackU32(&dp, crc, "CRC"); - LLVOCacheEntry* entry = getCacheEntry(local_id, false); + LLVOCacheEntry* entry = getCacheEntry(local_id, false); - if (entry) - { - entry->setValid(); + if (entry) + { + entry->setValid(); - // we've seen this object before - if (entry->getCRC() == crc) - { + // we've seen this object before + if (entry->getCRC() == crc) + { LL_DEBUGS("AnimatedObjects") << " got dupe for local_id " << local_id << LL_ENDL; dumpStack("AnimatedObjectsStack"); - // Record a hit - entry->recordDupe(); - result = CACHE_UPDATE_DUPE; - } - else //CRC changed - { + // Record a hit + entry->recordDupe(); + result = CACHE_UPDATE_DUPE; + } + else //CRC changed + { LL_DEBUGS("AnimatedObjects") << " got update for local_id " << local_id << LL_ENDL; dumpStack("AnimatedObjectsStack"); - // Update the cache entry - entry->updateEntry(crc, dp); + // Update the cache entry + entry->updateEntry(crc, dp); - decodeBoundingInfo(entry); + decodeBoundingInfo(entry); - result = CACHE_UPDATE_CHANGED; - } - } - else - { + result = CACHE_UPDATE_CHANGED; + } + } + else + { LL_DEBUGS("AnimatedObjects") << " got first notification for local_id " << local_id << LL_ENDL; dumpStack("AnimatedObjectsStack"); - // we haven't seen this object before - // Create new entry and add to map - result = CACHE_UPDATE_ADDED; - entry = new LLVOCacheEntry(local_id, crc, dp); - record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0)); - - mImpl->mCacheMap[local_id] = entry; - - decodeBoundingInfo(entry); - } - entry->setUpdateFlags(flags); - - return result; - } + // we haven't seen this object before + // Create new entry and add to map + result = CACHE_UPDATE_ADDED; + entry = new LLVOCacheEntry(local_id, crc, dp); + record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0)); + + mImpl->mCacheMap[local_id] = entry; + + decodeBoundingInfo(entry); + } + entry->setUpdateFlags(flags); + + return result; + } LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags) { - eCacheUpdateResult result = cacheFullUpdate(dp, flags); + eCacheUpdateResult result = cacheFullUpdate(dp, flags); - return result; + return result; } void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data) @@ -2764,216 +2764,216 @@ void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) { - if(!sVOCacheCullingEnabled) - { - return NULL; - } + if(!sVOCacheCullingEnabled) + { + return NULL; + } - LLVOCacheEntry* entry = getCacheEntry(local_id); - removeFromVOCacheTree(entry); - - return entry; + LLVOCacheEntry* entry = getCacheEntry(local_id); + removeFromVOCacheTree(entry); + + return entry; } LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid) { - LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); - if(iter != mImpl->mCacheMap.end()) - { - if(!valid || iter->second->isValid()) - { - return iter->second; - } - } - return NULL; + LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); + if(iter != mImpl->mCacheMap.end()) + { + if(!valid || iter->second->isValid()) + { + return iter->second; + } + } + return NULL; } void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType cache_miss_type) { - mRegionCacheMissCount++; + mRegionCacheMissCount++; mCacheMissList.push_back(CacheMissItem(id, cache_miss_type)); } //check if a non-cacheable object is already created. bool LLViewerRegion::isNonCacheableObjectCreated(U32 local_id) { - if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end()) - { - return true; - } - return false; + if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end()) + { + return true; + } + return false; } - + void LLViewerRegion::removeFromCreatedList(U32 local_id) -{ - if(mImpl && local_id > 0) - { - std::set::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id); - if(iter != mImpl->mNonCacheableCreatedList.end()) - { - mImpl->mNonCacheableCreatedList.erase(iter); - } - } - } +{ + if(mImpl && local_id > 0) + { + std::set::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id); + if(iter != mImpl->mNonCacheableCreatedList.end()) + { + mImpl->mNonCacheableCreatedList.erase(iter); + } + } + } void LLViewerRegion::addToCreatedList(U32 local_id) { - if(mImpl && local_id > 0) - { - mImpl->mNonCacheableCreatedList.insert(local_id); - } + if(mImpl && local_id > 0) + { + mImpl->mNonCacheableCreatedList.insert(local_id); + } } // Get data packer for this object, if we have cached data // AND the CRC matches. JC bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type) { - //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 + //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 - LLVOCacheEntry* entry = getCacheEntry(local_id, false); + LLVOCacheEntry* entry = getCacheEntry(local_id, false); - if (entry) - { - // we've seen this object before - if (entry->getCRC() == crc) - { - // Record a hit - mRegionCacheHitCount++; - entry->recordHit(); + if (entry) + { + // we've seen this object before + if (entry->getCRC() == crc) + { + // Record a hit + mRegionCacheHitCount++; + entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; - entry->setUpdateFlags(flags); - - if(entry->isState(LLVOCacheEntry::ACTIVE)) - { - ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags); - return true; - } - - if(entry->isValid()) - { - return true; //already probed - } - - entry->setValid(); - decodeBoundingInfo(entry); + entry->setUpdateFlags(flags); + + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags); + return true; + } + + if(entry->isValid()) + { + return true; //already probed + } + + entry->setValid(); + decodeBoundingInfo(entry); //loadCacheMiscExtras(local_id, entry, crc); - return true; - } - else - { - // LL_INFOS() << "CRC miss for " << local_id << LL_ENDL; + return true; + } + else + { + // LL_INFOS() << "CRC miss for " << local_id << LL_ENDL; - addCacheMiss(local_id, CACHE_MISS_TYPE_CRC); + addCacheMiss(local_id, CACHE_MISS_TYPE_CRC); cache_miss_type = CACHE_MISS_TYPE_CRC; - } - } - else - { // Total miss, don't have the object in cache - // LL_INFOS() << "Cache miss for " << local_id << LL_ENDL; + } + } + else + { // Total miss, don't have the object in cache + // LL_INFOS() << "Cache miss for " << local_id << LL_ENDL; addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL); cache_miss_type = CACHE_MISS_TYPE_TOTAL; - } + } - return false; + return false; } void LLViewerRegion::addCacheMissFull(const U32 local_id) { - addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL); + addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL); } void LLViewerRegion::requestCacheMisses() { - if (!mCacheMissList.size()) - { - return; - } - - LLMessageSystem* msg = gMessageSystem; - BOOL start_new_message = TRUE; - S32 blocks = 0; - - //send requests for all cache-missed objects - for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter) - { - if (start_new_message) - { - msg->newMessageFast(_PREHASH_RequestMultipleObjects); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - start_new_message = FALSE; - } - - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType); - msg->addU32Fast(_PREHASH_ID, (*iter).mID); + if (!mCacheMissList.size()) + { + return; + } + + LLMessageSystem* msg = gMessageSystem; + BOOL start_new_message = TRUE; + S32 blocks = 0; + + //send requests for all cache-missed objects + for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter) + { + if (start_new_message) + { + msg->newMessageFast(_PREHASH_RequestMultipleObjects); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + start_new_message = FALSE; + } + + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType); + msg->addU32Fast(_PREHASH_ID, (*iter).mID); LL_DEBUGS("AnimatedObjects") << "Requesting cache missed object " << (*iter).mID << LL_ENDL; - - blocks++; - if (blocks >= 255) - { - sendReliableMessage(); - start_new_message = TRUE; - blocks = 0; - } - } + blocks++; - // finish any pending message - if (!start_new_message) - { - sendReliableMessage(); - } + if (blocks >= 255) + { + sendReliableMessage(); + start_new_message = TRUE; + blocks = 0; + } + } - mCacheDirty = TRUE ; - // LL_INFOS() << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << LL_ENDL; - LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size()); + // finish any pending message + if (!start_new_message) + { + sendReliableMessage(); + } + + mCacheDirty = TRUE ; + // LL_INFOS() << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << LL_ENDL; + LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size()); - mCacheMissList.clear(); + mCacheMissList.clear(); } void LLViewerRegion::dumpCache() { - const S32 BINS = 4; - S32 hit_bin[BINS]; - S32 change_bin[BINS]; + const S32 BINS = 4; + S32 hit_bin[BINS]; + S32 change_bin[BINS]; - S32 i; - for (i = 0; i < BINS; ++i) - { - hit_bin[i] = 0; - change_bin[i] = 0; - } + S32 i; + for (i = 0; i < BINS; ++i) + { + hit_bin[i] = 0; + change_bin[i] = 0; + } - LLVOCacheEntry *entry; - for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) - { - entry = iter->second ; + LLVOCacheEntry *entry; + for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) + { + entry = iter->second ; - S32 hits = entry->getHitCount(); - S32 changes = entry->getCRCChangeCount(); + S32 hits = entry->getHitCount(); + S32 changes = entry->getCRCChangeCount(); - hits = llclamp(hits, 0, BINS-1); - changes = llclamp(changes, 0, BINS-1); + hits = llclamp(hits, 0, BINS-1); + changes = llclamp(changes, 0, BINS-1); - hit_bin[hits]++; - change_bin[changes]++; - } + hit_bin[hits]++; + change_bin[changes]++; + } - LL_INFOS() << "Count " << mImpl->mCacheMap.size() << LL_ENDL; - for (i = 0; i < BINS; i++) - { - LL_INFOS() << "Hits " << i << " " << hit_bin[i] << LL_ENDL; - } - for (i = 0; i < BINS; i++) - { - LL_INFOS() << "Changes " << i << " " << change_bin[i] << LL_ENDL; - } - // TODO - add overrides cache too + LL_INFOS() << "Count " << mImpl->mCacheMap.size() << LL_ENDL; + for (i = 0; i < BINS; i++) + { + LL_INFOS() << "Hits " << i << " " << hit_bin[i] << LL_ENDL; + } + for (i = 0; i < BINS; i++) + { + LL_INFOS() << "Changes " << i << " " << change_bin[i] << LL_ENDL; + } + // TODO - add overrides cache too } void LLViewerRegion::clearVOCacheFromMemory() @@ -2983,315 +2983,315 @@ void LLViewerRegion::clearVOCacheFromMemory() void LLViewerRegion::unpackRegionHandshake() { - LLMessageSystem *msg = gMessageSystem; - - U64 region_flags = 0; - U64 region_protocols = 0; - U8 sim_access; - std::string sim_name; - LLUUID sim_owner; - BOOL is_estate_manager; - F32 water_height; - F32 billable_factor; - LLUUID cache_id; - - msg->getU8 ("RegionInfo", "SimAccess", sim_access); - msg->getString ("RegionInfo", "SimName", sim_name); - msg->getUUID ("RegionInfo", "SimOwner", sim_owner); - msg->getBOOL ("RegionInfo", "IsEstateManager", is_estate_manager); - msg->getF32 ("RegionInfo", "WaterHeight", water_height); - msg->getF32 ("RegionInfo", "BillableFactor", billable_factor); - msg->getUUID ("RegionInfo", "CacheID", cache_id ); - - if (msg->has(_PREHASH_RegionInfo4)) - { - msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags); - msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols); - } - else - { - U32 flags = 0; - msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags); - region_flags = flags; - } - - setRegionFlags(region_flags); - setRegionProtocols(region_protocols); - setSimAccess(sim_access); - setRegionNameAndZone(sim_name); - setOwner(sim_owner); - setIsEstateManager(is_estate_manager); - setWaterHeight(water_height); - setBillableFactor(billable_factor); - setCacheID(cache_id); - - LLUUID region_id; - msg->getUUID("RegionInfo2", "RegionID", region_id); - setRegionID(region_id); - - // Retrieve the CR-53 (Homestead/Land SKU) information - S32 classID = 0; - S32 cpuRatio = 0; - std::string coloName; - std::string productSKU; - std::string productName; - - // the only reasonable way to decide if we actually have any data is to - // check to see if any of these fields have positive sizes - if (msg->getSize("RegionInfo3", "ColoName") > 0 || - msg->getSize("RegionInfo3", "ProductSKU") > 0 || - msg->getSize("RegionInfo3", "ProductName") > 0) - { - msg->getS32 ("RegionInfo3", "CPUClassID", classID); - msg->getS32 ("RegionInfo3", "CPURatio", cpuRatio); - msg->getString ("RegionInfo3", "ColoName", coloName); - msg->getString ("RegionInfo3", "ProductSKU", productSKU); - msg->getString ("RegionInfo3", "ProductName", productName); - - mClassID = classID; - mCPURatio = cpuRatio; - mColoName = coloName; - mProductSKU = productSKU; - mProductName = productName; - } - - mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking"); - LLVLComposition *compp = getComposition(); - if (compp) - { - LLUUID tmp_id; - - bool changed = false; - - // Get the 4 textures for land - msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id); - changed |= (tmp_id != compp->getDetailAssetID(0)); - compp->setDetailAssetID(0, tmp_id); - - msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id); - changed |= (tmp_id != compp->getDetailAssetID(1)); - compp->setDetailAssetID(1, tmp_id); - - msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id); - changed |= (tmp_id != compp->getDetailAssetID(2)); - compp->setDetailAssetID(2, tmp_id); - - msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id); - changed |= (tmp_id != compp->getDetailAssetID(3)); - compp->setDetailAssetID(3, tmp_id); - - // Get the start altitude and range values for land textures - F32 tmp_f32; - msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32); - changed |= (tmp_f32 != compp->getStartHeight(0)); - compp->setStartHeight(0, tmp_f32); - - msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32); - changed |= (tmp_f32 != compp->getStartHeight(1)); - compp->setStartHeight(1, tmp_f32); - - msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32); - changed |= (tmp_f32 != compp->getStartHeight(2)); - compp->setStartHeight(2, tmp_f32); - - msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32); - changed |= (tmp_f32 != compp->getStartHeight(3)); - compp->setStartHeight(3, tmp_f32); - - - msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32); - changed |= (tmp_f32 != compp->getHeightRange(0)); - compp->setHeightRange(0, tmp_f32); - - msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32); - changed |= (tmp_f32 != compp->getHeightRange(1)); - compp->setHeightRange(1, tmp_f32); - - msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32); - changed |= (tmp_f32 != compp->getHeightRange(2)); - compp->setHeightRange(2, tmp_f32); - - msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32); - changed |= (tmp_f32 != compp->getHeightRange(3)); - compp->setHeightRange(3, tmp_f32); - - // If this is an UPDATE (params already ready, we need to regenerate - // all of our terrain stuff, by - if (compp->getParamsReady()) - { - // Update if the land changed - if (changed) - { - getLand().dirtyAllPatches(); - } - } - else - { - compp->setParamsReady(); - } - } - - - // Now that we have the name, we can load the cache file - // off disk. - loadObjectCache(); - - // After loading cache, signal that simulator can start - // sending data. - // TODO: Send all upstream viewer->sim handshake info here. - LLHost host = msg->getSender(); - msg->newMessage("RegionHandshakeReply"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("RegionInfo"); - - U32 flags = 0; - flags |= REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE; - - if(sVOCacheCullingEnabled) - { - flags |= 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. - } - if(mImpl->mCacheMap.empty()) - { - flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. - } - msg->addU32("Flags", flags ); - msg->sendReliable(host); - - mRegionTimer.reset(); //reset region timer. + LLMessageSystem *msg = gMessageSystem; + + U64 region_flags = 0; + U64 region_protocols = 0; + U8 sim_access; + std::string sim_name; + LLUUID sim_owner; + BOOL is_estate_manager; + F32 water_height; + F32 billable_factor; + LLUUID cache_id; + + msg->getU8 ("RegionInfo", "SimAccess", sim_access); + msg->getString ("RegionInfo", "SimName", sim_name); + msg->getUUID ("RegionInfo", "SimOwner", sim_owner); + msg->getBOOL ("RegionInfo", "IsEstateManager", is_estate_manager); + msg->getF32 ("RegionInfo", "WaterHeight", water_height); + msg->getF32 ("RegionInfo", "BillableFactor", billable_factor); + msg->getUUID ("RegionInfo", "CacheID", cache_id ); + + if (msg->has(_PREHASH_RegionInfo4)) + { + msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags); + msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols); + } + else + { + U32 flags = 0; + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags); + region_flags = flags; + } + + setRegionFlags(region_flags); + setRegionProtocols(region_protocols); + setSimAccess(sim_access); + setRegionNameAndZone(sim_name); + setOwner(sim_owner); + setIsEstateManager(is_estate_manager); + setWaterHeight(water_height); + setBillableFactor(billable_factor); + setCacheID(cache_id); + + LLUUID region_id; + msg->getUUID("RegionInfo2", "RegionID", region_id); + setRegionID(region_id); + + // Retrieve the CR-53 (Homestead/Land SKU) information + S32 classID = 0; + S32 cpuRatio = 0; + std::string coloName; + std::string productSKU; + std::string productName; + + // the only reasonable way to decide if we actually have any data is to + // check to see if any of these fields have positive sizes + if (msg->getSize("RegionInfo3", "ColoName") > 0 || + msg->getSize("RegionInfo3", "ProductSKU") > 0 || + msg->getSize("RegionInfo3", "ProductName") > 0) + { + msg->getS32 ("RegionInfo3", "CPUClassID", classID); + msg->getS32 ("RegionInfo3", "CPURatio", cpuRatio); + msg->getString ("RegionInfo3", "ColoName", coloName); + msg->getString ("RegionInfo3", "ProductSKU", productSKU); + msg->getString ("RegionInfo3", "ProductName", productName); + + mClassID = classID; + mCPURatio = cpuRatio; + mColoName = coloName; + mProductSKU = productSKU; + mProductName = productName; + } + + mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking"); + LLVLComposition *compp = getComposition(); + if (compp) + { + LLUUID tmp_id; + + bool changed = false; + + // Get the 4 textures for land + msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(0)); + compp->setDetailAssetID(0, tmp_id); + + msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(1)); + compp->setDetailAssetID(1, tmp_id); + + msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(2)); + compp->setDetailAssetID(2, tmp_id); + + msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(3)); + compp->setDetailAssetID(3, tmp_id); + + // Get the start altitude and range values for land textures + F32 tmp_f32; + msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32); + changed |= (tmp_f32 != compp->getStartHeight(0)); + compp->setStartHeight(0, tmp_f32); + + msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32); + changed |= (tmp_f32 != compp->getStartHeight(1)); + compp->setStartHeight(1, tmp_f32); + + msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32); + changed |= (tmp_f32 != compp->getStartHeight(2)); + compp->setStartHeight(2, tmp_f32); + + msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32); + changed |= (tmp_f32 != compp->getStartHeight(3)); + compp->setStartHeight(3, tmp_f32); + + + msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32); + changed |= (tmp_f32 != compp->getHeightRange(0)); + compp->setHeightRange(0, tmp_f32); + + msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32); + changed |= (tmp_f32 != compp->getHeightRange(1)); + compp->setHeightRange(1, tmp_f32); + + msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32); + changed |= (tmp_f32 != compp->getHeightRange(2)); + compp->setHeightRange(2, tmp_f32); + + msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32); + changed |= (tmp_f32 != compp->getHeightRange(3)); + compp->setHeightRange(3, tmp_f32); + + // If this is an UPDATE (params already ready, we need to regenerate + // all of our terrain stuff, by + if (compp->getParamsReady()) + { + // Update if the land changed + if (changed) + { + getLand().dirtyAllPatches(); + } + } + else + { + compp->setParamsReady(); + } + } + + + // Now that we have the name, we can load the cache file + // off disk. + loadObjectCache(); + + // After loading cache, signal that simulator can start + // sending data. + // TODO: Send all upstream viewer->sim handshake info here. + LLHost host = msg->getSender(); + msg->newMessage("RegionHandshakeReply"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("RegionInfo"); + + U32 flags = 0; + flags |= REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE; + + if(sVOCacheCullingEnabled) + { + flags |= 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. + } + if(mImpl->mCacheMap.empty()) + { + flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. + } + msg->addU32("Flags", flags ); + msg->sendReliable(host); + + mRegionTimer.reset(); //reset region timer. } // static void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { - capabilityNames.append("AbuseCategories"); - capabilityNames.append("AcceptFriendship"); - capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!! - capabilityNames.append("AgentPreferences"); + capabilityNames.append("AbuseCategories"); + capabilityNames.append("AcceptFriendship"); + capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!! + capabilityNames.append("AgentPreferences"); capabilityNames.append("AgentProfile"); - capabilityNames.append("AgentState"); - capabilityNames.append("AttachmentResources"); - capabilityNames.append("AvatarPickerSearch"); - capabilityNames.append("AvatarRenderInfo"); - capabilityNames.append("CharacterProperties"); - capabilityNames.append("ChatSessionRequest"); - capabilityNames.append("CopyInventoryFromNotecard"); - capabilityNames.append("CreateInventoryCategory"); - capabilityNames.append("DeclineFriendship"); - capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!! - capabilityNames.append("DispatchRegionInfo"); - capabilityNames.append("DirectDelivery"); - capabilityNames.append("EnvironmentSettings"); - capabilityNames.append("EstateAccess"); - capabilityNames.append("EstateChangeInfo"); - capabilityNames.append("EventQueueGet"); + capabilityNames.append("AgentState"); + capabilityNames.append("AttachmentResources"); + capabilityNames.append("AvatarPickerSearch"); + capabilityNames.append("AvatarRenderInfo"); + capabilityNames.append("CharacterProperties"); + capabilityNames.append("ChatSessionRequest"); + capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("CreateInventoryCategory"); + capabilityNames.append("DeclineFriendship"); + capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!! + capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("DirectDelivery"); + capabilityNames.append("EnvironmentSettings"); + capabilityNames.append("EstateAccess"); + capabilityNames.append("EstateChangeInfo"); + capabilityNames.append("EventQueueGet"); capabilityNames.append("ExtEnvironment"); - capabilityNames.append("FetchLib2"); - capabilityNames.append("FetchLibDescendents2"); - capabilityNames.append("FetchInventory2"); - capabilityNames.append("FetchInventoryDescendents2"); - capabilityNames.append("IncrementCOFVersion"); - AISAPI::getCapNames(capabilityNames); + capabilityNames.append("FetchLib2"); + capabilityNames.append("FetchLibDescendents2"); + capabilityNames.append("FetchInventory2"); + capabilityNames.append("FetchInventoryDescendents2"); + capabilityNames.append("IncrementCOFVersion"); + AISAPI::getCapNames(capabilityNames); - capabilityNames.append("InterestList"); + capabilityNames.append("InterestList"); capabilityNames.append("InventoryThumbnailUpload"); - capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetExperiences"); - capabilityNames.append("AgentExperiences"); - capabilityNames.append("FindExperienceByName"); - capabilityNames.append("GetExperienceInfo"); - capabilityNames.append("GetAdminExperiences"); - capabilityNames.append("GetCreatorExperiences"); - capabilityNames.append("ExperiencePreferences"); - capabilityNames.append("GroupExperiences"); - capabilityNames.append("UpdateExperience"); - capabilityNames.append("IsExperienceAdmin"); - capabilityNames.append("IsExperienceContributor"); - capabilityNames.append("RegionExperiences"); + capabilityNames.append("GetDisplayNames"); + capabilityNames.append("GetExperiences"); + capabilityNames.append("AgentExperiences"); + capabilityNames.append("FindExperienceByName"); + capabilityNames.append("GetExperienceInfo"); + capabilityNames.append("GetAdminExperiences"); + capabilityNames.append("GetCreatorExperiences"); + capabilityNames.append("ExperiencePreferences"); + capabilityNames.append("GroupExperiences"); + capabilityNames.append("UpdateExperience"); + capabilityNames.append("IsExperienceAdmin"); + capabilityNames.append("IsExperienceContributor"); + capabilityNames.append("RegionExperiences"); capabilityNames.append("ExperienceQuery"); - capabilityNames.append("GetMetadata"); - capabilityNames.append("GetObjectCost"); - capabilityNames.append("GetObjectPhysicsData"); - capabilityNames.append("GroupAPIv1"); - capabilityNames.append("GroupMemberData"); - capabilityNames.append("GroupProposalBallot"); - capabilityNames.append("HomeLocation"); - capabilityNames.append("LandResources"); - capabilityNames.append("LSLSyntax"); - capabilityNames.append("MapLayer"); - capabilityNames.append("MapLayerGod"); - capabilityNames.append("MeshUploadFlag"); - capabilityNames.append("ModifyMaterialParams"); - capabilityNames.append("NavMeshGenerationStatus"); - capabilityNames.append("NewFileAgentInventory"); - capabilityNames.append("ObjectAnimation"); - capabilityNames.append("ObjectMedia"); - capabilityNames.append("ObjectMediaNavigate"); - capabilityNames.append("ObjectNavMeshProperties"); - capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelVoiceInfoRequest"); - capabilityNames.append("ProductInfoRequest"); - capabilityNames.append("ProvisionVoiceAccountRequest"); - capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite - capabilityNames.append("RegionObjects"); - capabilityNames.append("RemoteParcelRequest"); - capabilityNames.append("RenderMaterials"); - capabilityNames.append("RequestTextureDownload"); - capabilityNames.append("ResourceCostSelected"); - capabilityNames.append("RetrieveNavMeshSrc"); - capabilityNames.append("SearchStatRequest"); - capabilityNames.append("SearchStatTracking"); - capabilityNames.append("SendPostcard"); - capabilityNames.append("SendUserReport"); - capabilityNames.append("SendUserReportWithScreenshot"); - capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SetDisplayName"); - capabilityNames.append("SimConsoleAsync"); - capabilityNames.append("SimulatorFeatures"); - capabilityNames.append("StartGroupProposal"); - capabilityNames.append("TerrainNavMeshProperties"); - capabilityNames.append("TextureStats"); - capabilityNames.append("UntrustedSimulatorMessage"); - capabilityNames.append("UpdateAgentInformation"); - capabilityNames.append("UpdateAgentLanguage"); - capabilityNames.append("UpdateAvatarAppearance"); - capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateGestureTaskInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateNotecardTaskInventory"); - capabilityNames.append("UpdateScriptAgent"); - capabilityNames.append("UpdateScriptTask"); + capabilityNames.append("GetMetadata"); + capabilityNames.append("GetObjectCost"); + capabilityNames.append("GetObjectPhysicsData"); + capabilityNames.append("GroupAPIv1"); + capabilityNames.append("GroupMemberData"); + capabilityNames.append("GroupProposalBallot"); + capabilityNames.append("HomeLocation"); + capabilityNames.append("LandResources"); + capabilityNames.append("LSLSyntax"); + capabilityNames.append("MapLayer"); + capabilityNames.append("MapLayerGod"); + capabilityNames.append("MeshUploadFlag"); + capabilityNames.append("ModifyMaterialParams"); + capabilityNames.append("NavMeshGenerationStatus"); + capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("ObjectAnimation"); + capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate"); + capabilityNames.append("ObjectNavMeshProperties"); + capabilityNames.append("ParcelPropertiesUpdate"); + capabilityNames.append("ParcelVoiceInfoRequest"); + capabilityNames.append("ProductInfoRequest"); + capabilityNames.append("ProvisionVoiceAccountRequest"); + capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite + capabilityNames.append("RegionObjects"); + capabilityNames.append("RemoteParcelRequest"); + capabilityNames.append("RenderMaterials"); + capabilityNames.append("RequestTextureDownload"); + capabilityNames.append("ResourceCostSelected"); + capabilityNames.append("RetrieveNavMeshSrc"); + capabilityNames.append("SearchStatRequest"); + capabilityNames.append("SearchStatTracking"); + capabilityNames.append("SendPostcard"); + capabilityNames.append("SendUserReport"); + capabilityNames.append("SendUserReportWithScreenshot"); + capabilityNames.append("ServerReleaseNotes"); + capabilityNames.append("SetDisplayName"); + capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("SimulatorFeatures"); + capabilityNames.append("StartGroupProposal"); + capabilityNames.append("TerrainNavMeshProperties"); + capabilityNames.append("TextureStats"); + capabilityNames.append("UntrustedSimulatorMessage"); + capabilityNames.append("UpdateAgentInformation"); + capabilityNames.append("UpdateAgentLanguage"); + capabilityNames.append("UpdateAvatarAppearance"); + capabilityNames.append("UpdateGestureAgentInventory"); + capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); + capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptAgent"); + capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UpdateSettingsAgentInventory"); capabilityNames.append("UpdateSettingsTaskInventory"); capabilityNames.append("UploadAgentProfileImage"); capabilityNames.append("UpdateMaterialAgentInventory"); capabilityNames.append("UpdateMaterialTaskInventory"); - capabilityNames.append("UploadBakedTexture"); + capabilityNames.append("UploadBakedTexture"); capabilityNames.append("UserInfo"); - capabilityNames.append("ViewerAsset"); - capabilityNames.append("ViewerBenefits"); - capabilityNames.append("ViewerMetrics"); - capabilityNames.append("ViewerStartAuction"); - capabilityNames.append("ViewerStats"); + capabilityNames.append("ViewerAsset"); + capabilityNames.append("ViewerBenefits"); + capabilityNames.append("ViewerMetrics"); + capabilityNames.append("ViewerStartAuction"); + capabilityNames.append("ViewerStats"); - // Please add new capabilities alphabetically to reduce - // merge conflicts. + // Please add new capabilities alphabetically to reduce + // merge conflicts. } void LLViewerRegion::setSeedCapability(const std::string& url) { - if (getCapability("Seed") == url) - { - setCapabilityDebug("Seed", url); - LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " << - url << LL_ENDL; + if (getCapability("Seed") == url) + { + setCapabilityDebug("Seed", url); + LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " << + url << LL_ENDL; - //Instead of just returning we build up a second set of seed caps and compare them - //to the "original" seed cap received and determine why there is problem! + //Instead of just returning we build up a second set of seed caps and compare them + //to the "original" seed cap received and determine why there is problem! std::string coroname = LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro", boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle())); @@ -3301,14 +3301,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url) // Make sure we are still good to do LLCoros::checkStop(); - return; + return; } - - delete mImpl->mEventPoll; - mImpl->mEventPoll = NULL; - - mImpl->mCapabilities.clear(); - setCapability("Seed", url); + + delete mImpl->mEventPoll; + mImpl->mEventPoll = NULL; + + mImpl->mCapabilities.clear(); + setCapability("Seed", url); std::string coroname = LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro", @@ -3324,69 +3324,69 @@ void LLViewerRegion::setSeedCapability(const std::string& url) S32 LLViewerRegion::getNumSeedCapRetries() { - return mImpl->mSeedCapAttempts; + return mImpl->mSeedCapAttempts; } void LLViewerRegion::setCapability(const std::string& name, const std::string& url) { - if(name == "EventQueueGet") - { - delete mImpl->mEventPoll; - mImpl->mEventPoll = NULL; - mImpl->mEventPoll = new LLEventPoll(url, getHost()); - } - else if(name == "UntrustedSimulatorMessage") - { + if(name == "EventQueueGet") + { + delete mImpl->mEventPoll; + mImpl->mEventPoll = NULL; + mImpl->mEventPoll = new LLEventPoll(url, getHost()); + } + else if(name == "UntrustedSimulatorMessage") + { mImpl->mHost.setUntrustedSimulatorCap(url); - } - else if (name == "SimulatorFeatures") - { + } + else if (name == "SimulatorFeatures") + { mImpl->mCapabilities["SimulatorFeatures"] = url; requestSimulatorFeatures(); - } - else - { - mImpl->mCapabilities[name] = url; - if(name == "ViewerAsset") - { - /*==============================================================*/ - // The following inserted lines are a hack for testing MAINT-7081, - // which is why the indentation and formatting are left ugly. - const char* VIEWERASSET = getenv("VIEWERASSET"); - if (VIEWERASSET) - { - mImpl->mCapabilities[name] = VIEWERASSET; - mViewerAssetUrl = VIEWERASSET; - } - else - /*==============================================================*/ - mViewerAssetUrl = url; - } - } + } + else + { + mImpl->mCapabilities[name] = url; + if(name == "ViewerAsset") + { + /*==============================================================*/ + // The following inserted lines are a hack for testing MAINT-7081, + // which is why the indentation and formatting are left ugly. + const char* VIEWERASSET = getenv("VIEWERASSET"); + if (VIEWERASSET) + { + mImpl->mCapabilities[name] = VIEWERASSET; + mViewerAssetUrl = VIEWERASSET; + } + else + /*==============================================================*/ + mViewerAssetUrl = url; + } + } } void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url) { - // Continue to not add certain caps, as we do in setCapability. This is so they match up when we check them later. - if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) ) - { - mImpl->mSecondCapabilitiesTracker[name] = url; - if(name == "ViewerAsset") - { - /*==============================================================*/ - // The following inserted lines are a hack for testing MAINT-7081, - // which is why the indentation and formatting are left ugly. - const char* VIEWERASSET = getenv("VIEWERASSET"); - if (VIEWERASSET) - { - mImpl->mSecondCapabilitiesTracker[name] = VIEWERASSET; - mViewerAssetUrl = VIEWERASSET; - } - else - /*==============================================================*/ - mViewerAssetUrl = url; - } - } + // Continue to not add certain caps, as we do in setCapability. This is so they match up when we check them later. + if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) ) + { + mImpl->mSecondCapabilitiesTracker[name] = url; + if(name == "ViewerAsset") + { + /*==============================================================*/ + // The following inserted lines are a hack for testing MAINT-7081, + // which is why the indentation and formatting are left ugly. + const char* VIEWERASSET = getenv("VIEWERASSET"); + if (VIEWERASSET) + { + mImpl->mSecondCapabilitiesTracker[name] = VIEWERASSET; + mViewerAssetUrl = VIEWERASSET; + } + else + /*==============================================================*/ + mViewerAssetUrl = url; + } + } } std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const @@ -3403,44 +3403,44 @@ std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const bool LLViewerRegion::isSpecialCapabilityName(const std::string &name) { - return name == "EventQueueGet" || name == "UntrustedSimulatorMessage"; + return name == "EventQueueGet" || name == "UntrustedSimulatorMessage"; } std::string LLViewerRegion::getCapability(const std::string& name) const { - if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia"))) - { - LL_WARNS() << "getCapability called before caps received for " << name << LL_ENDL; - } - - CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); - if(iter == mImpl->mCapabilities.end()) - { - return ""; - } + if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia"))) + { + LL_WARNS() << "getCapability called before caps received for " << name << LL_ENDL; + } + + CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); + if(iter == mImpl->mCapabilities.end()) + { + return ""; + } - return iter->second; + return iter->second; } bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const { - if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia"))) - { - LL_WARNS() << "isCapabilityAvailable called before caps received for " << name << LL_ENDL; - } - - CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); - if(iter == mImpl->mCapabilities.end()) - { - return false; - } + if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia"))) + { + LL_WARNS() << "isCapabilityAvailable called before caps received for " << name << LL_ENDL; + } + + CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); + if(iter == mImpl->mCapabilities.end()) + { + return false; + } - return true; + return true; } bool LLViewerRegion::capabilitiesReceived() const { - return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED; + return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED; } bool LLViewerRegion::capabilitiesError() const @@ -3450,22 +3450,22 @@ bool LLViewerRegion::capabilitiesError() const void LLViewerRegion::setCapabilitiesReceived(bool received) { - mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT; + mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT; - // Tell interested parties that we've received capabilities, - // so that they can safely use getCapability(). - if (received) - { - mCapabilitiesReceivedSignal(getRegionID(), this); + // Tell interested parties that we've received capabilities, + // so that they can safely use getCapability(). + if (received) + { + mCapabilitiesReceivedSignal(getRegionID(), this); - LLFloaterPermsDefault::sendInitialPerms(); + LLFloaterPermsDefault::sendInitialPerms(); - // This is a single-shot signal. Forget callbacks to save resources. - mCapabilitiesReceivedSignal.disconnect_all_slots(); + // This is a single-shot signal. Forget callbacks to save resources. + mCapabilitiesReceivedSignal.disconnect_all_slots(); - // Set the region to the desired interest list mode + // Set the region to the desired interest list mode setInterestListMode(gAgent.getInterestListMode()); - } + } } void LLViewerRegion::setCapabilitiesError() @@ -3475,12 +3475,12 @@ void LLViewerRegion::setCapabilitiesError() boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb) { - return mCapabilitiesReceivedSignal.connect(cb); + return mCapabilitiesReceivedSignal.connect(cb); } void LLViewerRegion::logActiveCapabilities() const { - log_capabilities(mImpl->mCapabilities); + log_capabilities(mImpl->mCapabilities); } @@ -3491,7 +3491,7 @@ bool LLViewerRegion::requestPostCapability(const std::string &capName, LLSD &pos if (url.empty()) { LL_WARNS("Region") << "Could not retrieve region " << getRegionID() - << " POST capability \"" << capName << "\"" << LL_ENDL; + << " POST capability \"" << capName << "\"" << LL_ENDL; return false; } @@ -3538,14 +3538,14 @@ void LLViewerRegion::setInterestListMode(const std::string &new_mode) { mInterestListMode = new_mode; - if (mInterestListMode != std::string(IL_MODE_DEFAULT) && mInterestListMode != std::string(IL_MODE_360)) - { - LL_WARNS("360Capture") << "Region " << getRegionID() << " setInterestListMode() invalid interest list mode: " - << mInterestListMode << ", setting to default" << LL_ENDL; + if (mInterestListMode != std::string(IL_MODE_DEFAULT) && mInterestListMode != std::string(IL_MODE_360)) + { + LL_WARNS("360Capture") << "Region " << getRegionID() << " setInterestListMode() invalid interest list mode: " + << mInterestListMode << ", setting to default" << LL_ENDL; mInterestListMode = IL_MODE_DEFAULT; - } + } - LLSD body; + LLSD body; body["mode"] = mInterestListMode; if (requestPostCapability("InterestList", body, [](const LLSD &response) { @@ -3559,99 +3559,99 @@ void LLViewerRegion::setInterestListMode(const std::string &new_mode) } else { - LL_WARNS("360Capture") << "Region " << getRegionID() - << " Unable to post an InterestList capability request with payload: \n" + LL_WARNS("360Capture") << "Region " << getRegionID() + << " Unable to post an InterestList capability request with payload: \n" << ll_pretty_print_sd(body) << LL_ENDL; } } else { LL_DEBUGS("360Capture") << "Region " << getRegionID() << "No change, skipping Interest List mode POST to " - << new_mode << " mode" << LL_ENDL; + << new_mode << " mode" << LL_ENDL; } } void LLViewerRegion::resetInterestList() { - if (requestDelCapability("InterestList", [](const LLSD &response) { - LL_DEBUGS("360Capture") << "InterestList capability DEL responded: \n" << ll_pretty_print_sd(response) << LL_ENDL; - })) - { - LL_DEBUGS("360Capture") << "Region " << getRegionID() << " Successfully reset InterestList capability" << LL_ENDL; - } - else - { - LL_WARNS("360Capture") << "Region " << getRegionID() << " Unable to DEL InterestList capability request" << LL_ENDL; - } + if (requestDelCapability("InterestList", [](const LLSD &response) { + LL_DEBUGS("360Capture") << "InterestList capability DEL responded: \n" << ll_pretty_print_sd(response) << LL_ENDL; + })) + { + LL_DEBUGS("360Capture") << "Region " << getRegionID() << " Successfully reset InterestList capability" << LL_ENDL; + } + else + { + LL_WARNS("360Capture") << "Region " << getRegionID() << " Unable to DEL InterestList capability request" << LL_ENDL; + } } LLSpatialPartition *LLViewerRegion::getSpatialPartition(U32 type) { - if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) - { - return (LLSpatialPartition*)mImpl->mObjectPartition[type]; - } - return NULL; + if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) + { + return (LLSpatialPartition*)mImpl->mObjectPartition[type]; + } + return NULL; } LLVOCachePartition* LLViewerRegion::getVOCachePartition() { - if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) - { - return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; - } - return NULL; + if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) + { + return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; + } + return NULL; } // the viewer can not yet distinquish between normal- and estate-owned objects // so we collapse these two bits and enable the UI if either are set const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT - | REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT; + | REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT; bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const { - return (mParcelOverlay != NULL) - && (mParcelOverlay->isOwnedSelf(pos) - || mParcelOverlay->isOwnedGroup(pos) - || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT) - && mParcelOverlay->encroachesOwned(boxes)) ); + return (mParcelOverlay != NULL) + && (mParcelOverlay->isOwnedSelf(pos) + || mParcelOverlay->isOwnedGroup(pos) + || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT) + && mParcelOverlay->encroachesOwned(boxes)) ); } bool LLViewerRegion::childrenObjectReturnable( const std::vector& boxes ) const { - bool result = false; - result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0; - return result; + bool result = false; + result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0; + return result; } bool LLViewerRegion::objectsCrossParcel(const std::vector& boxes) const { - return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes); + return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes); } void LLViewerRegion::getNeighboringRegions( std::vector& uniqueRegions ) { - mImpl->mLandp->getNeighboringRegions( uniqueRegions ); + mImpl->mLandp->getNeighboringRegions( uniqueRegions ); } void LLViewerRegion::getNeighboringRegionsStatus( std::vector& regions ) { - mImpl->mLandp->getNeighboringRegionsStatus( regions ); + mImpl->mLandp->getNeighboringRegionsStatus( regions ); } void LLViewerRegion::showReleaseNotes() { - std::string url = this->getCapability("ServerReleaseNotes"); + std::string url = this->getCapability("ServerReleaseNotes"); - if (url.empty()) { - // HACK haven't received the capability yet, we'll wait until - // it arives. - mReleaseNotesRequested = TRUE; - return; - } + if (url.empty()) { + // HACK haven't received the capability yet, we'll wait until + // it arives. + mReleaseNotesRequested = TRUE; + return; + } - LLWeb::loadURL(url); - mReleaseNotesRequested = FALSE; + LLWeb::loadURL(url); + mReleaseNotesRequested = FALSE; } std::string LLViewerRegion::getDescription() const @@ -3661,98 +3661,98 @@ std::string LLViewerRegion::getDescription() const bool LLViewerRegion::meshUploadEnabled() const { - return (mSimulatorFeatures.has("MeshUploadEnabled") && - mSimulatorFeatures["MeshUploadEnabled"].asBoolean()); + return (mSimulatorFeatures.has("MeshUploadEnabled") && + mSimulatorFeatures["MeshUploadEnabled"].asBoolean()); } bool LLViewerRegion::bakesOnMeshEnabled() const { - return (mSimulatorFeatures.has("BakesOnMeshEnabled") && - mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean()); + return (mSimulatorFeatures.has("BakesOnMeshEnabled") && + mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean()); } bool LLViewerRegion::meshRezEnabled() const { - return (mSimulatorFeatures.has("MeshRezEnabled") && - mSimulatorFeatures["MeshRezEnabled"].asBoolean()); + return (mSimulatorFeatures.has("MeshRezEnabled") && + mSimulatorFeatures["MeshRezEnabled"].asBoolean()); } bool LLViewerRegion::dynamicPathfindingEnabled() const { - return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && - mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); + return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && + mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); } bool LLViewerRegion::avatarHoverHeightEnabled() const { - return ( mSimulatorFeatures.has("AvatarHoverHeightEnabled") && - mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean()); + return ( mSimulatorFeatures.has("AvatarHoverHeightEnabled") && + mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean()); } /* Static Functions */ void log_capabilities(const CapabilityMap &capmap) { - S32 count = 0; - CapabilityMap::const_iterator iter; - for (iter = capmap.begin(); iter != capmap.end(); ++iter, ++count) - { - if (!iter->second.empty()) - { - LL_INFOS() << "log_capabilities: " << iter->first << " URL is " << iter->second << LL_ENDL; - } - } - LL_INFOS() << "log_capabilities: Dumped " << count << " entries." << LL_ENDL; + S32 count = 0; + CapabilityMap::const_iterator iter; + for (iter = capmap.begin(); iter != capmap.end(); ++iter, ++count) + { + if (!iter->second.empty()) + { + LL_INFOS() << "log_capabilities: " << iter->first << " URL is " << iter->second << LL_ENDL; + } + } + LL_INFOS() << "log_capabilities: Dumped " << count << " entries." << LL_ENDL; } void LLViewerRegion::resetMaterialsCapThrottle() { - F32 requests_per_sec = 1.0f; // original default; - if ( mSimulatorFeatures.has("RenderMaterialsCapability") - && mSimulatorFeatures["RenderMaterialsCapability"].isReal() ) - { - requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal(); - if ( requests_per_sec == 0.0f ) - { - requests_per_sec = 1.0f; - LL_WARNS("Materials") - << "region '" << getName() - << "' returned zero for RenderMaterialsCapability; using default " - << requests_per_sec << " per second" - << LL_ENDL; - } - LL_DEBUGS("Materials") << "region '" << getName() - << "' RenderMaterialsCapability " << requests_per_sec - << LL_ENDL; - } - else - { - LL_DEBUGS("Materials") - << "region '" << getName() - << "' did not return RenderMaterialsCapability, using default " - << requests_per_sec << " per second" - << LL_ENDL; - } - - mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec ); + F32 requests_per_sec = 1.0f; // original default; + if ( mSimulatorFeatures.has("RenderMaterialsCapability") + && mSimulatorFeatures["RenderMaterialsCapability"].isReal() ) + { + requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal(); + if ( requests_per_sec == 0.0f ) + { + requests_per_sec = 1.0f; + LL_WARNS("Materials") + << "region '" << getName() + << "' returned zero for RenderMaterialsCapability; using default " + << requests_per_sec << " per second" + << LL_ENDL; + } + LL_DEBUGS("Materials") << "region '" << getName() + << "' RenderMaterialsCapability " << requests_per_sec + << LL_ENDL; + } + else + { + LL_DEBUGS("Materials") + << "region '" << getName() + << "' did not return RenderMaterialsCapability, using default " + << requests_per_sec << " per second" + << LL_ENDL; + } + + mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec ); } U32 LLViewerRegion::getMaxMaterialsPerTransaction() const { - U32 max_entries = 50; // original hard coded default - if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" ) - && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger()) - { - max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger(); - } - return max_entries; + U32 max_entries = 50; // original hard coded default + if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" ) + && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger()) + { + max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger(); + } + return max_entries; } std::string LLViewerRegion::getSimHostName() { - if (mSimulatorFeaturesReceived) - { - return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName(); - } - return std::string("..."); + if (mSimulatorFeaturesReceived) + { + return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName(); + } + return std::string("..."); } void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj) diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 1c89cc4e6d..f1c40dbe9d 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -1,25 +1,25 @@ -/** +/** * @file llviewerregion.h * @brief Description of the LLViewerRegion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,14 +40,14 @@ #include "lluuid.h" #include "llweb.h" #include "llcapabilityprovider.h" -#include "m4math.h" // LLMatrix4 +#include "m4math.h" // LLMatrix4 #include "llframetimer.h" #include "llreflectionmap.h" // Surface id's #define LAND 1 #define WATER 2 -const U32 MAX_OBJECT_CACHE_ENTRIES = 50000; +const U32 MAX_OBJECT_CACHE_ENTRIES = 50000; // Region handshake flags const U32 REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE = 1U << 2; @@ -77,214 +77,214 @@ class LLVOCachePartition; class LLViewerRegion: public LLCapabilityProvider // implements this interface { public: - //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR - typedef enum - { - PARTITION_HUD=0, - PARTITION_TERRAIN, - PARTITION_VOIDWATER, - PARTITION_WATER, - PARTITION_TREE, - PARTITION_PARTICLE, - PARTITION_GRASS, - PARTITION_VOLUME, - PARTITION_BRIDGE, - PARTITION_AVATAR, - PARTITION_CONTROL_AV, // Animesh - PARTITION_HUD_PARTICLE, - PARTITION_VO_CACHE, - PARTITION_NONE, - NUM_PARTITIONS - } eObjectPartitions; - - typedef boost::signals2::signal caps_received_signal_t; - - LLViewerRegion(const U64 &handle, - const LLHost &host, - const U32 surface_grid_width, - const U32 patch_grid_width, - const F32 region_width_meters); - ~LLViewerRegion(); - - // Call this after you have the region name and handle. - void loadObjectCache(); - void saveObjectCache(); - - void sendMessage(); // Send the current message to this region's simulator - void sendReliableMessage(); // Send the current message to this region's simulator - - void setOriginGlobal(const LLVector3d &origin); - //void setAgentOffset(const LLVector3d &offset); - void updateRenderMatrix(); - - void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); } - void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); } - void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } - void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } - void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } - //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used - void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } - - - inline BOOL getAllowDamage() const; - inline BOOL getAllowLandmark() const; - inline BOOL getAllowSetHome() const; - inline BOOL getResetHomeOnTeleport() const; - inline BOOL getSunFixed() const; - inline BOOL getBlockFly() const; - inline BOOL getAllowDirectTeleport() const; - inline BOOL isPrelude() const; - inline BOOL getAllowTerraform() const; - inline BOOL getRestrictPushObject() const; + //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR + typedef enum + { + PARTITION_HUD=0, + PARTITION_TERRAIN, + PARTITION_VOIDWATER, + PARTITION_WATER, + PARTITION_TREE, + PARTITION_PARTICLE, + PARTITION_GRASS, + PARTITION_VOLUME, + PARTITION_BRIDGE, + PARTITION_AVATAR, + PARTITION_CONTROL_AV, // Animesh + PARTITION_HUD_PARTICLE, + PARTITION_VO_CACHE, + PARTITION_NONE, + NUM_PARTITIONS + } eObjectPartitions; + + typedef boost::signals2::signal caps_received_signal_t; + + LLViewerRegion(const U64 &handle, + const LLHost &host, + const U32 surface_grid_width, + const U32 patch_grid_width, + const F32 region_width_meters); + ~LLViewerRegion(); + + // Call this after you have the region name and handle. + void loadObjectCache(); + void saveObjectCache(); + + void sendMessage(); // Send the current message to this region's simulator + void sendReliableMessage(); // Send the current message to this region's simulator + + void setOriginGlobal(const LLVector3d &origin); + //void setAgentOffset(const LLVector3d &offset); + void updateRenderMatrix(); + + void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); } + void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); } + void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } + void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } + void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } + //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used + void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } + + + inline BOOL getAllowDamage() const; + inline BOOL getAllowLandmark() const; + inline BOOL getAllowSetHome() const; + inline BOOL getResetHomeOnTeleport() const; + inline BOOL getSunFixed() const; + inline BOOL getBlockFly() const; + inline BOOL getAllowDirectTeleport() const; + inline BOOL isPrelude() const; + inline BOOL getAllowTerraform() const; + inline BOOL getRestrictPushObject() const; inline BOOL getAllowEnvironmentOverride() const; - inline BOOL getReleaseNotesRequested() const; + inline BOOL getReleaseNotesRequested() const; - bool isAlive(); // can become false if circuit disconnects + bool isAlive(); // can become false if circuit disconnects - void setWaterHeight(F32 water_level); - F32 getWaterHeight() const; + void setWaterHeight(F32 water_level); + F32 getWaterHeight() const; - BOOL isVoiceEnabled() const; + BOOL isVoiceEnabled() const; - void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; } - F32 getBillableFactor() const { return mBillableFactor; } + void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; } + F32 getBillableFactor() const { return mBillableFactor; } - // Maximum number of primitives allowed, regardless of object - // bonus factor. - U32 getMaxTasks() const { return mMaxTasks; } - void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; } + // Maximum number of primitives allowed, regardless of object + // bonus factor. + U32 getMaxTasks() const { return mMaxTasks; } + void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; } - // Draw lines in the dirt showing ownership. Return number of - // vertices drawn. - S32 renderPropertyLines(); + // 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) - void dirtyHeights(); + // Call this whenever you change the height data in the region. + // (Automatically called by LLSurfacePatch's update routine) + void dirtyHeights(); // Call this whenever you want to force all terrain to rebuild. // (For example, if a global terrain config option has changed) void dirtyAllPatches(); - LLViewerParcelOverlay *getParcelOverlay() const - { return mParcelOverlay; } - - inline void setRegionFlag(U64 flag, BOOL on); - inline BOOL getRegionFlag(U64 flag) const; - void setRegionFlags(U64 flags); - U64 getRegionFlags() const { return mRegionFlags; } - - inline void setRegionProtocol(U64 protocol, BOOL on); - BOOL getRegionProtocol(U64 protocol) const; - void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; } - U64 getRegionProtocols() const { return mRegionProtocols; } - - void setTimeDilation(F32 time_dilation); - F32 getTimeDilation() const { return mTimeDilation; } - - // Origin height is at zero. - const LLVector3d &getOriginGlobal() const; - LLVector3 getOriginAgent() const; - - // Center is at the height of the water table. - const LLVector3d &getCenterGlobal() const; - LLVector3 getCenterAgent() const; - - void setRegionNameAndZone(const std::string& name_and_zone); - const std::string& getName() const { return mName; } - const std::string& getZoning() const { return mZoning; } - - void setOwner(const LLUUID& owner_id); - const LLUUID& getOwner() const; - - // Is the current agent on the estate manager list for this region? - void setIsEstateManager(BOOL b) { mIsEstateManager = b; } - BOOL isEstateManager() const { return mIsEstateManager; } - BOOL canManageEstate() const; - - void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } - U8 getSimAccess() const { return mSimAccess; } - const std::string getSimAccessString() const; - - // Homestead-related getters; there are no setters as nobody should be - // setting them other than the individual message handler which is a member - S32 getSimClassID() const { return mClassID; } - S32 getSimCPURatio() const { return mCPURatio; } - const std::string& getSimColoName() const { return mColoName; } - const std::string& getSimProductSKU() const { return mProductSKU; } - std::string getLocalizedSimProductName() const; - - // Returns "Sandbox", "Expensive", etc. - static std::string regionFlagsToString(U64 flags); - - // Returns translated version of "Mature", "PG", "Adult", etc. - static std::string accessToString(U8 sim_access); - - // Returns "M", "PG", "A" etc. - static std::string accessToShortString(U8 sim_access); - static U8 shortStringToAccess(const std::string &sim_access); - - // Return access icon name - static std::string getAccessIcon(U8 sim_access); - - // helper function which just makes sure all interested parties - // can process the message. - static void processRegionInfo(LLMessageSystem* msg, void**); - - //check if the viewer camera is static - static BOOL isViewerCameraStatic(); - static void calcNewObjectCreationThrottle(); - - void setCacheID(const LLUUID& id); - - F32 getWidth() const { return mWidth; } - - // regions are expensive to release, this function gradually releases cache from memory - static void idleCleanup(F32 max_update_time); - - void idleUpdate(F32 max_update_time); - void lightIdleUpdate(); - bool addVisibleGroup(LLViewerOctreeGroup* group); - void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child); - void addActiveCacheEntry(LLVOCacheEntry* entry); - void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); - void killCacheEntry(U32 local_id); //physically delete the cache entry - - // Like idleUpdate, but forces everything to complete regardless of - // how long it takes. - void forceUpdate(); - - void connectNeighbor(LLViewerRegion *neighborp, U32 direction); - - void updateNetStats(); - - U32 getPacketsLost() const; - - S32 getHttpResponderID() const; - - // Get/set named capability URLs for this region. - void setSeedCapability(const std::string& url); - S32 getNumSeedCapRetries(); - void setCapability(const std::string& name, const std::string& url); - void setCapabilityDebug(const std::string& name, const std::string& url); - bool isCapabilityAvailable(const std::string& name) const; - // implements LLCapabilityProvider + LLViewerParcelOverlay *getParcelOverlay() const + { return mParcelOverlay; } + + inline void setRegionFlag(U64 flag, BOOL on); + inline BOOL getRegionFlag(U64 flag) const; + void setRegionFlags(U64 flags); + U64 getRegionFlags() const { return mRegionFlags; } + + inline void setRegionProtocol(U64 protocol, BOOL on); + BOOL getRegionProtocol(U64 protocol) const; + void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; } + U64 getRegionProtocols() const { return mRegionProtocols; } + + void setTimeDilation(F32 time_dilation); + F32 getTimeDilation() const { return mTimeDilation; } + + // Origin height is at zero. + const LLVector3d &getOriginGlobal() const; + LLVector3 getOriginAgent() const; + + // Center is at the height of the water table. + const LLVector3d &getCenterGlobal() const; + LLVector3 getCenterAgent() const; + + void setRegionNameAndZone(const std::string& name_and_zone); + const std::string& getName() const { return mName; } + const std::string& getZoning() const { return mZoning; } + + void setOwner(const LLUUID& owner_id); + const LLUUID& getOwner() const; + + // Is the current agent on the estate manager list for this region? + void setIsEstateManager(BOOL b) { mIsEstateManager = b; } + BOOL isEstateManager() const { return mIsEstateManager; } + BOOL canManageEstate() const; + + void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } + U8 getSimAccess() const { return mSimAccess; } + const std::string getSimAccessString() const; + + // Homestead-related getters; there are no setters as nobody should be + // setting them other than the individual message handler which is a member + S32 getSimClassID() const { return mClassID; } + S32 getSimCPURatio() const { return mCPURatio; } + const std::string& getSimColoName() const { return mColoName; } + const std::string& getSimProductSKU() const { return mProductSKU; } + std::string getLocalizedSimProductName() const; + + // Returns "Sandbox", "Expensive", etc. + static std::string regionFlagsToString(U64 flags); + + // Returns translated version of "Mature", "PG", "Adult", etc. + static std::string accessToString(U8 sim_access); + + // Returns "M", "PG", "A" etc. + static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); + + // Return access icon name + static std::string getAccessIcon(U8 sim_access); + + // helper function which just makes sure all interested parties + // can process the message. + static void processRegionInfo(LLMessageSystem* msg, void**); + + //check if the viewer camera is static + static BOOL isViewerCameraStatic(); + static void calcNewObjectCreationThrottle(); + + void setCacheID(const LLUUID& id); + + F32 getWidth() const { return mWidth; } + + // regions are expensive to release, this function gradually releases cache from memory + static void idleCleanup(F32 max_update_time); + + void idleUpdate(F32 max_update_time); + void lightIdleUpdate(); + bool addVisibleGroup(LLViewerOctreeGroup* group); + void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child); + void addActiveCacheEntry(LLVOCacheEntry* entry); + void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); + void killCacheEntry(U32 local_id); //physically delete the cache entry + + // Like idleUpdate, but forces everything to complete regardless of + // how long it takes. + void forceUpdate(); + + void connectNeighbor(LLViewerRegion *neighborp, U32 direction); + + void updateNetStats(); + + U32 getPacketsLost() const; + + S32 getHttpResponderID() const; + + // Get/set named capability URLs for this region. + void setSeedCapability(const std::string& url); + S32 getNumSeedCapRetries(); + void setCapability(const std::string& name, const std::string& url); + void setCapabilityDebug(const std::string& name, const std::string& url); + bool isCapabilityAvailable(const std::string& name) const; + // implements LLCapabilityProvider virtual std::string getCapability(const std::string& name) const; std::string getCapabilityDebug(const std::string& name) const; - // has region received its final (not seed) capability list? - bool capabilitiesReceived() const; + // has region received its final (not seed) capability list? + bool capabilitiesReceived() const; bool capabilitiesError() const; - void setCapabilitiesReceived(bool received); - void setCapabilitiesError(); - boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); + void setCapabilitiesReceived(bool received); + void setCapabilitiesError(); + boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); - static bool isSpecialCapabilityName(const std::string &name); - void logActiveCapabilities() const; + static bool isSpecialCapabilityName(const std::string &name); + void logActiveCapabilities() const; - // Utilities to post and get via + // Utilities to post and get via // HTTP using the agent's policy settings and headers. typedef LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t httpCallback_t; bool requestPostCapability(const std::string &capName, @@ -295,279 +295,279 @@ public: bool requestDelCapability(const std::string &capName, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL); /// implements LLCapabilityProvider - /*virtual*/ const LLHost& getHost() const; - const U64 &getHandle() const { return mHandle; } + /*virtual*/ const LLHost& getHost() const; + const U64 &getHandle() const { return mHandle; } + + LLSurface &getLand() const; - LLSurface &getLand() const; + // set and get the region id + const LLUUID& getRegionID() const; + void setRegionID(const LLUUID& region_id); - // set and get the region id - const LLUUID& getRegionID() const; - void setRegionID(const LLUUID& region_id); + BOOL pointInRegionGlobal(const LLVector3d &point_global) const; + LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const; + LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const; + LLVector3 getPosAgentFromRegion(const LLVector3 ®ion_pos) const; + LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const; - BOOL pointInRegionGlobal(const LLVector3d &point_global) const; - LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const; - LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const; - LLVector3 getPosAgentFromRegion(const LLVector3 ®ion_pos) const; - LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const; + LLVLComposition *getComposition() const; + F32 getCompositionXY(const S32 x, const S32 y) const; - LLVLComposition *getComposition() const; - F32 getCompositionXY(const S32 x, const S32 y) const; + BOOL isOwnedSelf(const LLVector3& pos); - BOOL isOwnedSelf(const LLVector3& pos); + // Owned by a group you belong to? (officer OR member) + BOOL isOwnedGroup(const LLVector3& pos); - // Owned by a group you belong to? (officer OR member) - BOOL isOwnedGroup(const LLVector3& pos); + // deal with map object updates in the world. + void updateCoarseLocations(LLMessageSystem* msg); - // deal with map object updates in the world. - void updateCoarseLocations(LLMessageSystem* msg); + F32 getLandHeightRegion(const LLVector3& region_pos); - F32 getLandHeightRegion(const LLVector3& region_pos); + U8 getCentralBakeVersion() { return mCentralBakeVersion; } - U8 getCentralBakeVersion() { return mCentralBakeVersion; } + void getInfo(LLSD& info); - void getInfo(LLSD& info); - - bool meshRezEnabled() const; - bool meshUploadEnabled() const; + bool meshRezEnabled() const; + bool meshUploadEnabled() const; - bool bakesOnMeshEnabled() const; + bool bakesOnMeshEnabled() const; - // has region received its simulator features list? Requires an additional query after caps received. + // has region received its simulator features list? Requires an additional query after caps received. void requestSimulatorFeatures(); - void setSimulatorFeaturesReceived(bool); - bool simulatorFeaturesReceived() const; - boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb); - - void getSimulatorFeatures(LLSD& info) const; - void setSimulatorFeatures(const LLSD& info); - - - bool dynamicPathfindingEnabled() const; - - bool avatarHoverHeightEnabled() const; - - typedef enum - { - CACHE_MISS_TYPE_TOTAL = 0, // total cache miss - object not in cache - CACHE_MISS_TYPE_CRC, // object in cache, but CRC doesn't match - CACHE_MISS_TYPE_NONE // not a miss: cache hit - } eCacheMissType; - - typedef enum - { - CACHE_UPDATE_DUPE = 0, - CACHE_UPDATE_CHANGED, - CACHE_UPDATE_ADDED, - CACHE_UPDATE_REPLACED - } eCacheUpdateResult; - - // handle a full update message - eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); - eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); + void setSimulatorFeaturesReceived(bool); + bool simulatorFeaturesReceived() const; + boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb); + + void getSimulatorFeatures(LLSD& info) const; + void setSimulatorFeatures(const LLSD& info); + + + bool dynamicPathfindingEnabled() const; + + bool avatarHoverHeightEnabled() const; + + typedef enum + { + CACHE_MISS_TYPE_TOTAL = 0, // total cache miss - object not in cache + CACHE_MISS_TYPE_CRC, // object in cache, but CRC doesn't match + CACHE_MISS_TYPE_NONE // not a miss: cache hit + } eCacheMissType; + + typedef enum + { + CACHE_UPDATE_DUPE = 0, + CACHE_UPDATE_CHANGED, + CACHE_UPDATE_ADDED, + CACHE_UPDATE_REPLACED + } eCacheUpdateResult; + + // handle a full update message + eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); void cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data); - LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); - LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true); - bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); - U64 getRegionCacheHitCount() { return mRegionCacheHitCount; } - U64 getRegionCacheMissCount() { return mRegionCacheMissCount; } - void requestCacheMisses(); - void addCacheMissFull(const U32 local_id); - //update object cache if the object receives a full-update or terse update - LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp); - void findOrphans(U32 parent_id); - void clearCachedVisibleObjects(); - void dumpCache (); + LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); + LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true); + bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); + U64 getRegionCacheHitCount() { return mRegionCacheHitCount; } + U64 getRegionCacheMissCount() { return mRegionCacheMissCount; } + void requestCacheMisses(); + void addCacheMissFull(const U32 local_id); + //update object cache if the object receives a full-update or terse update + LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp); + void findOrphans(U32 parent_id); + void clearCachedVisibleObjects(); + void dumpCache (); void clearVOCacheFromMemory(); - void unpackRegionHandshake(); + void unpackRegionHandshake(); - void calculateCenterGlobal(); - void calculateCameraDistance(); + void calculateCenterGlobal(); + void calculateCameraDistance(); - friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion); + friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion); /// implements LLCapabilityProvider virtual std::string getDescription() const; std::string getViewerAssetUrl() const { return mViewerAssetUrl; } - U32 getNumOfVisibleGroups() const; - U32 getNumOfActiveCachedObjects() const; - LLSpatialPartition* getSpatialPartition(U32 type); - LLVOCachePartition* getVOCachePartition(); + U32 getNumOfVisibleGroups() const; + U32 getNumOfActiveCachedObjects() const; + LLSpatialPartition* getSpatialPartition(U32 type); + LLVOCachePartition* getVOCachePartition(); - bool objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const; - bool childrenObjectReturnable( const std::vector& boxes ) const; - bool objectsCrossParcel(const std::vector& boxes) const; + bool objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const; + bool childrenObjectReturnable( const std::vector& boxes ) const; + bool objectsCrossParcel(const std::vector& boxes) const; - void getNeighboringRegions( std::vector& uniqueRegions ); - void getNeighboringRegionsStatus( std::vector& regions ); - const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } - LLViewerRegionImpl * getRegionImplNC() { return mImpl; } + void getNeighboringRegions( std::vector& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector& regions ); + const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } + LLViewerRegionImpl * getRegionImplNC() { return mImpl; } - // implements the materials capability throttle - bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } - void resetMaterialsCapThrottle(); - - U32 getMaxMaterialsPerTransaction() const; + // implements the materials capability throttle + bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } + void resetMaterialsCapThrottle(); - void removeFromCreatedList(U32 local_id); - void addToCreatedList(U32 local_id); + U32 getMaxMaterialsPerTransaction() const; - BOOL isPaused() const {return mPaused;} - S32 getLastUpdate() const {return mLastUpdate;} + void removeFromCreatedList(U32 local_id); + void addToCreatedList(U32 local_id); - std::string getSimHostName(); + BOOL isPaused() const {return mPaused;} + S32 getLastUpdate() const {return mLastUpdate;} - static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} + std::string getSimHostName(); + + static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} // rebuild reflection probe list void updateReflectionProbes(); private: - void addToVOCacheTree(LLVOCacheEntry* entry); - LLViewerObject* addNewObject(LLVOCacheEntry* entry); - void killObject(LLVOCacheEntry* entry, std::vector& delete_list); //adds entry into list if it is safe to move into cache - void removeFromVOCacheTree(LLVOCacheEntry* entry); - void killCacheEntry(LLVOCacheEntry* entry, bool for_rendering = false); //physically delete the cache entry - void killInvisibleObjects(F32 max_time); - void createVisibleObjects(F32 max_time); - void updateVisibleEntries(F32 max_time); //update visible entries - - void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type); - void decodeBoundingInfo(LLVOCacheEntry* entry); - bool isNonCacheableObjectCreated(U32 local_id); + void addToVOCacheTree(LLVOCacheEntry* entry); + LLViewerObject* addNewObject(LLVOCacheEntry* entry); + void killObject(LLVOCacheEntry* entry, std::vector& delete_list); //adds entry into list if it is safe to move into cache + void removeFromVOCacheTree(LLVOCacheEntry* entry); + void killCacheEntry(LLVOCacheEntry* entry, bool for_rendering = false); //physically delete the cache entry + void killInvisibleObjects(F32 max_time); + void createVisibleObjects(F32 max_time); + void updateVisibleEntries(F32 max_time); //update visible entries + + void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type); + void decodeBoundingInfo(LLVOCacheEntry* entry); + bool isNonCacheableObjectCreated(U32 local_id); public: void applyCacheMiscExtras(LLViewerObject* obj); - struct CompareDistance - { - bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) - { - return lhs->mCameraDistanceSquared < rhs->mCameraDistanceSquared; - } - }; + struct CompareDistance + { + bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) + { + return lhs->mCameraDistanceSquared < rhs->mCameraDistanceSquared; + } + }; - void showReleaseNotes(); + void showReleaseNotes(); protected: - void disconnectAllNeighbors(); - void initStats(); + void disconnectAllNeighbors(); + void initStats(); public: - LLWind mWind; - LLViewerParcelOverlay *mParcelOverlay; - - F32Bits mBitsReceived; - F32 mPacketsReceived; - - LLMatrix4 mRenderMatrix; - - // These arrays are maintained in parallel. Ideally they'd be combined into a - // single array of an aggrigate data type but for compatibility with the old - // messaging system in which the previous message only sends and parses the - // positions stored in the first array so they're maintained separately until - // we stop supporting the old CoarseLocationUpdate message. - std::vector mMapAvatars; - std::vector mMapAvatarIDs; - - static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not. - static S32 sLastCameraUpdated; - - LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; }; - LLFrameTimer & getRenderInfoReportTimer() { return mRenderInfoReportTimer; }; - - struct CompareRegionByLastUpdate - { - bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) const - { - S32 lpa = lhs->getLastUpdate(); - S32 rpa = rhs->getLastUpdate(); - - //small mLastUpdate first - if(lpa < rpa) - { - return true; - } - else if(lpa > rpa) - { - return false; - } - else - { - return lhs < rhs; - } - } - }; - typedef std::set region_priority_list_t; - - void setInterestListMode(const std::string & new_mode); + LLWind mWind; + LLViewerParcelOverlay *mParcelOverlay; + + F32Bits mBitsReceived; + F32 mPacketsReceived; + + LLMatrix4 mRenderMatrix; + + // These arrays are maintained in parallel. Ideally they'd be combined into a + // single array of an aggrigate data type but for compatibility with the old + // messaging system in which the previous message only sends and parses the + // positions stored in the first array so they're maintained separately until + // we stop supporting the old CoarseLocationUpdate message. + std::vector mMapAvatars; + std::vector mMapAvatarIDs; + + static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not. + static S32 sLastCameraUpdated; + + LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; }; + LLFrameTimer & getRenderInfoReportTimer() { return mRenderInfoReportTimer; }; + + struct CompareRegionByLastUpdate + { + bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) const + { + S32 lpa = lhs->getLastUpdate(); + S32 rpa = rhs->getLastUpdate(); + + //small mLastUpdate first + if(lpa < rpa) + { + return true; + } + else if(lpa > rpa) + { + return false; + } + else + { + return lhs < rhs; + } + } + }; + typedef std::set region_priority_list_t; + + void setInterestListMode(const std::string & new_mode); const std::string & getInterestListMode() const { return mInterestListMode; } - void resetInterestList(); + void resetInterestList(); - static const std::string IL_MODE_DEFAULT; + static const std::string IL_MODE_DEFAULT; static const std::string IL_MODE_360; private: - static S32 sNewObjectCreationThrottle; - LLViewerRegionImpl * mImpl; - LLFrameTimer mRegionTimer; - - F32 mWidth; // Width of region on a side (meters) - U64 mHandle; - F32 mTimeDilation; // time dilation of physics simulation on simulator - S32 mLastUpdate; //last time called idleUpdate() - - // simulator name - std::string mName; - std::string mZoning; - - // Is this agent on the estate managers list for this region? - BOOL mIsEstateManager; - - U32 mPacketsIn; - U32Bits mBitsIn, - mLastBitsIn; - U32 mLastPacketsIn; - U32 mPacketsOut; - U32 mLastPacketsOut; - S32 mPacketsLost; - S32 mLastPacketsLost; - U32Milliseconds mPingDelay; - F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc - - U64 mRegionFlags; // includes damage flags - U64 mRegionProtocols; // protocols supported by this region - U8 mSimAccess; - F32 mBillableFactor; - U32 mMaxTasks; // max prim count - F32 mCameraDistanceSquared; // updated once per frame - U8 mCentralBakeVersion; - - LLVOCacheEntry* mLastVisitedEntry; - U32 mInvisibilityCheckHistory; - - // Information for Homestead / CR-53 - S32 mClassID; - S32 mCPURatio; - - std::string mColoName; - std::string mProductSKU; - std::string mProductName; - std::string mViewerAssetUrl ; - - // Maps local ids to cache entries. - // Regions can have order 10,000 objects, so assume - // a structure of size 2^14 = 16,000 - BOOL mCacheLoaded; - BOOL mCacheDirty; - BOOL mAlive; // can become false if circuit disconnects - BOOL mSimulatorFeaturesReceived; - BOOL mReleaseNotesRequested; - BOOL mDead; //if true, this region is in the process of deleting. - BOOL mPaused; //pause processing the objects in the region + static S32 sNewObjectCreationThrottle; + LLViewerRegionImpl * mImpl; + LLFrameTimer mRegionTimer; + + F32 mWidth; // Width of region on a side (meters) + U64 mHandle; + F32 mTimeDilation; // time dilation of physics simulation on simulator + S32 mLastUpdate; //last time called idleUpdate() + + // simulator name + std::string mName; + std::string mZoning; + + // Is this agent on the estate managers list for this region? + BOOL mIsEstateManager; + + U32 mPacketsIn; + U32Bits mBitsIn, + mLastBitsIn; + U32 mLastPacketsIn; + U32 mPacketsOut; + U32 mLastPacketsOut; + S32 mPacketsLost; + S32 mLastPacketsLost; + U32Milliseconds mPingDelay; + F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc + + U64 mRegionFlags; // includes damage flags + U64 mRegionProtocols; // protocols supported by this region + U8 mSimAccess; + F32 mBillableFactor; + U32 mMaxTasks; // max prim count + F32 mCameraDistanceSquared; // updated once per frame + U8 mCentralBakeVersion; + + LLVOCacheEntry* mLastVisitedEntry; + U32 mInvisibilityCheckHistory; + + // Information for Homestead / CR-53 + S32 mClassID; + S32 mCPURatio; + + std::string mColoName; + std::string mProductSKU; + std::string mProductName; + std::string mViewerAssetUrl ; + + // Maps local ids to cache entries. + // Regions can have order 10,000 objects, so assume + // a structure of size 2^14 = 16,000 + BOOL mCacheLoaded; + BOOL mCacheDirty; + BOOL mAlive; // can become false if circuit disconnects + BOOL mSimulatorFeaturesReceived; + BOOL mReleaseNotesRequested; + BOOL mDead; //if true, this region is in the process of deleting. + BOOL mPaused; //pause processing the objects in the region typedef enum { @@ -576,39 +576,39 @@ public: CAPABILITIES_STATE_RECEIVED } eCababilitiesState; - eCababilitiesState mCapabilitiesState; + eCababilitiesState mCapabilitiesState; - typedef std::map > orphan_list_t; - orphan_list_t mOrphanMap; + typedef std::map > orphan_list_t; + orphan_list_t mOrphanMap; - class CacheMissItem - { - public: + class CacheMissItem + { + public: CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type) {} - U32 mID; //local object id - LLViewerRegion::eCacheMissType mType; // cache miss type + U32 mID; //local object id + LLViewerRegion::eCacheMissType mType; // cache miss type - typedef std::list cache_miss_list_t; - }; - CacheMissItem::cache_miss_list_t mCacheMissList; - U64 mRegionCacheHitCount; - U64 mRegionCacheMissCount; + typedef std::list cache_miss_list_t; + }; + CacheMissItem::cache_miss_list_t mCacheMissList; + U64 mRegionCacheHitCount; + U64 mRegionCacheMissCount; - caps_received_signal_t mCapabilitiesReceivedSignal; - caps_received_signal_t mSimulatorFeaturesReceivedSignal; + caps_received_signal_t mCapabilitiesReceivedSignal; + caps_received_signal_t mSimulatorFeaturesReceivedSignal; - LLSD mSimulatorFeatures; + LLSD mSimulatorFeatures; - typedef std::map > vocache_entry_map_t; + typedef std::map > vocache_entry_map_t; static vocache_entry_map_t sRegionCacheCleanup; - // the materials capability throttle - LLFrameTimer mMaterialsCapThrottleTimer; - LLFrameTimer mRenderInfoRequestTimer; - LLFrameTimer mRenderInfoReportTimer; + // the materials capability throttle + LLFrameTimer mMaterialsCapThrottleTimer; + LLFrameTimer mRenderInfoRequestTimer; + LLFrameTimer mRenderInfoReportTimer; - // how the server interest list works + // how the server interest list works std::string mInterestListMode; // list of reflection maps being managed by this llviewer region @@ -618,86 +618,86 @@ public: inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const { - return ((mRegionProtocols & protocol) != 0); + return ((mRegionProtocols & protocol) != 0); } inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on) { - if (on) - { - mRegionProtocols |= protocol; - } - else - { - mRegionProtocols &= ~protocol; - } + if (on) + { + mRegionProtocols |= protocol; + } + else + { + mRegionProtocols &= ~protocol; + } } inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const { - return ((mRegionFlags & flag) != 0); + return ((mRegionFlags & flag) != 0); } inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on) { - if (on) - { - mRegionFlags |= flag; - } - else - { - mRegionFlags &= ~flag; - } + if (on) + { + mRegionFlags |= flag; + } + else + { + mRegionFlags &= ~flag; + } } inline BOOL LLViewerRegion::getAllowDamage() const { - return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0); + return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0); } inline BOOL LLViewerRegion::getAllowLandmark() const { - return ((mRegionFlags & REGION_FLAGS_ALLOW_LANDMARK) !=0); + return ((mRegionFlags & REGION_FLAGS_ALLOW_LANDMARK) !=0); } inline BOOL LLViewerRegion::getAllowSetHome() const { - return ((mRegionFlags & REGION_FLAGS_ALLOW_SET_HOME) != 0); + return ((mRegionFlags & REGION_FLAGS_ALLOW_SET_HOME) != 0); } inline BOOL LLViewerRegion::getResetHomeOnTeleport() const { - return ((mRegionFlags & REGION_FLAGS_RESET_HOME_ON_TELEPORT) !=0); + return ((mRegionFlags & REGION_FLAGS_RESET_HOME_ON_TELEPORT) !=0); } inline BOOL LLViewerRegion::getSunFixed() const { - return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) !=0); + return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) !=0); } inline BOOL LLViewerRegion::getBlockFly() const { - return ((mRegionFlags & REGION_FLAGS_BLOCK_FLY) !=0); + return ((mRegionFlags & REGION_FLAGS_BLOCK_FLY) !=0); } inline BOOL LLViewerRegion::getAllowDirectTeleport() const { - return ((mRegionFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT) !=0); + return ((mRegionFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT) !=0); } inline BOOL LLViewerRegion::isPrelude() const { - return is_prelude( mRegionFlags ); + return is_prelude( mRegionFlags ); } inline BOOL LLViewerRegion::getAllowTerraform() const { - return ((mRegionFlags & REGION_FLAGS_BLOCK_TERRAFORM) == 0); + return ((mRegionFlags & REGION_FLAGS_BLOCK_TERRAFORM) == 0); } inline BOOL LLViewerRegion::getRestrictPushObject() const { - return ((mRegionFlags & REGION_FLAGS_RESTRICT_PUSHOBJECT) != 0); + return ((mRegionFlags & REGION_FLAGS_RESTRICT_PUSHOBJECT) != 0); } inline BOOL LLViewerRegion::getAllowEnvironmentOverride() const @@ -707,7 +707,7 @@ inline BOOL LLViewerRegion::getAllowEnvironmentOverride() const inline BOOL LLViewerRegion::getReleaseNotesRequested() const { - return mReleaseNotesRequested; + return mReleaseNotesRequested; } #endif diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5144b28ce9..d0846e3017 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewershadermgr.cpp * @brief Viewer shader manager implementation. * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -64,10 +64,10 @@ using std::pair; using std::make_pair; using std::string; -BOOL LLViewerShaderMgr::sInitialized = FALSE; -bool LLViewerShaderMgr::sSkipReload = false; +BOOL LLViewerShaderMgr::sInitialized = FALSE; +bool LLViewerShaderMgr::sSkipReload = false; -LLVector4 gShinyOrigin; +LLVector4 gShinyOrigin; S32 clamp_terrain_mapping(S32 mapping) { @@ -78,155 +78,155 @@ S32 clamp_terrain_mapping(S32 mapping) } //utility shaders -LLGLSLShader gOcclusionProgram; +LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; -LLGLSLShader gOcclusionCubeProgram; -LLGLSLShader gGlowCombineProgram; -LLGLSLShader gReflectionMipProgram; +LLGLSLShader gOcclusionCubeProgram; +LLGLSLShader gGlowCombineProgram; +LLGLSLShader gReflectionMipProgram; LLGLSLShader gGaussianProgram; LLGLSLShader gRadianceGenProgram; LLGLSLShader gHeroRadianceGenProgram; -LLGLSLShader gIrradianceGenProgram; -LLGLSLShader gGlowCombineFXAAProgram; -LLGLSLShader gTwoTextureCompareProgram; -LLGLSLShader gOneTextureFilterProgram; -LLGLSLShader gDebugProgram; +LLGLSLShader gIrradianceGenProgram; +LLGLSLShader gGlowCombineFXAAProgram; +LLGLSLShader gTwoTextureCompareProgram; +LLGLSLShader gOneTextureFilterProgram; +LLGLSLShader gDebugProgram; LLGLSLShader gSkinnedDebugProgram; -LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; -LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; -LLGLSLShader gClipProgram; -LLGLSLShader gAlphaMaskProgram; -LLGLSLShader gBenchmarkProgram; +LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +LLGLSLShader gClipProgram; +LLGLSLShader gAlphaMaskProgram; +LLGLSLShader gBenchmarkProgram; LLGLSLShader gReflectionProbeDisplayProgram; LLGLSLShader gCopyProgram; LLGLSLShader gCopyDepthProgram; //object shaders -LLGLSLShader gObjectPreviewProgram; +LLGLSLShader gObjectPreviewProgram; LLGLSLShader gSkinnedObjectPreviewProgram; LLGLSLShader gPhysicsPreviewProgram; -LLGLSLShader gObjectFullbrightAlphaMaskProgram; -LLGLSLShader gObjectBumpProgram; +LLGLSLShader gObjectFullbrightAlphaMaskProgram; +LLGLSLShader gObjectBumpProgram; LLGLSLShader gSkinnedObjectBumpProgram; -LLGLSLShader gObjectAlphaMaskNoColorProgram; +LLGLSLShader gObjectAlphaMaskNoColorProgram; //environment shaders -LLGLSLShader gWaterProgram; +LLGLSLShader gWaterProgram; LLGLSLShader gWaterEdgeProgram; -LLGLSLShader gUnderWaterProgram; +LLGLSLShader gUnderWaterProgram; //interface shaders -LLGLSLShader gHighlightProgram; +LLGLSLShader gHighlightProgram; LLGLSLShader gSkinnedHighlightProgram; -LLGLSLShader gHighlightNormalProgram; -LLGLSLShader gHighlightSpecularProgram; +LLGLSLShader gHighlightNormalProgram; +LLGLSLShader gHighlightSpecularProgram; -LLGLSLShader gDeferredHighlightProgram; +LLGLSLShader gDeferredHighlightProgram; -LLGLSLShader gPathfindingProgram; -LLGLSLShader gPathfindingNoNormalsProgram; +LLGLSLShader gPathfindingProgram; +LLGLSLShader gPathfindingNoNormalsProgram; //avatar shader handles -LLGLSLShader gAvatarProgram; -LLGLSLShader gAvatarEyeballProgram; -LLGLSLShader gImpostorProgram; +LLGLSLShader gAvatarProgram; +LLGLSLShader gAvatarEyeballProgram; +LLGLSLShader gImpostorProgram; // Effects Shaders -LLGLSLShader gGlowProgram; -LLGLSLShader gGlowExtractProgram; -LLGLSLShader gPostScreenSpaceReflectionProgram; +LLGLSLShader gGlowProgram; +LLGLSLShader gGlowExtractProgram; +LLGLSLShader gPostScreenSpaceReflectionProgram; // Deferred rendering shaders -LLGLSLShader gDeferredImpostorProgram; -LLGLSLShader gDeferredDiffuseProgram; -LLGLSLShader gDeferredDiffuseAlphaMaskProgram; +LLGLSLShader gDeferredImpostorProgram; +LLGLSLShader gDeferredDiffuseProgram; +LLGLSLShader gDeferredDiffuseAlphaMaskProgram; LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram; -LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; -LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; -LLGLSLShader gDeferredSkinnedDiffuseProgram; -LLGLSLShader gDeferredSkinnedBumpProgram; -LLGLSLShader gDeferredBumpProgram; -LLGLSLShader gDeferredTerrainProgram; -LLGLSLShader gDeferredTreeProgram; -LLGLSLShader gDeferredTreeShadowProgram; +LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; +LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; +LLGLSLShader gDeferredSkinnedDiffuseProgram; +LLGLSLShader gDeferredSkinnedBumpProgram; +LLGLSLShader gDeferredBumpProgram; +LLGLSLShader gDeferredTerrainProgram; +LLGLSLShader gDeferredTreeProgram; +LLGLSLShader gDeferredTreeShadowProgram; LLGLSLShader gDeferredSkinnedTreeShadowProgram; -LLGLSLShader gDeferredAvatarProgram; -LLGLSLShader gDeferredAvatarAlphaProgram; -LLGLSLShader gDeferredLightProgram; -LLGLSLShader gDeferredMultiLightProgram[16]; -LLGLSLShader gDeferredSpotLightProgram; -LLGLSLShader gDeferredMultiSpotLightProgram; -LLGLSLShader gDeferredSunProgram; +LLGLSLShader gDeferredAvatarProgram; +LLGLSLShader gDeferredAvatarAlphaProgram; +LLGLSLShader gDeferredLightProgram; +LLGLSLShader gDeferredMultiLightProgram[16]; +LLGLSLShader gDeferredSpotLightProgram; +LLGLSLShader gDeferredMultiSpotLightProgram; +LLGLSLShader gDeferredSunProgram; LLGLSLShader gHazeProgram; LLGLSLShader gHazeWaterProgram; -LLGLSLShader gDeferredBlurLightProgram; -LLGLSLShader gDeferredSoftenProgram; -LLGLSLShader gDeferredShadowProgram; +LLGLSLShader gDeferredBlurLightProgram; +LLGLSLShader gDeferredSoftenProgram; +LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredSkinnedShadowProgram; -LLGLSLShader gDeferredShadowCubeProgram; -LLGLSLShader gDeferredShadowAlphaMaskProgram; +LLGLSLShader gDeferredShadowCubeProgram; +LLGLSLShader gDeferredShadowAlphaMaskProgram; LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram; -LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram; -LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram; +LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram; +LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram; LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram; LLGLSLShader gDeferredSkinnedShadowGLTFAlphaBlendProgram; -LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; +LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram; -LLGLSLShader gDeferredAvatarShadowProgram; -LLGLSLShader gDeferredAvatarAlphaShadowProgram; -LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; -LLGLSLShader gDeferredAlphaProgram; -LLGLSLShader gHUDAlphaProgram; +LLGLSLShader gDeferredAvatarShadowProgram; +LLGLSLShader gDeferredAvatarAlphaShadowProgram; +LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; +LLGLSLShader gDeferredAlphaProgram; +LLGLSLShader gHUDAlphaProgram; LLGLSLShader gDeferredSkinnedAlphaProgram; -LLGLSLShader gDeferredAlphaImpostorProgram; +LLGLSLShader gDeferredAlphaImpostorProgram; LLGLSLShader gDeferredSkinnedAlphaImpostorProgram; -LLGLSLShader gDeferredAvatarEyesProgram; -LLGLSLShader gDeferredFullbrightProgram; +LLGLSLShader gDeferredAvatarEyesProgram; +LLGLSLShader gDeferredFullbrightProgram; LLGLSLShader gHUDFullbrightProgram; -LLGLSLShader gDeferredFullbrightAlphaMaskProgram; -LLGLSLShader gHUDFullbrightAlphaMaskProgram; -LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram; -LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram; -LLGLSLShader gDeferredEmissiveProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskProgram; +LLGLSLShader gHUDFullbrightAlphaMaskProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram; +LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram; +LLGLSLShader gDeferredEmissiveProgram; LLGLSLShader gDeferredSkinnedEmissiveProgram; -LLGLSLShader gDeferredPostProgram; -LLGLSLShader gDeferredCoFProgram; -LLGLSLShader gDeferredDoFCombineProgram; -LLGLSLShader gDeferredPostGammaCorrectProgram; +LLGLSLShader gDeferredPostProgram; +LLGLSLShader gDeferredCoFProgram; +LLGLSLShader gDeferredDoFCombineProgram; +LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gNoPostGammaCorrectProgram; LLGLSLShader gLegacyPostGammaCorrectProgram; -LLGLSLShader gExposureProgram; -LLGLSLShader gExposureProgramNoFade; -LLGLSLShader gLuminanceProgram; -LLGLSLShader gFXAAProgram; -LLGLSLShader gDeferredPostNoDoFProgram; -LLGLSLShader gDeferredWLSkyProgram; +LLGLSLShader gExposureProgram; +LLGLSLShader gExposureProgramNoFade; +LLGLSLShader gLuminanceProgram; +LLGLSLShader gFXAAProgram; +LLGLSLShader gDeferredPostNoDoFProgram; +LLGLSLShader gDeferredWLSkyProgram; LLGLSLShader gEnvironmentMapProgram; -LLGLSLShader gDeferredWLCloudProgram; -LLGLSLShader gDeferredWLSunProgram; -LLGLSLShader gDeferredWLMoonProgram; -LLGLSLShader gDeferredStarProgram; -LLGLSLShader gDeferredFullbrightShinyProgram; +LLGLSLShader gDeferredWLCloudProgram; +LLGLSLShader gDeferredWLSunProgram; +LLGLSLShader gDeferredWLMoonProgram; +LLGLSLShader gDeferredStarProgram; +LLGLSLShader gDeferredFullbrightShinyProgram; LLGLSLShader gHUDFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; -LLGLSLShader gDeferredSkinnedFullbrightProgram; +LLGLSLShader gDeferredSkinnedFullbrightProgram; LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram; LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram; -LLGLSLShader gNormalMapGenProgram; +LLGLSLShader gNormalMapGenProgram; LLGLSLShader gDeferredGenBrdfLutProgram; LLGLSLShader gDeferredBufferVisualProgram; // Deferred materials shaders -LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; -LLGLSLShader gHUDPBROpaqueProgram; +LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader gHUDPBROpaqueProgram; LLGLSLShader gPBRGlowProgram; LLGLSLShader gPBRGlowSkinnedProgram; -LLGLSLShader gDeferredPBROpaqueProgram; +LLGLSLShader gDeferredPBROpaqueProgram; LLGLSLShader gDeferredSkinnedPBROpaqueProgram; LLGLSLShader gHUDPBRAlphaProgram; LLGLSLShader gDeferredPBRAlphaProgram; LLGLSLShader gDeferredSkinnedPBRAlphaProgram; -LLGLSLShader gDeferredPBRTerrainProgram; +LLGLSLShader gDeferredPBRTerrainProgram; //helper for making a rigged variant of a given shader static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -275,15 +275,15 @@ static bool no_redundant_shaders(const std::vector& shaders) LLViewerShaderMgr::LLViewerShaderMgr() : - mShaderLevel(SHADER_COUNT, 0), - mMaxAvatarShaderLevel(0) -{ + mShaderLevel(SHADER_COUNT, 0), + mMaxAvatarShaderLevel(0) +{ } LLViewerShaderMgr::~LLViewerShaderMgr() { - mShaderLevel.clear(); - mShaderList.clear(); + mShaderLevel.clear(); + mShaderList.clear(); } void LLViewerShaderMgr::finalizeShaderList() @@ -336,46 +336,46 @@ void LLViewerShaderMgr::finalizeShaderList() mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram); mShaderList.push_back(&gDeferredTreeProgram); - // make sure there are no redundancies + // make sure there are no redundancies llassert(no_redundant_shaders(mShaderList)); } // static LLViewerShaderMgr * LLViewerShaderMgr::instance() { - if(NULL == sInstance) - { - sInstance = new LLViewerShaderMgr(); - } + if(NULL == sInstance) + { + sInstance = new LLViewerShaderMgr(); + } - return static_cast(sInstance); + return static_cast(sInstance); } // static void LLViewerShaderMgr::releaseInstance() { - if (sInstance != NULL) - { - delete sInstance; - sInstance = NULL; - } + if (sInstance != NULL) + { + delete sInstance; + sInstance = NULL; + } } void LLViewerShaderMgr::initAttribsAndUniforms(void) { - if (mReservedAttribs.empty()) - { - LLShaderMgr::initAttribsAndUniforms(); - } + if (mReservedAttribs.empty()) + { + LLShaderMgr::initAttribsAndUniforms(); + } } - + //============================================================================ // Set Levels S32 LLViewerShaderMgr::getShaderLevel(S32 type) { - return mShaderLevel[type]; + return mShaderLevel[type]; } //============================================================================ @@ -386,7 +386,7 @@ void LLViewerShaderMgr::setShaders() LL_PROFILE_ZONE_SCOPED; //setShaders might be called redundantly by gSavedSettings, so return on reentrance static bool reentrance = false; - + if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload) { return; @@ -403,25 +403,25 @@ void LLViewerShaderMgr::setShaders() return; } - { - static LLCachedControl shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true); - static LLUUID old_cache_version; - static LLUUID current_cache_version; - if (current_cache_version.isNull()) - { - HBXXH128 hash_obj; - hash_obj.update(LLVersionInfo::instance().getVersion()); - current_cache_version = hash_obj.digest(); + { + static LLCachedControl shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true); + static LLUUID old_cache_version; + static LLUUID current_cache_version; + if (current_cache_version.isNull()) + { + HBXXH128 hash_obj; + hash_obj.update(LLVersionInfo::instance().getVersion()); + current_cache_version = hash_obj.digest(); - old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion")); - gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString()); - } + old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion")); + gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString()); + } - initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version); - } + initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version); + } static LLCachedControl max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); - + // when using indexed texture rendering, leave some texture units available for shadow and reflection maps static LLCachedControl reserved_texture_units(gSavedSettings, "RenderReservedTextureIndices", 14); @@ -433,14 +433,14 @@ void LLViewerShaderMgr::setShaders() // Make sure the compiled shader map is cleared before we recompile shaders. mVertexShaderObjects.clear(); mFragmentShaderObjects.clear(); - + initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - unloadShaders(); + unloadShaders(); + + LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); - LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); - if (gViewerWindow) { gViewerWindow->setCursor(UI_CURSOR_WAIT); @@ -460,7 +460,7 @@ void LLViewerShaderMgr::setShaders() llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10)); - + S32 light_class = 3; S32 interface_class = 2; S32 env_class = 2; @@ -499,7 +499,7 @@ void LLViewerShaderMgr::setShaders() loadBasicShaders(); LLError::setDefaultLevel(lvl); LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL; - reentrance = false; // For hygiene only, re-try probably helps nothing + reentrance = false; // For hygiene only, re-try probably helps nothing return; } @@ -555,7 +555,7 @@ void LLViewerShaderMgr::setShaders() { //hardware skinning is enabled and rigged attachment shaders loaded correctly // cloth is a class3 shader S32 avatar_class = 1; - + // Set the actual level mShaderLevel[SHADER_AVATAR] = avatar_class; @@ -572,7 +572,7 @@ void LLViewerShaderMgr::setShaders() loaded = loaded && loadShadersDeferred(); llassert(loaded); - persistShaderCacheMetadata(); + persistShaderCacheMetadata(); if (gViewerWindow) { @@ -587,76 +587,76 @@ void LLViewerShaderMgr::setShaders() void LLViewerShaderMgr::unloadShaders() { - while (!LLGLSLShader::sInstances.empty()) - { - LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); - shader->unload(); - } - - mShaderLevel[SHADER_LIGHTING] = 0; - mShaderLevel[SHADER_OBJECT] = 0; - mShaderLevel[SHADER_AVATAR] = 0; - mShaderLevel[SHADER_ENVIRONMENT] = 0; - mShaderLevel[SHADER_WATER] = 0; - mShaderLevel[SHADER_INTERFACE] = 0; - mShaderLevel[SHADER_EFFECT] = 0; - mShaderLevel[SHADER_WINDLIGHT] = 0; - - gPipeline.mShadersLoaded = false; + while (!LLGLSLShader::sInstances.empty()) + { + LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); + shader->unload(); + } + + mShaderLevel[SHADER_LIGHTING] = 0; + mShaderLevel[SHADER_OBJECT] = 0; + mShaderLevel[SHADER_AVATAR] = 0; + mShaderLevel[SHADER_ENVIRONMENT] = 0; + mShaderLevel[SHADER_WATER] = 0; + mShaderLevel[SHADER_INTERFACE] = 0; + mShaderLevel[SHADER_EFFECT] = 0; + mShaderLevel[SHADER_WINDLIGHT] = 0; + + gPipeline.mShadersLoaded = false; } std::string LLViewerShaderMgr::loadBasicShaders() { - // Load basic dependency shaders first - // All of these have to load for any shaders to function - - S32 sum_lights_class = 3; + // Load basic dependency shaders first + // All of these have to load for any shaders to function + + S32 sum_lights_class = 3; #if LL_DARWIN - // Work around driver crashes on older Macs when using deferred rendering - // NORSPEC-59 - // - if (gGLManager.mIsMobileGF) - sum_lights_class = 3; + // Work around driver crashes on older Macs when using deferred rendering + // NORSPEC-59 + // + if (gGLManager.mIsMobileGF) + sum_lights_class = 3; #endif - // Use the feature table to mask out the max light level to use. Also make sure it's at least 1. - S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel"); - sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); - - // Load the Basic Vertex Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) - - vector< pair > shaders; - shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + // Use the feature table to mask out the max light level to use. Also make sure it's at least 1. + S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel"); + sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); + + // Load the Basic Vertex Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) + + vector< pair > shaders; + shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) ); - shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); - shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); + shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); + shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) ); - if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) - { - shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); - } - shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); + if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) + { + shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); + } + shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); - std::map attribs; - attribs["MAX_JOINTS_PER_MESH_OBJECT"] = - std::to_string(LLSkinningUtil::getMaxJointCount()); + std::map attribs; + attribs["MAX_JOINTS_PER_MESH_OBJECT"] = + std::to_string(LLSkinningUtil::getMaxJointCount()); BOOL ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections"); - bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f; + bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f; - S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3); + S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3); S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); @@ -675,11 +675,11 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["SSR"] = "1"; } - if (has_reflection_probes) - { + if (has_reflection_probes) + { attribs["REFMAP_LEVEL"] = std::to_string(probe_level); - attribs["REF_SAMPLE_COUNT"] = "32"; - } + attribs["REF_SAMPLE_COUNT"] = "32"; + } { // PBR terrain const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); @@ -691,94 +691,94 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail); } - LLGLSLShader::sGlobalDefines = attribs; + LLGLSLShader::sGlobalDefines = attribs; - // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_VERTEX_SHADER - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0) - { - LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; - return shaders[i].first; - } - } + // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. + for (U32 i = 0; i < shaders.size(); i++) + { + // Note usage of GL_VERTEX_SHADER + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0) + { + LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; + } + } - // Load the Basic Fragment Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) + // Load the Basic Fragment Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) - shaders.clear(); - S32 ch = 1; + shaders.clear(); + S32 ch = 1; - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { //use indexed texture rendering for GLSL >= 1.30 - ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1); - } + if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) + { //use indexed texture rendering for GLSL >= 1.30 + ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1); + } - std::vector index_channels; - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) ); + std::vector index_channels; + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) ); index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/globalF.glsl", 1)); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_FRAGMENT_SHADER - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0) - { - LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; - return shaders[i].first; - } - } - - return std::string(); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + + for (U32 i = 0; i < shaders.size(); i++) + { + // Note usage of GL_FRAGMENT_SHADER + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0) + { + LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; + } + } + + return std::string(); } BOOL LLViewerShaderMgr::loadShadersWater() { LL_PROFILE_ZONE_SCOPED; - BOOL success = TRUE; - BOOL terrainWaterSuccess = TRUE; - + BOOL success = TRUE; + BOOL terrainWaterSuccess = TRUE; + bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 && gSavedSettings.getS32("RenderShadowDetail") > 0; - if (mShaderLevel[SHADER_WATER] == 0) - { - gWaterProgram.unload(); - gWaterEdgeProgram.unload(); - gUnderWaterProgram.unload(); - return TRUE; - } - - if (success) - { - // load water shader - gWaterProgram.mName = "Water Shader"; - gWaterProgram.mFeatures.calculatesAtmospherics = true; + if (mShaderLevel[SHADER_WATER] == 0) + { + gWaterProgram.unload(); + gWaterEdgeProgram.unload(); + gUnderWaterProgram.unload(); + return TRUE; + } + + if (success) + { + // load water shader + gWaterProgram.mName = "Water Shader"; + gWaterProgram.mFeatures.calculatesAtmospherics = true; gWaterProgram.mFeatures.hasAtmospherics = true; - gWaterProgram.mFeatures.hasGamma = true; - gWaterProgram.mFeatures.hasSrgb = true; + gWaterProgram.mFeatures.hasGamma = true; + gWaterProgram.mFeatures.hasSrgb = true; gWaterProgram.mFeatures.hasReflectionProbes = true; gWaterProgram.mFeatures.hasShadows = use_sun_shadow; - gWaterProgram.mShaderFiles.clear(); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); + gWaterProgram.mShaderFiles.clear(); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); gWaterProgram.clearPermutations(); if (LLPipeline::sRenderTransparentWater) { @@ -790,27 +790,27 @@ BOOL LLViewerShaderMgr::loadShadersWater() gWaterProgram.addPermutation("HAS_SUN_SHADOW", "1"); } - gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - success = gWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - // load water shader - gWaterEdgeProgram.mName = "Water Edge Shader"; - gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; + gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + success = gWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + // load water shader + gWaterEdgeProgram.mName = "Water Edge Shader"; + gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; gWaterEdgeProgram.mFeatures.hasAtmospherics = true; - gWaterEdgeProgram.mFeatures.hasGamma = true; - gWaterEdgeProgram.mFeatures.hasSrgb = true; + gWaterEdgeProgram.mFeatures.hasGamma = true; + gWaterEdgeProgram.mFeatures.hasSrgb = true; gWaterEdgeProgram.mFeatures.hasReflectionProbes = true; gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow; - gWaterEdgeProgram.mShaderFiles.clear(); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); + gWaterEdgeProgram.mShaderFiles.clear(); + gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); + gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); gWaterEdgeProgram.clearPermutations(); - gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); + gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); if (LLPipeline::sRenderTransparentWater) { gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1"); @@ -820,54 +820,54 @@ BOOL LLViewerShaderMgr::loadShadersWater() { gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1"); } - gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - success = gWaterEdgeProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - //load under water vertex shader - gUnderWaterProgram.mName = "Underwater Shader"; - gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; - gUnderWaterProgram.mFeatures.hasAtmospherics = true; - gUnderWaterProgram.mShaderFiles.clear(); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER)); - gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + success = gWaterEdgeProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + //load under water vertex shader + gUnderWaterProgram.mName = "Underwater Shader"; + gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; + gUnderWaterProgram.mFeatures.hasAtmospherics = true; + gUnderWaterProgram.mShaderFiles.clear(); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER)); + gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gUnderWaterProgram.clearPermutations(); if (LLPipeline::sRenderTransparentWater) { gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1"); } - success = gUnderWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - /// Keep track of water shader levels - if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER] - || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]) - { - mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); - } - - if (!success) - { - mShaderLevel[SHADER_WATER] = 0; - return FALSE; - } - - // if we failed to load the terrain water shaders and we need them (using class2 water), - // then drop down to class1 water. - if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) - { - mShaderLevel[SHADER_WATER]--; - return loadShadersWater(); - } - - LLWorld::getInstance()->updateWaterObjects(); + success = gUnderWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + /// Keep track of water shader levels + if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER] + || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]) + { + mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); + } + + if (!success) + { + mShaderLevel[SHADER_WATER] = 0; + return FALSE; + } + + // if we failed to load the terrain water shaders and we need them (using class2 water), + // then drop down to class1 water. + if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) + { + mShaderLevel[SHADER_WATER]--; + return loadShadersWater(); + } + + LLWorld::getInstance()->updateWaterObjects(); return TRUE; } @@ -875,146 +875,146 @@ BOOL LLViewerShaderMgr::loadShadersWater() BOOL LLViewerShaderMgr::loadShadersEffects() { LL_PROFILE_ZONE_SCOPED; - BOOL success = TRUE; - - if (mShaderLevel[SHADER_EFFECT] == 0) - { - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - return TRUE; - } - - if (success) - { - gGlowProgram.mName = "Glow Shader (Post)"; - gGlowProgram.mShaderFiles.clear(); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER)); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER)); - gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; - success = gGlowProgram.createShader(NULL, NULL); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - - if (success) - { + BOOL success = TRUE; + + if (mShaderLevel[SHADER_EFFECT] == 0) + { + gGlowProgram.unload(); + gGlowExtractProgram.unload(); + return TRUE; + } + + if (success) + { + gGlowProgram.mName = "Glow Shader (Post)"; + gGlowProgram.mShaderFiles.clear(); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER)); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER)); + gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + success = gGlowProgram.createShader(NULL, NULL); + if (!success) + { + LLPipeline::sRenderGlow = FALSE; + } + } + + if (success) + { const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise"); const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : ""; - gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str()); - gGlowExtractProgram.mShaderFiles.clear(); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER)); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER)); - gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str()); + gGlowExtractProgram.mShaderFiles.clear(); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER)); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER)); + gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; if (use_glow_noise) { gGlowExtractProgram.addPermutation("HAS_NOISE", "1"); } - success = gGlowExtractProgram.createShader(NULL, NULL); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - - return success; + success = gGlowExtractProgram.createShader(NULL, NULL); + if (!success) + { + LLPipeline::sRenderGlow = FALSE; + } + } + + return success; } BOOL LLViewerShaderMgr::loadShadersDeferred() { LL_PROFILE_ZONE_SCOPED; - bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 && + bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 && gSavedSettings.getS32("RenderShadowDetail") > 0; - if (mShaderLevel[SHADER_DEFERRED] == 0) - { - gDeferredTreeProgram.unload(); - gDeferredTreeShadowProgram.unload(); + if (mShaderLevel[SHADER_DEFERRED] == 0) + { + gDeferredTreeProgram.unload(); + gDeferredTreeShadowProgram.unload(); gDeferredSkinnedTreeShadowProgram.unload(); - gDeferredDiffuseProgram.unload(); + gDeferredDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); - gDeferredDiffuseAlphaMaskProgram.unload(); + gDeferredDiffuseAlphaMaskProgram.unload(); gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); - gDeferredBumpProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); + gDeferredBumpProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gDeferredImpostorProgram.unload(); - gDeferredTerrainProgram.unload(); - gDeferredLightProgram.unload(); - for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) - { - gDeferredMultiLightProgram[i].unload(); - } - gDeferredSpotLightProgram.unload(); - gDeferredMultiSpotLightProgram.unload(); - gDeferredSunProgram.unload(); - gDeferredBlurLightProgram.unload(); - gDeferredSoftenProgram.unload(); - gDeferredShadowProgram.unload(); + gDeferredImpostorProgram.unload(); + gDeferredTerrainProgram.unload(); + gDeferredLightProgram.unload(); + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) + { + gDeferredMultiLightProgram[i].unload(); + } + gDeferredSpotLightProgram.unload(); + gDeferredMultiSpotLightProgram.unload(); + gDeferredSunProgram.unload(); + gDeferredBlurLightProgram.unload(); + gDeferredSoftenProgram.unload(); + gDeferredShadowProgram.unload(); gDeferredSkinnedShadowProgram.unload(); - gDeferredShadowCubeProgram.unload(); + gDeferredShadowCubeProgram.unload(); gDeferredShadowAlphaMaskProgram.unload(); gDeferredSkinnedShadowAlphaMaskProgram.unload(); gDeferredShadowGLTFAlphaMaskProgram.unload(); gDeferredSkinnedShadowGLTFAlphaMaskProgram.unload(); gDeferredShadowFullbrightAlphaMaskProgram.unload(); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload(); - gDeferredAvatarShadowProgram.unload(); + gDeferredAvatarShadowProgram.unload(); gDeferredAvatarAlphaShadowProgram.unload(); gDeferredAvatarAlphaMaskShadowProgram.unload(); - gDeferredAvatarProgram.unload(); - gDeferredAvatarAlphaProgram.unload(); - gDeferredAlphaProgram.unload(); + gDeferredAvatarProgram.unload(); + gDeferredAvatarAlphaProgram.unload(); + gDeferredAlphaProgram.unload(); gHUDAlphaProgram.unload(); gDeferredSkinnedAlphaProgram.unload(); - gDeferredFullbrightProgram.unload(); + gDeferredFullbrightProgram.unload(); gHUDFullbrightProgram.unload(); - gDeferredFullbrightAlphaMaskProgram.unload(); + gDeferredFullbrightAlphaMaskProgram.unload(); gHUDFullbrightAlphaMaskProgram.unload(); gDeferredFullbrightAlphaMaskAlphaProgram.unload(); gHUDFullbrightAlphaMaskAlphaProgram.unload(); - gDeferredEmissiveProgram.unload(); + gDeferredEmissiveProgram.unload(); gDeferredSkinnedEmissiveProgram.unload(); - gDeferredAvatarEyesProgram.unload(); - gDeferredPostProgram.unload(); - gDeferredCoFProgram.unload(); - gDeferredDoFCombineProgram.unload(); + gDeferredAvatarEyesProgram.unload(); + gDeferredPostProgram.unload(); + gDeferredCoFProgram.unload(); + gDeferredDoFCombineProgram.unload(); gExposureProgram.unload(); gExposureProgramNoFade.unload(); gLuminanceProgram.unload(); - gDeferredPostGammaCorrectProgram.unload(); + gDeferredPostGammaCorrectProgram.unload(); gNoPostGammaCorrectProgram.unload(); gLegacyPostGammaCorrectProgram.unload(); - gFXAAProgram.unload(); + gFXAAProgram.unload(); gEnvironmentMapProgram.unload(); - gDeferredWLSkyProgram.unload(); - gDeferredWLCloudProgram.unload(); + gDeferredWLSkyProgram.unload(); + gDeferredWLCloudProgram.unload(); gDeferredWLSunProgram.unload(); gDeferredWLMoonProgram.unload(); - gDeferredStarProgram.unload(); - gDeferredFullbrightShinyProgram.unload(); + gDeferredStarProgram.unload(); + gDeferredFullbrightShinyProgram.unload(); gHUDFullbrightShinyProgram.unload(); gDeferredSkinnedFullbrightShinyProgram.unload(); - gDeferredSkinnedFullbrightProgram.unload(); + gDeferredSkinnedFullbrightProgram.unload(); gDeferredSkinnedFullbrightAlphaMaskProgram.unload(); gDeferredSkinnedFullbrightAlphaMaskAlphaProgram.unload(); gDeferredHighlightProgram.unload(); - - gNormalMapGenProgram.unload(); + + gNormalMapGenProgram.unload(); gDeferredGenBrdfLutProgram.unload(); - gDeferredBufferVisualProgram.unload(); + gDeferredBufferVisualProgram.unload(); - for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) - { - gDeferredMaterialProgram[i].unload(); - } + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) + { + gDeferredMaterialProgram[i].unload(); + } gHUDPBROpaqueProgram.unload(); gPBRGlowProgram.unload(); @@ -1022,95 +1022,95 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedPBROpaqueProgram.unload(); gDeferredPBRAlphaProgram.unload(); gDeferredSkinnedPBRAlphaProgram.unload(); - gDeferredPBRTerrainProgram.unload(); + gDeferredPBRTerrainProgram.unload(); - return TRUE; - } + return TRUE; + } - BOOL success = TRUE; + BOOL success = TRUE; if (success) - { - gDeferredHighlightProgram.mName = "Deferred Highlight Shader"; - gDeferredHighlightProgram.mShaderFiles.clear(); - gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER)); - gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gDeferredHighlightProgram.createShader(NULL, NULL); - } + { + gDeferredHighlightProgram.mName = "Deferred Highlight Shader"; + gDeferredHighlightProgram.mShaderFiles.clear(); + gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER)); + gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gDeferredHighlightProgram.createShader(NULL, NULL); + } - if (success) - { - gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; + if (success) + { + gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; gDeferredDiffuseProgram.mFeatures.hasSrgb = true; - gDeferredDiffuseProgram.mShaderFiles.clear(); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER)); - gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredDiffuseProgram.mShaderFiles.clear(); + gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); + gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER)); + gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram); - success = success && gDeferredDiffuseProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader"; - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear(); - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER)); - gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = success && gDeferredDiffuseProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader"; + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear(); + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER)); + gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram); - success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL); + success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear(); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader"; - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER)); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER)); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredBumpProgram.mName = "Deferred Bump Shader"; - gDeferredBumpProgram.mShaderFiles.clear(); - gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER)); - gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER)); - gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + } + + if (success) + { + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader"; + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear(); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER)); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER)); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredBumpProgram.mName = "Deferred Bump Shader"; + gDeferredBumpProgram.mShaderFiles.clear(); + gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER)); + gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER)); + gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram); - success = success && gDeferredBumpProgram.createShader(NULL, NULL); - llassert(success); - } - - gDeferredMaterialProgram[1].mFeatures.hasLighting = false; - gDeferredMaterialProgram[5].mFeatures.hasLighting = false; - gDeferredMaterialProgram[9].mFeatures.hasLighting = false; - gDeferredMaterialProgram[13].mFeatures.hasLighting = false; - gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - - for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) - { - if (success) - { + success = success && gDeferredBumpProgram.createShader(NULL, NULL); + llassert(success); + } + + gDeferredMaterialProgram[1].mFeatures.hasLighting = false; + gDeferredMaterialProgram[5].mFeatures.hasLighting = false; + gDeferredMaterialProgram[9].mFeatures.hasLighting = false; + gDeferredMaterialProgram[13].mFeatures.hasLighting = false; + gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) + { + if (success) + { bool has_skin = i & 0x10; if (!has_skin) @@ -1122,28 +1122,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredMaterialProgram[i].mName = llformat("Skinned Material Shader %d", i); } - - U32 alpha_mode = i & 0x3; - gDeferredMaterialProgram[i].mShaderFiles.clear(); - gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER)); - gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER)); - gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + U32 alpha_mode = i & 0x3; - gDeferredMaterialProgram[i].clearPermutations(); + gDeferredMaterialProgram[i].mShaderFiles.clear(); + gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER)); + gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER)); + gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - bool has_normal_map = (i & 0x8) > 0; - bool has_specular_map = (i & 0x4) > 0; + gDeferredMaterialProgram[i].clearPermutations(); - if (has_normal_map) - { - gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1"); - } + bool has_normal_map = (i & 0x8) > 0; + bool has_specular_map = (i & 0x4) > 0; - if (has_specular_map) - { - gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1"); - } + if (has_normal_map) + { + gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1"); + } + + if (has_specular_map) + { + gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1"); + } gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); @@ -1158,7 +1158,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); } - + gDeferredMaterialProgram[i].mFeatures.hasSrgb = true; gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true; gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true; @@ -1178,17 +1178,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMaterialProgram[i].createShader(NULL, NULL); llassert(success); - } - } + } + } - gDeferredMaterialProgram[1].mFeatures.hasLighting = true; - gDeferredMaterialProgram[5].mFeatures.hasLighting = true; - gDeferredMaterialProgram[9].mFeatures.hasLighting = true; - gDeferredMaterialProgram[13].mFeatures.hasLighting = true; - gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[1].mFeatures.hasLighting = true; + gDeferredMaterialProgram[5].mFeatures.hasLighting = true; + gDeferredMaterialProgram[9].mFeatures.hasLighting = true; + gDeferredMaterialProgram[13].mFeatures.hasLighting = true; + gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; if (success) { @@ -1200,7 +1200,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER)); gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredPBROpaqueProgram.clearPermutations(); - + success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram); if (success) { @@ -1238,17 +1238,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1"); success = gHUDPBROpaqueProgram.createShader(NULL, NULL); - + llassert(success); } - - if (success) - { + + if (success) + { LLGLSLShader* shader = &gDeferredPBRAlphaProgram; shader->mName = "Deferred PBR Alpha Shader"; - + shader->mFeatures.calculatesLighting = false; shader->mFeatures.hasLighting = false; shader->mFeatures.isAlphaLighting = true; @@ -1301,7 +1301,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() shader->mName = "HUD PBR Alpha Shader"; shader->mFeatures.hasSrgb = true; - + shader->mShaderFiles.clear(); shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); @@ -1315,8 +1315,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { + if (success) + { S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); @@ -1340,29 +1340,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT", llformat("%d", mapping)); success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredTreeProgram.mName = "Deferred Tree Shader"; - gDeferredTreeProgram.mShaderFiles.clear(); - gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER)); - gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER)); - gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredTreeProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader"; - gDeferredTreeShadowProgram.mShaderFiles.clear(); - gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER)); - gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + } + + if (success) + { + gDeferredTreeProgram.mName = "Deferred Tree Shader"; + gDeferredTreeProgram.mShaderFiles.clear(); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER)); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER)); + gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredTreeProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader"; + gDeferredTreeShadowProgram.mShaderFiles.clear(); + gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER)); + gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram; - success = gDeferredTreeShadowProgram.createShader(NULL, NULL); + success = gDeferredTreeShadowProgram.createShader(NULL, NULL); llassert(success); - } + } if (success) { @@ -1376,96 +1376,96 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; - gDeferredImpostorProgram.mFeatures.hasSrgb = true; - gDeferredImpostorProgram.mShaderFiles.clear(); - gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER)); + if (success) + { + gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; + gDeferredImpostorProgram.mFeatures.hasSrgb = true; + gDeferredImpostorProgram.mShaderFiles.clear(); + gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER)); gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER)); gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredImpostorProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredLightProgram.mName = "Deferred Light Shader"; - gDeferredLightProgram.mFeatures.isDeferred = true; - gDeferredLightProgram.mFeatures.hasShadows = true; + if (success) + { + gDeferredLightProgram.mName = "Deferred Light Shader"; + gDeferredLightProgram.mFeatures.isDeferred = true; + gDeferredLightProgram.mFeatures.hasShadows = true; gDeferredLightProgram.mFeatures.hasSrgb = true; - gDeferredLightProgram.mShaderFiles.clear(); - gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER)); - gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredLightProgram.mShaderFiles.clear(); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER)); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredLightProgram.clearPermutations(); - success = gDeferredLightProgram.createShader(NULL, NULL); + success = gDeferredLightProgram.createShader(NULL, NULL); llassert(success); - } - - for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++) - { - if (success) - { - gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); - gDeferredMultiLightProgram[i].mFeatures.isDeferred = true; - gDeferredMultiLightProgram[i].mFeatures.hasShadows = true; + } + + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++) + { + if (success) + { + gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); + gDeferredMultiLightProgram[i].mFeatures.isDeferred = true; + gDeferredMultiLightProgram[i].mFeatures.hasShadows = true; gDeferredMultiLightProgram[i].mFeatures.hasSrgb = true; gDeferredMultiLightProgram[i].clearPermutations(); - gDeferredMultiLightProgram[i].mShaderFiles.clear(); - gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER)); - gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); + gDeferredMultiLightProgram[i].mShaderFiles.clear(); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER)); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); - success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); + success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); llassert(success); - } - } + } + } - if (success) - { - gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; - gDeferredSpotLightProgram.mShaderFiles.clear(); - gDeferredSpotLightProgram.mFeatures.hasSrgb = true; - gDeferredSpotLightProgram.mFeatures.isDeferred = true; - gDeferredSpotLightProgram.mFeatures.hasShadows = true; + if (success) + { + gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; + gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredSpotLightProgram.mFeatures.isDeferred = true; + gDeferredSpotLightProgram.mFeatures.hasShadows = true; gDeferredSpotLightProgram.clearPermutations(); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER)); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredSpotLightProgram.createShader(NULL, NULL); + success = gDeferredSpotLightProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; - gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true; - gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true; - gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true; + if (success) + { + gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true; + gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true; gDeferredMultiSpotLightProgram.clearPermutations(); gDeferredMultiSpotLightProgram.addPermutation("MULTI_SPOTLIGHT", "1"); - gDeferredMultiSpotLightProgram.mShaderFiles.clear(); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER)); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredMultiSpotLightProgram.mShaderFiles.clear(); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); + success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - std::string fragment; - std::string vertex = "deferred/sunLightV.glsl"; + if (success) + { + std::string fragment; + std::string vertex = "deferred/sunLightV.glsl"; bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO"); @@ -1488,30 +1488,30 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao; gDeferredSunProgram.mShaderFiles.clear(); - gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER)); - gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER)); - gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER)); + gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER)); + gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSunProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; - gDeferredBlurLightProgram.mFeatures.isDeferred = true; + if (success) + { + gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; + gDeferredBlurLightProgram.mFeatures.isDeferred = true; - gDeferredBlurLightProgram.mShaderFiles.clear(); - gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER)); - gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredBlurLightProgram.mShaderFiles.clear(); + gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER)); + gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredBlurLightProgram.createShader(NULL, NULL); + success = gDeferredBlurLightProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { + if (success) + { for (int i = 0; i < 3 && success; ++i) { LLGLSLShader* shader = nullptr; @@ -1584,9 +1584,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - LLGLSLShader* shaders[] = { - &gDeferredAlphaImpostorProgram, - &gDeferredSkinnedAlphaImpostorProgram + LLGLSLShader* shaders[] = { + &gDeferredAlphaImpostorProgram, + &gDeferredSkinnedAlphaImpostorProgram }; for (int i = 0; i < 2 && success; ++i) @@ -1641,40 +1641,40 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } } - if (success) - { - gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; - gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; - gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true; - gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; - gDeferredAvatarEyesProgram.mFeatures.hasShadows = true; - - gDeferredAvatarEyesProgram.mShaderFiles.clear(); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader"; - gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightProgram.mFeatures.hasGamma = true; - gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true; - gDeferredFullbrightProgram.mFeatures.hasSrgb = true; - gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightProgram.mShaderFiles.clear(); - gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); - gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (success) + { + gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; + gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; + gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true; + gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; + gDeferredAvatarEyesProgram.mFeatures.hasShadows = true; + + gDeferredAvatarEyesProgram.mShaderFiles.clear(); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER)); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER)); + gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader"; + gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightProgram.mFeatures.hasGamma = true; + gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true; + gDeferredFullbrightProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightProgram.mShaderFiles.clear(); + gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); + gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram); - success = gDeferredFullbrightProgram.createShader(NULL, NULL); - llassert(success); - } + success = gDeferredFullbrightProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -1694,24 +1694,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader"; - gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); + if (success) + { + gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader"; + gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gDeferredFullbrightAlphaMaskProgram.clearPermutations(); - gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); - gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); + gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram); - success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } + success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -1774,23 +1774,23 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; - gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true; - gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; - gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true; - gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightShinyProgram.mShaderFiles.clear(); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); - gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (success) + { + gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; + gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true; + gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; + gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightShinyProgram.mShaderFiles.clear(); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); + gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true; success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram); - success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL); - llassert(success); - } + success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -1811,54 +1811,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredEmissiveProgram.mName = "Deferred Emissive Shader"; - gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true; - gDeferredEmissiveProgram.mFeatures.hasGamma = true; - gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true; - gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredEmissiveProgram.mShaderFiles.clear(); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER)); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER)); - gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (success) + { + gDeferredEmissiveProgram.mName = "Deferred Emissive Shader"; + gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true; + gDeferredEmissiveProgram.mFeatures.hasGamma = true; + gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true; + gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredEmissiveProgram.mShaderFiles.clear(); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER)); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER)); + gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram); - success = success && gDeferredEmissiveProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSoftenProgram.mName = "Deferred Soften Shader"; - gDeferredSoftenProgram.mShaderFiles.clear(); - gDeferredSoftenProgram.mFeatures.hasSrgb = true; - gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; - gDeferredSoftenProgram.mFeatures.hasGamma = true; - gDeferredSoftenProgram.mFeatures.isDeferred = true; - gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow; + success = success && gDeferredEmissiveProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSoftenProgram.mName = "Deferred Soften Shader"; + gDeferredSoftenProgram.mShaderFiles.clear(); + gDeferredSoftenProgram.mFeatures.hasSrgb = true; + gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasGamma = true; + gDeferredSoftenProgram.mFeatures.isDeferred = true; + gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow; gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2; gDeferredSoftenProgram.clearPermutations(); - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER)); - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; if (use_sun_shadow) { gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1"); } - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //if using SSAO, take screen space light map into account as if shadows are enabled - gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); + if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + { //if using SSAO, take screen space light map into account as if shadows are enabled + gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1"); - } - - success = gDeferredSoftenProgram.createShader(NULL, NULL); - llassert(success); - } + } + + success = gDeferredSoftenProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -1907,17 +1907,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } - if (success) - { - gDeferredShadowProgram.mName = "Deferred Shadow Shader"; - gDeferredShadowProgram.mShaderFiles.clear(); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; - success = gDeferredShadowProgram.createShader(NULL, NULL); - llassert(success); - } + if (success) + { + gDeferredShadowProgram.mName = "Deferred Shadow Shader"; + gDeferredShadowProgram.mShaderFiles.clear(); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; + success = gDeferredShadowProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -1934,52 +1934,52 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; - gDeferredShadowCubeProgram.mFeatures.isDeferred = true; - gDeferredShadowCubeProgram.mFeatures.hasShadows = true; - gDeferredShadowCubeProgram.mShaderFiles.clear(); - gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER)); - gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); - // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); - gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredShadowCubeProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader"; - gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - - gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear(); - gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); - gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); + if (success) + { + gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; + gDeferredShadowCubeProgram.mFeatures.isDeferred = true; + gDeferredShadowCubeProgram.mFeatures.hasShadows = true; + gDeferredShadowCubeProgram.mShaderFiles.clear(); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER)); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); + // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); + gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowCubeProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader"; + gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations(); - gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); - gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredShadowFullbrightAlphaMaskProgram, gDeferredSkinnedShadowFullbrightAlphaMaskProgram); success = success && gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; - gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - - gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); - gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); - gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + llassert(success); + } + + if (success) + { + gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; + gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + + gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); + gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); + gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); + gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(gDeferredShadowAlphaMaskProgram, gDeferredSkinnedShadowAlphaMaskProgram); success = success && gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } - + llassert(success); + } + if (success) { @@ -2007,108 +2007,108 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; - gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; - - gDeferredAvatarShadowProgram.mShaderFiles.clear(); - gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader"; - gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); - gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); + if (success) + { + gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; + gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; + + gDeferredAvatarShadowProgram.mShaderFiles.clear(); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER)); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); llassert(success); - } - if (success) - { - gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader"; - gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); - gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader"; + gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true; + gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); + gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); + gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) + { + gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader"; + gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true; + gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); + gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); + gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; - gDeferredTerrainProgram.mFeatures.hasSrgb = true; - gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; - gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true; - gDeferredTerrainProgram.mFeatures.hasAtmospherics = true; - gDeferredTerrainProgram.mFeatures.hasGamma = true; - - gDeferredTerrainProgram.mShaderFiles.clear(); - gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER)); - gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER)); - gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + } + + if (success) + { + gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; + gDeferredTerrainProgram.mFeatures.hasSrgb = true; + gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredTerrainProgram.mFeatures.hasGamma = true; + + gDeferredTerrainProgram.mShaderFiles.clear(); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER)); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER)); + gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredTerrainProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAvatarProgram.mName = "Deferred Avatar Shader"; - gDeferredAvatarProgram.mFeatures.hasSkinning = true; - gDeferredAvatarProgram.mShaderFiles.clear(); - gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader"; - gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; - gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true; - gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; + llassert(success); + } + + if (success) + { + gDeferredAvatarProgram.mName = "Deferred Avatar Shader"; + gDeferredAvatarProgram.mFeatures.hasSkinning = true; + gDeferredAvatarProgram.mShaderFiles.clear(); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER)); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER)); + gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader"; + gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; + gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true; - gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true; + gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true; gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true; - gDeferredAvatarAlphaProgram.mShaderFiles.clear(); + gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaProgram.clearPermutations(); - gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); - if (use_sun_shadow) - { - gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1"); - } + gDeferredAvatarAlphaProgram.clearPermutations(); + gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); + gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); + if (use_sun_shadow) + { + gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1"); + } - gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL); - llassert(success); + success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL); + llassert(success); - gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; - gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; - } + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; + } if (success) { @@ -2151,20 +2151,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; - gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; - gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; - gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); + if (success) + { + gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; + gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; + gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; + gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); gDeferredPostGammaCorrectProgram.clearPermutations(); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); - llassert(success); - } - + success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process"; @@ -2196,65 +2196,65 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } - if (success && gGLManager.mGLVersion > 3.9f) - { - gFXAAProgram.mName = "FXAA Shader"; - gFXAAProgram.mFeatures.isDeferred = true; - gFXAAProgram.mShaderFiles.clear(); - gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER)); - gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER)); - gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gFXAAProgram.createShader(NULL, NULL); - llassert(success); - } + if (success && gGLManager.mGLVersion > 3.9f) + { + gFXAAProgram.mName = "FXAA Shader"; + gFXAAProgram.mFeatures.isDeferred = true; + gFXAAProgram.mShaderFiles.clear(); + gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER)); + gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER)); + gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gFXAAProgram.createShader(NULL, NULL); + llassert(success); + } - if (success) - { - gDeferredPostProgram.mName = "Deferred Post Shader"; + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; gDeferredPostProgram.mFeatures.isDeferred = true; - gDeferredPostProgram.mShaderFiles.clear(); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER)); - gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredCoFProgram.mName = "Deferred CoF Shader"; - gDeferredCoFProgram.mShaderFiles.clear(); - gDeferredCoFProgram.mFeatures.isDeferred = true; - gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER)); - gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredCoFProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; - gDeferredDoFCombineProgram.mFeatures.isDeferred = true; - gDeferredDoFCombineProgram.mShaderFiles.clear(); - gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER)); - gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDoFCombineProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader"; - gDeferredPostNoDoFProgram.mFeatures.isDeferred = true; - gDeferredPostNoDoFProgram.mShaderFiles.clear(); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER)); - gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); - llassert(success); - } + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredCoFProgram.mName = "Deferred CoF Shader"; + gDeferredCoFProgram.mShaderFiles.clear(); + gDeferredCoFProgram.mFeatures.isDeferred = true; + gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER)); + gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredCoFProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; + gDeferredDoFCombineProgram.mFeatures.isDeferred = true; + gDeferredDoFCombineProgram.mShaderFiles.clear(); + gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER)); + gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredDoFCombineProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader"; + gDeferredPostNoDoFProgram.mFeatures.isDeferred = true; + gDeferredPostNoDoFProgram.mShaderFiles.clear(); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -2276,45 +2276,45 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; - gDeferredWLSkyProgram.mShaderFiles.clear(); - gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true; - gDeferredWLSkyProgram.mFeatures.hasGamma = true; - gDeferredWLSkyProgram.mFeatures.hasSrgb = true; - - gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER)); - gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER)); - gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - - success = gDeferredWLSkyProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; - gDeferredWLCloudProgram.mShaderFiles.clear(); - gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true; + if (success) + { + gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; + gDeferredWLSkyProgram.mShaderFiles.clear(); + gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true; + gDeferredWLSkyProgram.mFeatures.hasGamma = true; + gDeferredWLSkyProgram.mFeatures.hasSrgb = true; + + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER)); + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER)); + gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; + + success = gDeferredWLSkyProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; + gDeferredWLCloudProgram.mShaderFiles.clear(); + gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true; gDeferredWLCloudProgram.mFeatures.hasGamma = true; gDeferredWLCloudProgram.mFeatures.hasSrgb = true; - - gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER)); - gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER)); - gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; + + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER)); + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER)); + gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113 - success = gDeferredWLCloudProgram.createShader(NULL, NULL); - llassert(success); - } + success = gDeferredWLCloudProgram.createShader(NULL, NULL); + llassert(success); + } - if (success) - { - gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; + if (success) + { + gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true; gDeferredWLSunProgram.mFeatures.hasAtmospherics = true; gDeferredWLSunProgram.mFeatures.hasGamma = true; @@ -2339,40 +2339,40 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true; gDeferredWLMoonProgram.mFeatures.hasSrgb = true; gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true; - + gDeferredWLMoonProgram.mShaderFiles.clear(); gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER)); gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER)); gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY; gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113 - success = gDeferredWLMoonProgram.createShader(NULL, NULL); + success = gDeferredWLMoonProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredStarProgram.mName = "Deferred Star Program"; - gDeferredStarProgram.mShaderFiles.clear(); - gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER)); - gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER)); - gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; + } + + if (success) + { + gDeferredStarProgram.mName = "Deferred Star Program"; + gDeferredStarProgram.mShaderFiles.clear(); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER)); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER)); + gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113 - success = gDeferredStarProgram.createShader(NULL, NULL); + success = gDeferredStarProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gNormalMapGenProgram.mName = "Normal Map Generation Program"; - gNormalMapGenProgram.mShaderFiles.clear(); - gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER)); - gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER)); - gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gNormalMapGenProgram.createShader(NULL, NULL); - } + if (success) + { + gNormalMapGenProgram.mName = "Normal Map Generation Program"; + gNormalMapGenProgram.mShaderFiles.clear(); + gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER)); + gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER)); + gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gNormalMapGenProgram.createShader(NULL, NULL); + } if (success) { @@ -2384,7 +2384,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL); } - if (success) { + if (success) { gPostScreenSpaceReflectionProgram.mName = "Screen Space Reflection Post"; gPostScreenSpaceReflectionProgram.mShaderFiles.clear(); gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostV.glsl", GL_VERTEX_SHADER)); @@ -2393,24 +2393,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gPostScreenSpaceReflectionProgram.mFeatures.isDeferred = true; gPostScreenSpaceReflectionProgram.mShaderLevel = 3; success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL); - } - - if (success) { - gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader"; - gDeferredBufferVisualProgram.mShaderFiles.clear(); - gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER)); - gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredBufferVisualProgram.createShader(NULL, NULL); - } - - return success; + } + + if (success) { + gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader"; + gDeferredBufferVisualProgram.mShaderFiles.clear(); + gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER)); + gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredBufferVisualProgram.createShader(NULL, NULL); + } + + return success; } BOOL LLViewerShaderMgr::loadShadersObject() { LL_PROFILE_ZONE_SCOPED; - BOOL success = TRUE; + BOOL success = TRUE; if (success) { @@ -2434,66 +2434,66 @@ BOOL LLViewerShaderMgr::loadShadersObject() } } - if (success) - { - gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader"; - gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true; - gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true; - gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true; - gObjectAlphaMaskNoColorProgram.mShaderFiles.clear(); - gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER)); - gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); - gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL); - } - - if (success) - { - gImpostorProgram.mName = "Impostor Shader"; - gImpostorProgram.mFeatures.disableTextureIndex = true; - gImpostorProgram.mFeatures.hasSrgb = true; - gImpostorProgram.mShaderFiles.clear(); - gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER)); - gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER)); - gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gImpostorProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectPreviewProgram.mName = "Object Preview Shader"; - gObjectPreviewProgram.mFeatures.disableTextureIndex = true; - gObjectPreviewProgram.mShaderFiles.clear(); - gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER)); - gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER)); - gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + if (success) + { + gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader"; + gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true; + gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true; + gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true; + gObjectAlphaMaskNoColorProgram.mShaderFiles.clear(); + gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER)); + gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); + gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL); + } + + if (success) + { + gImpostorProgram.mName = "Impostor Shader"; + gImpostorProgram.mFeatures.disableTextureIndex = true; + gImpostorProgram.mFeatures.hasSrgb = true; + gImpostorProgram.mShaderFiles.clear(); + gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER)); + gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER)); + gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gImpostorProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectPreviewProgram.mName = "Object Preview Shader"; + gObjectPreviewProgram.mFeatures.disableTextureIndex = true; + gObjectPreviewProgram.mShaderFiles.clear(); + gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER)); + gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER)); + gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram); - success = gObjectPreviewProgram.createShader(NULL, NULL); - gObjectPreviewProgram.mFeatures.hasLighting = true; + success = gObjectPreviewProgram.createShader(NULL, NULL); + gObjectPreviewProgram.mFeatures.hasLighting = true; gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gPhysicsPreviewProgram.mName = "Preview Physics Shader"; - gPhysicsPreviewProgram.mFeatures.calculatesLighting = false; - gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false; - gPhysicsPreviewProgram.mFeatures.hasGamma = false; - gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false; - gPhysicsPreviewProgram.mFeatures.hasLighting = false; - gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0; - gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true; - gPhysicsPreviewProgram.mShaderFiles.clear(); - gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER)); - gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER)); - gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gPhysicsPreviewProgram.createShader(NULL, NULL); - gPhysicsPreviewProgram.mFeatures.hasLighting = false; - } + } + + if (success) + { + gPhysicsPreviewProgram.mName = "Preview Physics Shader"; + gPhysicsPreviewProgram.mFeatures.calculatesLighting = false; + gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false; + gPhysicsPreviewProgram.mFeatures.hasGamma = false; + gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false; + gPhysicsPreviewProgram.mFeatures.hasLighting = false; + gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0; + gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true; + gPhysicsPreviewProgram.mShaderFiles.clear(); + gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER)); + gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER)); + gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gPhysicsPreviewProgram.createShader(NULL, NULL); + gPhysicsPreviewProgram.mFeatures.hasLighting = false; + } if (!success) { @@ -2501,234 +2501,234 @@ BOOL LLViewerShaderMgr::loadShadersObject() return FALSE; } - return TRUE; + return TRUE; } BOOL LLViewerShaderMgr::loadShadersAvatar() { LL_PROFILE_ZONE_SCOPED; #if 1 // DEPRECATED -- forward rendering is deprecated - BOOL success = TRUE; - - if (mShaderLevel[SHADER_AVATAR] == 0) - { - gAvatarProgram.unload(); - gAvatarEyeballProgram.unload(); - return TRUE; - } - - if (success) - { - gAvatarProgram.mName = "Avatar Shader"; - gAvatarProgram.mFeatures.hasSkinning = true; - gAvatarProgram.mFeatures.calculatesAtmospherics = true; - gAvatarProgram.mFeatures.calculatesLighting = true; - gAvatarProgram.mFeatures.hasGamma = true; - gAvatarProgram.mFeatures.hasAtmospherics = true; - gAvatarProgram.mFeatures.hasLighting = true; - gAvatarProgram.mFeatures.hasAlphaMask = true; - gAvatarProgram.mFeatures.disableTextureIndex = true; - gAvatarProgram.mShaderFiles.clear(); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER)); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER)); - gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarProgram.createShader(NULL, NULL); - - /// Keep track of avatar levels - if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR]) - { - mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; - } - } - - if (success) - { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; - gAvatarEyeballProgram.mFeatures.calculatesLighting = true; - gAvatarEyeballProgram.mFeatures.isSpecular = true; - gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasGamma = true; - gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasLighting = true; - gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; - gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; - gAvatarEyeballProgram.mShaderFiles.clear(); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER)); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER)); - gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL); - } - - if( !success ) - { - mShaderLevel[SHADER_AVATAR] = 0; - mMaxAvatarShaderLevel = 0; - return FALSE; - } + BOOL success = TRUE; + + if (mShaderLevel[SHADER_AVATAR] == 0) + { + gAvatarProgram.unload(); + gAvatarEyeballProgram.unload(); + return TRUE; + } + + if (success) + { + gAvatarProgram.mName = "Avatar Shader"; + gAvatarProgram.mFeatures.hasSkinning = true; + gAvatarProgram.mFeatures.calculatesAtmospherics = true; + gAvatarProgram.mFeatures.calculatesLighting = true; + gAvatarProgram.mFeatures.hasGamma = true; + gAvatarProgram.mFeatures.hasAtmospherics = true; + gAvatarProgram.mFeatures.hasLighting = true; + gAvatarProgram.mFeatures.hasAlphaMask = true; + gAvatarProgram.mFeatures.disableTextureIndex = true; + gAvatarProgram.mShaderFiles.clear(); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER)); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER)); + gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; + success = gAvatarProgram.createShader(NULL, NULL); + + /// Keep track of avatar levels + if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR]) + { + mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; + } + } + + if (success) + { + gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; + gAvatarEyeballProgram.mFeatures.calculatesLighting = true; + gAvatarEyeballProgram.mFeatures.isSpecular = true; + gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasGamma = true; + gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasLighting = true; + gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; + gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; + gAvatarEyeballProgram.mShaderFiles.clear(); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER)); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER)); + gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; + success = gAvatarEyeballProgram.createShader(NULL, NULL); + } + + if( !success ) + { + mShaderLevel[SHADER_AVATAR] = 0; + mMaxAvatarShaderLevel = 0; + return FALSE; + } #endif - return TRUE; + return TRUE; } BOOL LLViewerShaderMgr::loadShadersInterface() { LL_PROFILE_ZONE_SCOPED; - BOOL success = TRUE; - - if (success) - { - gHighlightProgram.mName = "Highlight Shader"; - gHighlightProgram.mShaderFiles.clear(); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER)); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); - gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + BOOL success = TRUE; + + if (success) + { + gHighlightProgram.mName = "Highlight Shader"; + gHighlightProgram.mShaderFiles.clear(); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER)); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); + gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram); - success = success && gHighlightProgram.createShader(NULL, NULL); - } - - if (success) - { - gHighlightNormalProgram.mName = "Highlight Normals Shader"; - gHighlightNormalProgram.mShaderFiles.clear(); - gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER)); - gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); - gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightNormalProgram.createShader(NULL, NULL); - } - - if (success) - { - gHighlightSpecularProgram.mName = "Highlight Spec Shader"; - gHighlightSpecularProgram.mShaderFiles.clear(); - gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER)); - gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); - gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightSpecularProgram.createShader(NULL, NULL); - } - - if (success) - { - gUIProgram.mName = "UI Shader"; - gUIProgram.mShaderFiles.clear(); - gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER)); - gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER)); - gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gUIProgram.createShader(NULL, NULL); - } - - if (success) - { - gPathfindingProgram.mName = "Pathfinding Shader"; - gPathfindingProgram.mShaderFiles.clear(); - gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER)); - gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER)); - gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gPathfindingProgram.createShader(NULL, NULL); - } - - if (success) - { - gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader"; - gPathfindingNoNormalsProgram.mShaderFiles.clear(); - gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER)); - gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER)); - gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gPathfindingNoNormalsProgram.createShader(NULL, NULL); - } - - if (success) - { - gGlowCombineProgram.mName = "Glow Combine Shader"; - gGlowCombineProgram.mShaderFiles.clear(); - gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER)); - gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER)); - gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gGlowCombineProgram.createShader(NULL, NULL); - if (success) - { - gGlowCombineProgram.bind(); - gGlowCombineProgram.uniform1i(sGlowMap, 0); - gGlowCombineProgram.uniform1i(sScreenMap, 1); - gGlowCombineProgram.unbind(); - } - } - - if (success) - { - gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; - gGlowCombineFXAAProgram.mShaderFiles.clear(); - gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); - gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); - gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gGlowCombineFXAAProgram.createShader(NULL, NULL); - if (success) - { - gGlowCombineFXAAProgram.bind(); - gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0); - gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1); - gGlowCombineFXAAProgram.unbind(); - } - } + success = success && gHighlightProgram.createShader(NULL, NULL); + } + + if (success) + { + gHighlightNormalProgram.mName = "Highlight Normals Shader"; + gHighlightNormalProgram.mShaderFiles.clear(); + gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER)); + gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); + gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gHighlightNormalProgram.createShader(NULL, NULL); + } + + if (success) + { + gHighlightSpecularProgram.mName = "Highlight Spec Shader"; + gHighlightSpecularProgram.mShaderFiles.clear(); + gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER)); + gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); + gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gHighlightSpecularProgram.createShader(NULL, NULL); + } + + if (success) + { + gUIProgram.mName = "UI Shader"; + gUIProgram.mShaderFiles.clear(); + gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER)); + gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER)); + gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gUIProgram.createShader(NULL, NULL); + } + + if (success) + { + gPathfindingProgram.mName = "Pathfinding Shader"; + gPathfindingProgram.mShaderFiles.clear(); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER)); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER)); + gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gPathfindingProgram.createShader(NULL, NULL); + } + + if (success) + { + gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader"; + gPathfindingNoNormalsProgram.mShaderFiles.clear(); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER)); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER)); + gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gPathfindingNoNormalsProgram.createShader(NULL, NULL); + } + + if (success) + { + gGlowCombineProgram.mName = "Glow Combine Shader"; + gGlowCombineProgram.mShaderFiles.clear(); + gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER)); + gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER)); + gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gGlowCombineProgram.createShader(NULL, NULL); + if (success) + { + gGlowCombineProgram.bind(); + gGlowCombineProgram.uniform1i(sGlowMap, 0); + gGlowCombineProgram.uniform1i(sScreenMap, 1); + gGlowCombineProgram.unbind(); + } + } + + if (success) + { + gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; + gGlowCombineFXAAProgram.mShaderFiles.clear(); + gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); + gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); + gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gGlowCombineFXAAProgram.createShader(NULL, NULL); + if (success) + { + gGlowCombineFXAAProgram.bind(); + gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0); + gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1); + gGlowCombineFXAAProgram.unbind(); + } + } #ifdef LL_WINDOWS - if (success) - { - gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; - gTwoTextureCompareProgram.mShaderFiles.clear(); - gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER)); - gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER)); - gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gTwoTextureCompareProgram.createShader(NULL, NULL); - if (success) - { - gTwoTextureCompareProgram.bind(); - gTwoTextureCompareProgram.uniform1i(sTex0, 0); - gTwoTextureCompareProgram.uniform1i(sTex1, 1); - gTwoTextureCompareProgram.uniform1i(sDitherTex, 2); - } - } - - if (success) - { - gOneTextureFilterProgram.mName = "One Texture Filter Shader"; - gOneTextureFilterProgram.mShaderFiles.clear(); - gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER)); - gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER)); - gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOneTextureFilterProgram.createShader(NULL, NULL); - if (success) - { - gOneTextureFilterProgram.bind(); - gOneTextureFilterProgram.uniform1i(sTex0, 0); - } - } + if (success) + { + gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; + gTwoTextureCompareProgram.mShaderFiles.clear(); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER)); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER)); + gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gTwoTextureCompareProgram.createShader(NULL, NULL); + if (success) + { + gTwoTextureCompareProgram.bind(); + gTwoTextureCompareProgram.uniform1i(sTex0, 0); + gTwoTextureCompareProgram.uniform1i(sTex1, 1); + gTwoTextureCompareProgram.uniform1i(sDitherTex, 2); + } + } + + if (success) + { + gOneTextureFilterProgram.mName = "One Texture Filter Shader"; + gOneTextureFilterProgram.mShaderFiles.clear(); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER)); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER)); + gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOneTextureFilterProgram.createShader(NULL, NULL); + if (success) + { + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1i(sTex0, 0); + } + } #endif - if (success) - { - gSolidColorProgram.mName = "Solid Color Shader"; - gSolidColorProgram.mShaderFiles.clear(); - gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER)); - gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER)); - gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gSolidColorProgram.createShader(NULL, NULL); - if (success) - { - gSolidColorProgram.bind(); - gSolidColorProgram.uniform1i(sTex0, 0); - gSolidColorProgram.unbind(); - } - } - - if (success) - { - gOcclusionProgram.mName = "Occlusion Shader"; - gOcclusionProgram.mShaderFiles.clear(); - gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER)); - gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER)); - gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + if (success) + { + gSolidColorProgram.mName = "Solid Color Shader"; + gSolidColorProgram.mShaderFiles.clear(); + gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER)); + gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER)); + gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gSolidColorProgram.createShader(NULL, NULL); + if (success) + { + gSolidColorProgram.bind(); + gSolidColorProgram.uniform1i(sTex0, 0); + gSolidColorProgram.unbind(); + } + } + + if (success) + { + gOcclusionProgram.mName = "Occlusion Shader"; + gOcclusionProgram.mShaderFiles.clear(); + gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER)); + gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER)); + gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram; - success = gOcclusionProgram.createShader(NULL, NULL); - } + success = gOcclusionProgram.createShader(NULL, NULL); + } if (success) { @@ -2741,30 +2741,30 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = gSkinnedOcclusionProgram.createShader(NULL, NULL); } - if (success) - { - gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; - gOcclusionCubeProgram.mShaderFiles.clear(); - gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER)); - gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER)); - gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOcclusionCubeProgram.createShader(NULL, NULL); - } - - if (success) - { - gDebugProgram.mName = "Debug Shader"; - gDebugProgram.mShaderFiles.clear(); - gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER)); - gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER)); + if (success) + { + gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; + gOcclusionCubeProgram.mShaderFiles.clear(); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER)); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER)); + gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOcclusionCubeProgram.createShader(NULL, NULL); + } + + if (success) + { + gDebugProgram.mName = "Debug Shader"; + gDebugProgram.mShaderFiles.clear(); + gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER)); + gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER)); gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram; - gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram); - success = success && gDebugProgram.createShader(NULL, NULL); - } + success = success && gDebugProgram.createShader(NULL, NULL); + } - if (success) - { + if (success) + { for (S32 variant = 0; variant < NORMAL_DEBUG_SHADER_COUNT; ++variant) { LLGLSLShader& shader = gNormalDebugProgram[variant]; @@ -2788,27 +2788,27 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = make_rigged_variant(shader, skinned_shader); success = success && shader.createShader(NULL, NULL); } - } - - if (success) - { - gClipProgram.mName = "Clip Shader"; - gClipProgram.mShaderFiles.clear(); - gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER)); - gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER)); - gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gClipProgram.createShader(NULL, NULL); - } - - if (success) - { - gBenchmarkProgram.mName = "Benchmark Shader"; - gBenchmarkProgram.mShaderFiles.clear(); - gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER)); - gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER)); - gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gBenchmarkProgram.createShader(NULL, NULL); - } + } + + if (success) + { + gClipProgram.mName = "Clip Shader"; + gClipProgram.mShaderFiles.clear(); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER)); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER)); + gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gClipProgram.createShader(NULL, NULL); + } + + if (success) + { + gBenchmarkProgram.mName = "Benchmark Shader"; + gBenchmarkProgram.mShaderFiles.clear(); + gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER)); + gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER)); + gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gBenchmarkProgram.createShader(NULL, NULL); + } if (success) { @@ -2847,16 +2847,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; success = gCopyDepthProgram.createShader(NULL, NULL); } - - if (success) - { - gAlphaMaskProgram.mName = "Alpha Mask Shader"; - gAlphaMaskProgram.mShaderFiles.clear(); - gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER)); - gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER)); - gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gAlphaMaskProgram.createShader(NULL, NULL); - } + + if (success) + { + gAlphaMaskProgram.mName = "Alpha Mask Shader"; + gAlphaMaskProgram.mShaderFiles.clear(); + gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER)); + gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER)); + gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gAlphaMaskProgram.createShader(NULL, NULL); + } if (success) { @@ -2896,7 +2896,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "32"); success = gRadianceGenProgram.createShader(NULL, NULL); } - + if (success && gGLManager.mHasCubeMapArray) { gHeroRadianceGenProgram.mName = "Hero Radiance Gen Shader"; @@ -2919,19 +2919,19 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = gIrradianceGenProgram.createShader(NULL, NULL); } - if( !success ) - { - mShaderLevel[SHADER_INTERFACE] = 0; - return FALSE; - } - - return TRUE; + if( !success ) + { + mShaderLevel[SHADER_INTERFACE] = 0; + return FALSE; + } + + return TRUE; } std::string LLViewerShaderMgr::getShaderDirPrefix(void) { - return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); + return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); } void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) @@ -2941,11 +2941,11 @@ void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const { - return mShaderList.begin(); + return mShaderList.begin(); } LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const { - return mShaderList.end(); + return mShaderList.end(); } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index c51f583ebc..dbac352b92 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -1,25 +1,25 @@ -/** +/** * @file llviewershadermgr.h * @brief Viewer Shader Manager * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,251 +35,251 @@ class LLViewerShaderMgr: public LLShaderMgr { public: - static BOOL sInitialized; - static bool sSkipReload; + static BOOL sInitialized; + static bool sSkipReload; - LLViewerShaderMgr(); - /* virtual */ ~LLViewerShaderMgr(); + LLViewerShaderMgr(); + /* virtual */ ~LLViewerShaderMgr(); // Add shaders to mShaderList for later uniform propagation // Will assert on redundant shader entries in debug builds void finalizeShaderList(); - // singleton pattern implementation - static LLViewerShaderMgr * instance(); - static void releaseInstance(); + // singleton pattern implementation + static LLViewerShaderMgr * instance(); + static void releaseInstance(); - void initAttribsAndUniforms(void); - void setShaders(); - void unloadShaders(); + void initAttribsAndUniforms(void); + void setShaders(); + void unloadShaders(); S32 getShaderLevel(S32 type); // loadBasicShaders in case of a failure returns // name of a file error happened at, otherwise // returns an empty string std::string loadBasicShaders(); - BOOL loadShadersEffects(); - BOOL loadShadersDeferred(); - BOOL loadShadersObject(); - BOOL loadShadersAvatar(); - BOOL loadShadersWater(); - BOOL loadShadersInterface(); - - std::vector mShaderLevel; - S32 mMaxAvatarShaderLevel; - - enum EShaderClass - { - SHADER_LIGHTING, - SHADER_OBJECT, - SHADER_AVATAR, - SHADER_ENVIRONMENT, - SHADER_INTERFACE, - SHADER_EFFECT, - SHADER_WINDLIGHT, - SHADER_WATER, - SHADER_DEFERRED, - SHADER_COUNT - }; - - // simple model of forward iterator - // http://www.sgi.com/tech/stl/ForwardIterator.html - class shader_iter - { - private: - friend bool operator == (shader_iter const & a, shader_iter const & b); - friend bool operator != (shader_iter const & a, shader_iter const & b); - - typedef std::vector::const_iterator base_iter_t; - public: - shader_iter() - { - } - - shader_iter(base_iter_t iter) : mIter(iter) - { - } - - LLGLSLShader & operator * () const - { - return **mIter; - } - - LLGLSLShader * operator -> () const - { - return *mIter; - } - - shader_iter & operator++ () - { - ++mIter; - return *this; - } - - shader_iter operator++ (int) - { - return mIter++; - } - - private: - base_iter_t mIter; - }; - - shader_iter beginShaders() const; - shader_iter endShaders() const; - - /* virtual */ std::string getShaderDirPrefix(void); - - /* virtual */ void updateShaderUniforms(LLGLSLShader * shader); + BOOL loadShadersEffects(); + BOOL loadShadersDeferred(); + BOOL loadShadersObject(); + BOOL loadShadersAvatar(); + BOOL loadShadersWater(); + BOOL loadShadersInterface(); + + std::vector mShaderLevel; + S32 mMaxAvatarShaderLevel; + + enum EShaderClass + { + SHADER_LIGHTING, + SHADER_OBJECT, + SHADER_AVATAR, + SHADER_ENVIRONMENT, + SHADER_INTERFACE, + SHADER_EFFECT, + SHADER_WINDLIGHT, + SHADER_WATER, + SHADER_DEFERRED, + SHADER_COUNT + }; + + // simple model of forward iterator + // http://www.sgi.com/tech/stl/ForwardIterator.html + class shader_iter + { + private: + friend bool operator == (shader_iter const & a, shader_iter const & b); + friend bool operator != (shader_iter const & a, shader_iter const & b); + + typedef std::vector::const_iterator base_iter_t; + public: + shader_iter() + { + } + + shader_iter(base_iter_t iter) : mIter(iter) + { + } + + LLGLSLShader & operator * () const + { + return **mIter; + } + + LLGLSLShader * operator -> () const + { + return *mIter; + } + + shader_iter & operator++ () + { + ++mIter; + return *this; + } + + shader_iter operator++ (int) + { + return mIter++; + } + + private: + base_iter_t mIter; + }; + + shader_iter beginShaders() const; + shader_iter endShaders() const; + + /* virtual */ std::string getShaderDirPrefix(void); + + /* virtual */ void updateShaderUniforms(LLGLSLShader * shader); private: - // the list of shaders we need to propagate parameters to. - std::vector mShaderList; + // the list of shaders we need to propagate parameters to. + std::vector mShaderList; }; //LLViewerShaderMgr inline bool operator == (LLViewerShaderMgr::shader_iter const & a, LLViewerShaderMgr::shader_iter const & b) { - return a.mIter == b.mIter; + return a.mIter == b.mIter; } inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShaderMgr::shader_iter const & b) { - return a.mIter != b.mIter; + return a.mIter != b.mIter; } -extern LLVector4 gShinyOrigin; +extern LLVector4 gShinyOrigin; //utility shaders -extern LLGLSLShader gOcclusionProgram; -extern LLGLSLShader gOcclusionCubeProgram; -extern LLGLSLShader gGlowCombineProgram; -extern LLGLSLShader gReflectionMipProgram; +extern LLGLSLShader gOcclusionProgram; +extern LLGLSLShader gOcclusionCubeProgram; +extern LLGLSLShader gGlowCombineProgram; +extern LLGLSLShader gReflectionMipProgram; extern LLGLSLShader gGaussianProgram; extern LLGLSLShader gRadianceGenProgram; extern LLGLSLShader gHeroRadianceGenProgram; extern LLGLSLShader gIrradianceGenProgram; -extern LLGLSLShader gGlowCombineFXAAProgram; -extern LLGLSLShader gDebugProgram; +extern LLGLSLShader gGlowCombineFXAAProgram; +extern LLGLSLShader gDebugProgram; enum NormalDebugShaderVariant : S32 { NORMAL_DEBUG_SHADER_DEFAULT, NORMAL_DEBUG_SHADER_WITH_TANGENTS, NORMAL_DEBUG_SHADER_COUNT }; -extern LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; -extern LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; -extern LLGLSLShader gClipProgram; -extern LLGLSLShader gBenchmarkProgram; +extern LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +extern LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +extern LLGLSLShader gClipProgram; +extern LLGLSLShader gBenchmarkProgram; extern LLGLSLShader gReflectionProbeDisplayProgram; extern LLGLSLShader gCopyProgram; extern LLGLSLShader gCopyDepthProgram; //output tex0[tc0] - tex1[tc1] -extern LLGLSLShader gTwoTextureCompareProgram; +extern LLGLSLShader gTwoTextureCompareProgram; //discard some fragments based on user-set color tolerance -extern LLGLSLShader gOneTextureFilterProgram; - +extern LLGLSLShader gOneTextureFilterProgram; + //object shaders -extern LLGLSLShader gObjectPreviewProgram; +extern LLGLSLShader gObjectPreviewProgram; extern LLGLSLShader gPhysicsPreviewProgram; -extern LLGLSLShader gObjectBumpProgram; +extern LLGLSLShader gObjectBumpProgram; extern LLGLSLShader gSkinnedObjectBumpProgram; -extern LLGLSLShader gObjectAlphaMaskNoColorProgram; +extern LLGLSLShader gObjectAlphaMaskNoColorProgram; //environment shaders -extern LLGLSLShader gWaterProgram; -extern LLGLSLShader gWaterEdgeProgram; -extern LLGLSLShader gUnderWaterProgram; -extern LLGLSLShader gGlowProgram; -extern LLGLSLShader gGlowExtractProgram; +extern LLGLSLShader gWaterProgram; +extern LLGLSLShader gWaterEdgeProgram; +extern LLGLSLShader gUnderWaterProgram; +extern LLGLSLShader gGlowProgram; +extern LLGLSLShader gGlowExtractProgram; //interface shaders -extern LLGLSLShader gHighlightProgram; -extern LLGLSLShader gHighlightNormalProgram; -extern LLGLSLShader gHighlightSpecularProgram; +extern LLGLSLShader gHighlightProgram; +extern LLGLSLShader gHighlightNormalProgram; +extern LLGLSLShader gHighlightSpecularProgram; -extern LLGLSLShader gDeferredHighlightProgram; +extern LLGLSLShader gDeferredHighlightProgram; -extern LLGLSLShader gPathfindingProgram; -extern LLGLSLShader gPathfindingNoNormalsProgram; +extern LLGLSLShader gPathfindingProgram; +extern LLGLSLShader gPathfindingNoNormalsProgram; // avatar shader handles -extern LLGLSLShader gAvatarProgram; -extern LLGLSLShader gAvatarEyeballProgram; -extern LLGLSLShader gImpostorProgram; +extern LLGLSLShader gAvatarProgram; +extern LLGLSLShader gAvatarEyeballProgram; +extern LLGLSLShader gImpostorProgram; // Post Process Shaders extern LLGLSLShader gPostScreenSpaceReflectionProgram; // Deferred rendering shaders -extern LLGLSLShader gDeferredImpostorProgram; -extern LLGLSLShader gDeferredDiffuseProgram; -extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; -extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; -extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; -extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; -extern LLGLSLShader gDeferredBumpProgram; -extern LLGLSLShader gDeferredTerrainProgram; -extern LLGLSLShader gDeferredTreeProgram; -extern LLGLSLShader gDeferredTreeShadowProgram; -extern LLGLSLShader gDeferredLightProgram; -extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT]; -extern LLGLSLShader gDeferredSpotLightProgram; -extern LLGLSLShader gDeferredMultiSpotLightProgram; -extern LLGLSLShader gDeferredSunProgram; +extern LLGLSLShader gDeferredImpostorProgram; +extern LLGLSLShader gDeferredDiffuseProgram; +extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; +extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; +extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; +extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; +extern LLGLSLShader gDeferredBumpProgram; +extern LLGLSLShader gDeferredTerrainProgram; +extern LLGLSLShader gDeferredTreeProgram; +extern LLGLSLShader gDeferredTreeShadowProgram; +extern LLGLSLShader gDeferredLightProgram; +extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT]; +extern LLGLSLShader gDeferredSpotLightProgram; +extern LLGLSLShader gDeferredMultiSpotLightProgram; +extern LLGLSLShader gDeferredSunProgram; extern LLGLSLShader gHazeProgram; extern LLGLSLShader gHazeWaterProgram; -extern LLGLSLShader gDeferredBlurLightProgram; -extern LLGLSLShader gDeferredAvatarProgram; -extern LLGLSLShader gDeferredSoftenProgram; -extern LLGLSLShader gDeferredShadowProgram; -extern LLGLSLShader gDeferredShadowCubeProgram; -extern LLGLSLShader gDeferredShadowAlphaMaskProgram; +extern LLGLSLShader gDeferredBlurLightProgram; +extern LLGLSLShader gDeferredAvatarProgram; +extern LLGLSLShader gDeferredSoftenProgram; +extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredShadowCubeProgram; +extern LLGLSLShader gDeferredShadowAlphaMaskProgram; extern LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram; extern LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram; -extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; -extern LLGLSLShader gDeferredPostProgram; -extern LLGLSLShader gDeferredCoFProgram; -extern LLGLSLShader gDeferredDoFCombineProgram; -extern LLGLSLShader gFXAAProgram; -extern LLGLSLShader gDeferredPostNoDoFProgram; -extern LLGLSLShader gDeferredPostGammaCorrectProgram; +extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; +extern LLGLSLShader gDeferredPostProgram; +extern LLGLSLShader gDeferredCoFProgram; +extern LLGLSLShader gDeferredDoFCombineProgram; +extern LLGLSLShader gFXAAProgram; +extern LLGLSLShader gDeferredPostNoDoFProgram; +extern LLGLSLShader gDeferredPostGammaCorrectProgram; extern LLGLSLShader gNoPostGammaCorrectProgram; extern LLGLSLShader gLegacyPostGammaCorrectProgram; -extern LLGLSLShader gExposureProgram; -extern LLGLSLShader gExposureProgramNoFade; -extern LLGLSLShader gLuminanceProgram; -extern LLGLSLShader gDeferredAvatarShadowProgram; -extern LLGLSLShader gDeferredAvatarAlphaShadowProgram; -extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; -extern LLGLSLShader gDeferredAlphaProgram; -extern LLGLSLShader gHUDAlphaProgram; -extern LLGLSLShader gDeferredAlphaImpostorProgram; -extern LLGLSLShader gDeferredFullbrightProgram; -extern LLGLSLShader gHUDFullbrightProgram; -extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram; -extern LLGLSLShader gHUDFullbrightAlphaMaskProgram; -extern LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram; -extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram; -extern LLGLSLShader gDeferredEmissiveProgram; -extern LLGLSLShader gDeferredAvatarEyesProgram; -extern LLGLSLShader gDeferredAvatarAlphaProgram; +extern LLGLSLShader gExposureProgram; +extern LLGLSLShader gExposureProgramNoFade; +extern LLGLSLShader gLuminanceProgram; +extern LLGLSLShader gDeferredAvatarShadowProgram; +extern LLGLSLShader gDeferredAvatarAlphaShadowProgram; +extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; +extern LLGLSLShader gDeferredAlphaProgram; +extern LLGLSLShader gHUDAlphaProgram; +extern LLGLSLShader gDeferredAlphaImpostorProgram; +extern LLGLSLShader gDeferredFullbrightProgram; +extern LLGLSLShader gHUDFullbrightProgram; +extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram; +extern LLGLSLShader gHUDFullbrightAlphaMaskProgram; +extern LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram; +extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram; +extern LLGLSLShader gDeferredEmissiveProgram; +extern LLGLSLShader gDeferredAvatarEyesProgram; +extern LLGLSLShader gDeferredAvatarAlphaProgram; extern LLGLSLShader gEnvironmentMapProgram; -extern LLGLSLShader gDeferredWLSkyProgram; -extern LLGLSLShader gDeferredWLCloudProgram; -extern LLGLSLShader gDeferredWLSunProgram; -extern LLGLSLShader gDeferredWLMoonProgram; -extern LLGLSLShader gDeferredStarProgram; -extern LLGLSLShader gDeferredFullbrightShinyProgram; +extern LLGLSLShader gDeferredWLSkyProgram; +extern LLGLSLShader gDeferredWLCloudProgram; +extern LLGLSLShader gDeferredWLSunProgram; +extern LLGLSLShader gDeferredWLMoonProgram; +extern LLGLSLShader gDeferredStarProgram; +extern LLGLSLShader gDeferredFullbrightShinyProgram; extern LLGLSLShader gHUDFullbrightShinyProgram; -extern LLGLSLShader gNormalMapGenProgram; +extern LLGLSLShader gNormalMapGenProgram; extern LLGLSLShader gDeferredGenBrdfLutProgram; -extern LLGLSLShader gDeferredBufferVisualProgram; +extern LLGLSLShader gDeferredBufferVisualProgram; // Deferred materials shaders -extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gHUDPBROpaqueProgram; extern LLGLSLShader gPBRGlowProgram; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 6b496cf658..9aee1c0caf 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewertexture.cpp * @brief Object which handles a received image (and associated texture(s)) * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -115,24 +115,24 @@ const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_S //---------------------------------------------------------------------------------------------- LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb, - S32 discard_level, - BOOL need_imageraw, // Needs image raw for the callback - void* userdata, - LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, - LLViewerFetchedTexture* target, - BOOL pause) - : mCallback(cb), - mLastUsedDiscard(MAX_DISCARD_LEVEL+1), - mDesiredDiscard(discard_level), - mNeedsImageRaw(need_imageraw), - mUserData(userdata), - mSourceCallbackList(src_callback_list), - mPaused(pause) -{ - if(mSourceCallbackList) - { + S32 discard_level, + BOOL need_imageraw, // Needs image raw for the callback + void* userdata, + LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, + LLViewerFetchedTexture* target, + BOOL pause) + : mCallback(cb), + mLastUsedDiscard(MAX_DISCARD_LEVEL+1), + mDesiredDiscard(discard_level), + mNeedsImageRaw(need_imageraw), + mUserData(userdata), + mSourceCallbackList(src_callback_list), + mPaused(pause) +{ + if(mSourceCallbackList) + { mSourceCallbackList->insert(LLTextureKey(target->getID(), (ETexListType)target->getTextureListType())); - } + } } LLLoadedCallbackEntry::~LLLoadedCallbackEntry() @@ -141,34 +141,34 @@ LLLoadedCallbackEntry::~LLLoadedCallbackEntry() void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex) { - if(mSourceCallbackList) - { - mSourceCallbackList->erase(LLTextureKey(tex->getID(), (ETexListType)tex->getTextureListType())); - } + if(mSourceCallbackList) + { + mSourceCallbackList->erase(LLTextureKey(tex->getID(), (ETexListType)tex->getTextureListType())); + } } -//static +//static void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) { - //clear texture callbacks. - if(callback_list && !callback_list->empty()) - { - for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin(); - iter != callback_list->end(); ++iter) - { - LLViewerFetchedTexture* tex = gTextureList.findImage(*iter); - if(tex) - { - tex->deleteCallbackEntry(callback_list); - } - } - callback_list->clear(); - } + //clear texture callbacks. + if(callback_list && !callback_list->empty()) + { + for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin(); + iter != callback_list->end(); ++iter) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(*iter); + if(tex) + { + tex->deleteCallbackEntry(callback_list); + } + } + callback_list->clear(); + } } LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image) { - return new LLViewerMediaTexture(media_id, usemipmaps, gl_image); + return new LLViewerMediaTexture(media_id, usemipmaps, gl_image); } void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector &output) @@ -209,78 +209,78 @@ LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) { - return LLViewerMediaTexture::findMediaTexture(media_id); + return LLViewerMediaTexture::findMediaTexture(media_id); } -LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) +LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) { - LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id); - if(!tex) - { - tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image); - } + LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id); + if(!tex) + { + tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image); + } - tex->initVirtualSize(); + tex->initVirtualSize(); - return tex; + return tex; } LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error) { - if(!tex) - { - return NULL; - } + if(!tex) + { + return NULL; + } - S8 type = tex->getType(); - if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) - { - return static_cast(tex); - } + S8 type = tex->getType(); + if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) + { + return static_cast(tex); + } - if(report_error) - { - LL_ERRS() << "not a fetched texture type: " << type << LL_ENDL; - } + if(report_error) + { + LL_ERRS() << "not a fetched texture type: " << type << LL_ENDL; + } - return NULL; + return NULL; } LLPointer LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex) { - LLPointer tex = new LLViewerTexture(usemipmaps); - if(generate_gl_tex) - { - tex->generateGLTexture(); - tex->setCategory(LLGLTexture::LOCAL); - } - return tex; + LLPointer tex = new LLViewerTexture(usemipmaps); + if(generate_gl_tex) + { + tex->generateGLTexture(); + tex->setCategory(LLGLTexture::LOCAL); + } + return tex; } -LLPointer LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex) +LLPointer LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex) { - LLPointer tex = new LLViewerTexture(id, usemipmaps); - if(generate_gl_tex) - { - tex->generateGLTexture(); - tex->setCategory(LLGLTexture::LOCAL); - } - return tex; + LLPointer tex = new LLViewerTexture(id, usemipmaps); + if(generate_gl_tex) + { + tex->generateGLTexture(); + tex->setCategory(LLGLTexture::LOCAL); + } + return tex; } -LLPointer LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) +LLPointer LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) { - LLPointer tex = new LLViewerTexture(raw, usemipmaps); - tex->setCategory(LLGLTexture::LOCAL); - return tex; + LLPointer tex = new LLViewerTexture(raw, usemipmaps); + tex->setCategory(LLGLTexture::LOCAL); + return tex; } -LLPointer LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) +LLPointer LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) { - LLPointer tex = new LLViewerTexture(width, height, components, usemipmaps); - if(generate_gl_tex) - { - tex->generateGLTexture(); - tex->setCategory(LLGLTexture::LOCAL); - } - return tex; + LLPointer tex = new LLViewerTexture(width, height, components, usemipmaps); + if(generate_gl_tex) + { + tex->generateGLTexture(); + tex->setCategory(LLGLTexture::LOCAL); + } + return tex; } LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps) @@ -291,170 +291,170 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageR } LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( - const LLUUID &image_id, - FTType f_type, - BOOL usemipmaps, - LLViewerTexture::EBoostLevel boost_priority, - S8 texture_type, - LLGLint internal_format, - LLGLenum primary_format, - LLHost request_from_host) -{ - return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host); -} - + const LLUUID &image_id, + FTType f_type, + BOOL usemipmaps, + LLViewerTexture::EBoostLevel boost_priority, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host); +} + LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( - const std::string& filename, - FTType f_type, - BOOL usemipmaps, - LLViewerTexture::EBoostLevel boost_priority, - S8 texture_type, - LLGLint internal_format, - LLGLenum primary_format, - const LLUUID& force_id) + const std::string& filename, + FTType f_type, + BOOL usemipmaps, + LLViewerTexture::EBoostLevel boost_priority, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id) { - return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id); + return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id); } -//static +//static LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, - FTType f_type, - BOOL usemipmaps, - LLViewerTexture::EBoostLevel boost_priority, - S8 texture_type, - LLGLint internal_format, - LLGLenum primary_format, - const LLUUID& force_id - ) + FTType f_type, + BOOL usemipmaps, + LLViewerTexture::EBoostLevel boost_priority, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id + ) { - return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id); + return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id); } -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) { - return gTextureList.getImageFromHost(image_id, f_type, host); + return gTextureList.getImageFromHost(image_id, f_type, host); } // Create a bridge to the viewer texture manager. class LLViewerTextureManagerBridge : public LLTextureManagerBridge { - /*virtual*/ LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) - { - return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex); - } + /*virtual*/ LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex); + } - /*virtual*/ LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) - { - return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex); - } + /*virtual*/ LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex); + } - /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id) - { - return LLViewerTextureManager::getFetchedTexture(image_id); - } + /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id) + { + return LLViewerTextureManager::getFetchedTexture(image_id); + } }; void LLViewerTextureManager::init() { - { - LLPointer raw = new LLImageRaw(1,1,3); - raw->clear(0x77, 0x77, 0x77, 0xFF); - LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE); - } + { + LLPointer raw = new LLImageRaw(1,1,3); + raw->clear(0x77, 0x77, 0x77, 0xFF); + LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE); + } + + const S32 dim = 128; + LLPointer image_raw = new LLImageRaw(dim,dim,3); + U8* data = image_raw->getData(); - const S32 dim = 128; - LLPointer image_raw = new LLImageRaw(dim,dim,3); - U8* data = image_raw->getData(); - - memset(data, 0, dim * dim * 3); - LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); + memset(data, 0, dim * dim * 3); + LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); #if 1 - LLPointer imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT); - LLViewerFetchedTexture::sDefaultImagep = imagep; - - for (S32 i = 0; i imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT); + LLViewerFetchedTexture::sDefaultImagep = imagep; + + for (S32 i = 0; i=(dim-border) || j>=(dim-border)) - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0xff; - } - else + const S32 border = 2; + if (i=(dim-border) || j>=(dim-border)) + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0xff; + } + else #endif - { - *data++ = 0x7f; - *data++ = 0x7f; - *data++ = 0x7f; - } - } - } - imagep->createGLTexture(0, image_raw); - //cache the raw image - imagep->setCachedRawImage(0, image_raw); - image_raw = NULL; + { + *data++ = 0x7f; + *data++ = 0x7f; + *data++ = 0x7f; + } + } + } + imagep->createGLTexture(0, image_raw); + //cache the raw image + imagep->setCachedRawImage(0, image_raw); + image_raw = NULL; #else - LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); + LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); #endif - LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); - LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER); - - image_raw = new LLImageRaw(32,32,3); - data = image_raw->getData(); - - for (S32 i = 0; i < (32*32*3); i+=3) - { - S32 x = (i % (32*3)) / (3*16); - S32 y = i / (32*3*16); - U8 color = ((x + y) % 2) * 255; - data[i] = color; - data[i+1] = color; - data[i+2] = color; - } - - LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); - - LLViewerTexture::initClass(); - - // Create a texture manager bridge. - gTextureManagerBridgep = new LLViewerTextureManagerBridge; - - if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) - { - sTesterp = new LLTexturePipelineTester(); - if (!sTesterp->isValid()) - { - delete sTesterp; - sTesterp = NULL; - } - } + LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); + LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER); + + image_raw = new LLImageRaw(32,32,3); + data = image_raw->getData(); + + for (S32 i = 0; i < (32*32*3); i+=3) + { + S32 x = (i % (32*3)) / (3*16); + S32 y = i / (32*3*16); + U8 color = ((x + y) % 2) * 255; + data[i] = color; + data[i+1] = color; + data[i+2] = color; + } + + LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); + + LLViewerTexture::initClass(); + + // Create a texture manager bridge. + gTextureManagerBridgep = new LLViewerTextureManagerBridge; + + if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) + { + sTesterp = new LLTexturePipelineTester(); + if (!sTesterp->isValid()) + { + delete sTesterp; + sTesterp = NULL; + } + } } void LLViewerTextureManager::cleanup() { - stop_glerror(); + stop_glerror(); - delete gTextureManagerBridgep; - LLImageGL::sDefaultGLTexture = NULL; - LLViewerTexture::sNullImagep = NULL; - LLViewerTexture::sBlackImagep = NULL; - LLViewerTexture::sCheckerBoardImagep = NULL; - LLViewerFetchedTexture::sDefaultImagep = NULL; - LLViewerFetchedTexture::sSmokeImagep = NULL; - LLViewerFetchedTexture::sMissingAssetImagep = NULL; - LLTexUnit::sWhiteTexture = 0; - LLViewerFetchedTexture::sWhiteImagep = NULL; - - LLViewerFetchedTexture::sFlatNormalImagep = NULL; - LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL; + delete gTextureManagerBridgep; + LLImageGL::sDefaultGLTexture = NULL; + LLViewerTexture::sNullImagep = NULL; + LLViewerTexture::sBlackImagep = NULL; + LLViewerTexture::sCheckerBoardImagep = NULL; + LLViewerFetchedTexture::sDefaultImagep = NULL; + LLViewerFetchedTexture::sSmokeImagep = NULL; + LLViewerFetchedTexture::sMissingAssetImagep = NULL; + LLTexUnit::sWhiteTexture = 0; + LLViewerFetchedTexture::sWhiteImagep = NULL; - LLViewerMediaTexture::cleanUpClass(); + LLViewerFetchedTexture::sFlatNormalImagep = NULL; + LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL; + + LLViewerMediaTexture::cleanUpClass(); } //---------------------------------------------------------------------------------------------- @@ -464,7 +464,7 @@ void LLViewerTextureManager::cleanup() // static void LLViewerTexture::initClass() { - LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture(); + LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture(); } // tuning params @@ -473,7 +473,7 @@ const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f; F32 texmem_lower_bound_scale = 0.85f; F32 texmem_middle_bound_scale = 0.925f; -//static +//static bool LLViewerTexture::isMemoryForTextureLow() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -498,7 +498,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p static S32Megabytes gpu_res = S32Megabytes(S32_MAX); static S32Megabytes physical_res = S32Megabytes(S32_MAX); - + if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second. { gpu = gpu_res; @@ -509,7 +509,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p { gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes(); - + //check main memory, only works for windows and macos. LLMemory::updateMemoryInfo(); physical_res = LLMemory::getAvailableMemKB(); @@ -523,25 +523,25 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p void LLViewerTexture::updateClass() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - sCurrentTime = gFrameTimeSeconds; + sCurrentTime = gFrameTimeSeconds; - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->update(); - } + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); + if (tester) + { + tester->update(); + } - LLViewerMediaTexture::updateClass(); + LLViewerMediaTexture::updateClass(); static LLCachedControl max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0); - F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0; - F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 512.0; + F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0; + F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 512.0; - // get an estimate of how much video memory we're using + // get an estimate of how much video memory we're using // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number - F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); - + F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); + F32 budget = max_vram_budget == 0 ? gGLManager.mVRAM : max_vram_budget; // try to leave half a GB for everyone else, but keep at least 768MB for ourselves @@ -563,75 +563,75 @@ void LLViewerTexture::updateClass() const U32 LLViewerTexture::sCurrentFileVersion = 1; LLViewerTexture::LLViewerTexture(BOOL usemipmaps) : - LLGLTexture(usemipmaps) + LLGLTexture(usemipmaps) { - init(true); + init(true); - mID.generate(); - sImageCount++; + mID.generate(); + sImageCount++; } LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) : - LLGLTexture(usemipmaps), - mID(id) + LLGLTexture(usemipmaps), + mID(id) { - init(true); - - sImageCount++; + init(true); + + sImageCount++; } LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) : - LLGLTexture(width, height, components, usemipmaps) + LLGLTexture(width, height, components, usemipmaps) { - init(true); + init(true); - mID.generate(); - sImageCount++; + mID.generate(); + sImageCount++; } LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) : - LLGLTexture(raw, usemipmaps) + LLGLTexture(raw, usemipmaps) { - init(true); - - mID.generate(); - sImageCount++; + init(true); + + mID.generate(); + sImageCount++; } LLViewerTexture::~LLViewerTexture() { - // LL_DEBUGS("Avatar") << mID << LL_ENDL; - cleanup(); - sImageCount--; + // LL_DEBUGS("Avatar") << mID << LL_ENDL; + cleanup(); + sImageCount--; } // virtual void LLViewerTexture::init(bool firstinit) { - mMaxVirtualSize = 0.f; - mMaxVirtualSizeResetInterval = 1; - mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval; - mParcelMedia = NULL; - - memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS); - mFaceList[LLRender::DIFFUSE_MAP].clear(); - mFaceList[LLRender::NORMAL_MAP].clear(); - mFaceList[LLRender::SPECULAR_MAP].clear(); - mNumFaces[LLRender::DIFFUSE_MAP] = - mNumFaces[LLRender::NORMAL_MAP] = - mNumFaces[LLRender::SPECULAR_MAP] = 0; - - mVolumeList[LLRender::LIGHT_TEX].clear(); - mVolumeList[LLRender::SCULPT_TEX].clear(); - - mMainQueue = LL::WorkQueue::getInstance("mainloop"); - mImageQueue = LL::WorkQueue::getInstance("LLImageGL"); -} - -//virtual + mMaxVirtualSize = 0.f; + mMaxVirtualSizeResetInterval = 1; + mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval; + mParcelMedia = NULL; + + memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS); + mFaceList[LLRender::DIFFUSE_MAP].clear(); + mFaceList[LLRender::NORMAL_MAP].clear(); + mFaceList[LLRender::SPECULAR_MAP].clear(); + mNumFaces[LLRender::DIFFUSE_MAP] = + mNumFaces[LLRender::NORMAL_MAP] = + mNumFaces[LLRender::SPECULAR_MAP] = 0; + + mVolumeList[LLRender::LIGHT_TEX].clear(); + mVolumeList[LLRender::SCULPT_TEX].clear(); + + mMainQueue = LL::WorkQueue::getInstance("mainloop"); + mImageQueue = LL::WorkQueue::getInstance("LLImageGL"); +} + +//virtual S8 LLViewerTexture::getType() const { - return LLViewerTexture::LOCAL_TEXTURE; + return LLViewerTexture::LOCAL_TEXTURE; } void LLViewerTexture::cleanup() @@ -641,37 +641,37 @@ void LLViewerTexture::cleanup() LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); } - mFaceList[LLRender::DIFFUSE_MAP].clear(); - mFaceList[LLRender::NORMAL_MAP].clear(); - mFaceList[LLRender::SPECULAR_MAP].clear(); - mVolumeList[LLRender::LIGHT_TEX].clear(); - mVolumeList[LLRender::SCULPT_TEX].clear(); + mFaceList[LLRender::DIFFUSE_MAP].clear(); + mFaceList[LLRender::NORMAL_MAP].clear(); + mFaceList[LLRender::SPECULAR_MAP].clear(); + mVolumeList[LLRender::LIGHT_TEX].clear(); + mVolumeList[LLRender::SCULPT_TEX].clear(); } // virtual void LLViewerTexture::dump() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLGLTexture::dump(); + LLGLTexture::dump(); - LL_INFOS() << "LLViewerTexture" - << " mID " << mID - << LL_ENDL; + LL_INFOS() << "LLViewerTexture" + << " mID " << mID + << LL_ENDL; } void LLViewerTexture::setBoostLevel(S32 level) { - if(mBoostLevel != level) - { - mBoostLevel = level; - if(mBoostLevel != LLViewerTexture::BOOST_NONE && - mBoostLevel != LLViewerTexture::BOOST_SELECTED && - mBoostLevel != LLViewerTexture::BOOST_ICON && + if(mBoostLevel != level) + { + mBoostLevel = level; + if(mBoostLevel != LLViewerTexture::BOOST_NONE && + mBoostLevel != LLViewerTexture::BOOST_SELECTED && + mBoostLevel != LLViewerTexture::BOOST_ICON && mBoostLevel != LLViewerTexture::BOOST_THUMBNAIL) - { - setNoDelete(); - } - } + { + setNoDelete(); + } + } // strongly encourage anything boosted to load at full res if (mBoostLevel >= LLViewerTexture::BOOST_HIGH) @@ -682,159 +682,159 @@ void LLViewerTexture::setBoostLevel(S32 level) bool LLViewerTexture::isActiveFetching() { - return false; + return false; } bool LLViewerTexture::bindDebugImage(const S32 stage) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (stage < 0) return false; + if (stage < 0) return false; - bool res = true; - if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get())) - { - res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep); - } + bool res = true; + if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get())) + { + res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep); + } - if(!res) - { - return bindDefaultImage(stage); - } + if(!res) + { + return bindDefaultImage(stage); + } - return res; + return res; } -bool LLViewerTexture::bindDefaultImage(S32 stage) +bool LLViewerTexture::bindDefaultImage(S32 stage) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (stage < 0) return false; + if (stage < 0) return false; - bool res = true; - if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get())) - { - // use default if we've got it - res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep); - } - if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep)) - { - res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep); - } - if (!res) - { - LL_WARNS() << "LLViewerTexture::bindDefaultImage failed." << LL_ENDL; - } - stop_glerror(); + bool res = true; + if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get())) + { + // use default if we've got it + res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep); + } + if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep)) + { + res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep); + } + if (!res) + { + LL_WARNS() << "LLViewerTexture::bindDefaultImage failed." << LL_ENDL; + } + stop_glerror(); - //check if there is cached raw image and switch to it if possible - switchToCachedImage(); + //check if there is cached raw image and switch to it if possible + switchToCachedImage(); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->updateGrayTextureBinding(); - } - return res; + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); + if (tester) + { + tester->updateGrayTextureBinding(); + } + return res; } -//virtual -BOOL LLViewerTexture::isMissingAsset()const -{ - return FALSE; +//virtual +BOOL LLViewerTexture::isMissingAsset()const +{ + return FALSE; } -//virtual -void LLViewerTexture::forceImmediateUpdate() +//virtual +void LLViewerTexture::forceImmediateUpdate() { } -void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const +void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(needs_gltexture) - { - mNeedsGLTexture = TRUE; - } + if(needs_gltexture) + { + mNeedsGLTexture = TRUE; + } virtual_size = llmin(virtual_size, LLViewerFetchedTexture::sMaxVirtualSize); - if (virtual_size > mMaxVirtualSize) - { - mMaxVirtualSize = virtual_size; - } + if (virtual_size > mMaxVirtualSize) + { + mMaxVirtualSize = virtual_size; + } } void LLViewerTexture::resetTextureStats() { - mMaxVirtualSize = 0.0f; - mMaxVirtualSizeResetCounter = 0; + mMaxVirtualSize = 0.0f; + mMaxVirtualSizeResetCounter = 0; } -//virtual +//virtual F32 LLViewerTexture::getMaxVirtualSize() { - return mMaxVirtualSize; + return mMaxVirtualSize; } -//virtual +//virtual void LLViewerTexture::setKnownDrawSize(S32 width, S32 height) { - //nothing here. + //nothing here. } //virtual -void LLViewerTexture::addFace(U32 ch, LLFace* facep) +void LLViewerTexture::addFace(U32 ch, LLFace* facep) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - if(mNumFaces[ch] >= mFaceList[ch].size()) - { - mFaceList[ch].resize(2 * mNumFaces[ch] + 1); - } - mFaceList[ch][mNumFaces[ch]] = facep; - facep->setIndexInTex(ch, mNumFaces[ch]); - mNumFaces[ch]++; - mLastFaceListUpdateTimer.reset(); + if(mNumFaces[ch] >= mFaceList[ch].size()) + { + mFaceList[ch].resize(2 * mNumFaces[ch] + 1); + } + mFaceList[ch][mNumFaces[ch]] = facep; + facep->setIndexInTex(ch, mNumFaces[ch]); + mNumFaces[ch]++; + mLastFaceListUpdateTimer.reset(); } //virtual -void LLViewerTexture::removeFace(U32 ch, LLFace* facep) +void LLViewerTexture::removeFace(U32 ch, LLFace* facep) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - - if(mNumFaces[ch] > 1) - { - S32 index = facep->getIndexInTex(ch); - llassert(index < mFaceList[ch].size()); - llassert(index < mNumFaces[ch]); - mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]]; - mFaceList[ch][index]->setIndexInTex(ch, index); - } - else - { - mFaceList[ch].clear(); - mNumFaces[ch] = 0; - } - mLastFaceListUpdateTimer.reset(); + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + + if(mNumFaces[ch] > 1) + { + S32 index = facep->getIndexInTex(ch); + llassert(index < mFaceList[ch].size()); + llassert(index < mNumFaces[ch]); + mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]]; + mFaceList[ch][index]->setIndexInTex(ch, index); + } + else + { + mFaceList[ch].clear(); + mNumFaces[ch] = 0; + } + mLastFaceListUpdateTimer.reset(); } S32 LLViewerTexture::getTotalNumFaces() const { - S32 ret = 0; + S32 ret = 0; - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - ret += mNumFaces[i]; - } + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + ret += mNumFaces[i]; + } - return ret; + return ret; } S32 LLViewerTexture::getNumFaces(U32 ch) const { - llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - return mNumFaces[ch]; + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + return mNumFaces[ch]; } @@ -842,117 +842,117 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (mNumVolumes[ch] >= mVolumeList[ch].size()) - { - mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1); - } - mVolumeList[ch][mNumVolumes[ch]] = volumep; - volumep->setIndexInTex(ch, mNumVolumes[ch]); - mNumVolumes[ch]++; - mLastVolumeListUpdateTimer.reset(); + if (mNumVolumes[ch] >= mVolumeList[ch].size()) + { + mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1); + } + mVolumeList[ch][mNumVolumes[ch]] = volumep; + volumep->setIndexInTex(ch, mNumVolumes[ch]); + mNumVolumes[ch]++; + mLastVolumeListUpdateTimer.reset(); } //virtual void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (mNumVolumes[ch] > 1) - { - S32 index = volumep->getIndexInTex(ch); - llassert(index < mVolumeList[ch].size()); - llassert(index < mNumVolumes[ch]); - mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]]; - mVolumeList[ch][index]->setIndexInTex(ch, index); - } - else - { - mVolumeList[ch].clear(); - mNumVolumes[ch] = 0; - } - mLastVolumeListUpdateTimer.reset(); + if (mNumVolumes[ch] > 1) + { + S32 index = volumep->getIndexInTex(ch); + llassert(index < mVolumeList[ch].size()); + llassert(index < mNumVolumes[ch]); + mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]]; + mVolumeList[ch][index]->setIndexInTex(ch, index); + } + else + { + mVolumeList[ch].clear(); + mNumVolumes[ch] = 0; + } + mLastVolumeListUpdateTimer.reset(); } S32 LLViewerTexture::getNumVolumes(U32 ch) const { - return mNumVolumes[ch]; + return mNumVolumes[ch]; } void LLViewerTexture::reorganizeFaceList() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static const F32 MAX_WAIT_TIME = 20.f; // seconds - static const U32 MAX_EXTRA_BUFFER_SIZE = 4; + static const F32 MAX_WAIT_TIME = 20.f; // seconds + static const U32 MAX_EXTRA_BUFFER_SIZE = 4; + + if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) + { + return; + } - if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) - { - return; - } + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size()) + { + return; + } - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size()) - { - return; - } + mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end()); + } - mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end()); - } - - mLastFaceListUpdateTimer.reset(); + mLastFaceListUpdateTimer.reset(); } void LLViewerTexture::reorganizeVolumeList() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static const F32 MAX_WAIT_TIME = 20.f; // seconds - static const U32 MAX_EXTRA_BUFFER_SIZE = 4; + static const F32 MAX_WAIT_TIME = 20.f; // seconds + static const U32 MAX_EXTRA_BUFFER_SIZE = 4; - for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i) - { - if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size()) - { - return; - } - } + for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i) + { + if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size()) + { + return; + } + } - if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) - { - return; - } + if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) + { + return; + } - mLastVolumeListUpdateTimer.reset(); - for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i) - { - mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i], mVolumeList[i].end()); - } + mLastVolumeListUpdateTimer.reset(); + for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i) + { + mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i], mVolumeList[i].end()); + } } //virtual void LLViewerTexture::switchToCachedImage() { - //nothing here. + //nothing here. } //virtual void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) { - //nothing here. + //nothing here. } BOOL LLViewerTexture::isLargeImage() { - return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize; + return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize; } -//virtual +//virtual void LLViewerTexture::updateBindStatsForTester() { - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->updateTextureBindingStats(this); - } + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); + if (tester) + { + tester->updateTextureBindingStats(this); + } } //---------------------------------------------------------------------------------------------- @@ -961,30 +961,30 @@ void LLViewerTexture::updateBindStatsForTester() const std::string& fttype_to_string(const FTType& fttype) { - static const std::string ftt_unknown("FTT_UNKNOWN"); - static const std::string ftt_default("FTT_DEFAULT"); - static const std::string ftt_server_bake("FTT_SERVER_BAKE"); - static const std::string ftt_host_bake("FTT_HOST_BAKE"); - static const std::string ftt_map_tile("FTT_MAP_TILE"); - static const std::string ftt_local_file("FTT_LOCAL_FILE"); - static const std::string ftt_error("FTT_ERROR"); - switch(fttype) - { - case FTT_UNKNOWN: return ftt_unknown; break; - case FTT_DEFAULT: return ftt_default; break; - case FTT_SERVER_BAKE: return ftt_server_bake; break; - case FTT_HOST_BAKE: return ftt_host_bake; break; - case FTT_MAP_TILE: return ftt_map_tile; break; - case FTT_LOCAL_FILE: return ftt_local_file; break; - } - return ftt_error; + static const std::string ftt_unknown("FTT_UNKNOWN"); + static const std::string ftt_default("FTT_DEFAULT"); + static const std::string ftt_server_bake("FTT_SERVER_BAKE"); + static const std::string ftt_host_bake("FTT_HOST_BAKE"); + static const std::string ftt_map_tile("FTT_MAP_TILE"); + static const std::string ftt_local_file("FTT_LOCAL_FILE"); + static const std::string ftt_error("FTT_ERROR"); + switch(fttype) + { + case FTT_UNKNOWN: return ftt_unknown; break; + case FTT_DEFAULT: return ftt_default; break; + case FTT_SERVER_BAKE: return ftt_server_bake; break; + case FTT_HOST_BAKE: return ftt_host_bake; break; + case FTT_MAP_TILE: return ftt_map_tile; break; + case FTT_LOCAL_FILE: return ftt_local_file; break; + } + return ftt_error; } //---------------------------------------------------------------------------------------------- //start of LLViewerFetchedTexture //---------------------------------------------------------------------------------------------- -//static +//static LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage() { if (sSmokeImagep.isNull()) @@ -998,186 +998,186 @@ LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage() } LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps) - : LLViewerTexture(id, usemipmaps), - mTargetHost(host) -{ - init(TRUE); - mFTType = f_type; - if (mFTType == FTT_HOST_BAKE) - { - LL_WARNS() << "Unsupported fetch type " << mFTType << LL_ENDL; - } - generateGLTexture(); -} - + : LLViewerTexture(id, usemipmaps), + mTargetHost(host) +{ + init(TRUE); + mFTType = f_type; + if (mFTType == FTT_HOST_BAKE) + { + LL_WARNS() << "Unsupported fetch type " << mFTType << LL_ENDL; + } + generateGLTexture(); +} + LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps) - : LLViewerTexture(raw, usemipmaps) + : LLViewerTexture(raw, usemipmaps) { - init(TRUE); - mFTType = f_type; + init(TRUE); + mFTType = f_type; } - + LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps) - : LLViewerTexture(id, usemipmaps), - mUrl(url) + : LLViewerTexture(id, usemipmaps), + mUrl(url) { - init(TRUE); - mFTType = f_type; - generateGLTexture(); + init(TRUE); + mFTType = f_type; + generateGLTexture(); } void LLViewerFetchedTexture::init(bool firstinit) { - mOrigWidth = 0; - mOrigHeight = 0; - mHasAux = FALSE; - mNeedsAux = FALSE; - mRequestedDiscardLevel = -1; - mRequestedDownloadPriority = 0.f; - mFullyLoaded = FALSE; - mCanUseHTTP = true; - mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; - mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; - - mDecodingAux = FALSE; - - mKnownDrawWidth = 0; - mKnownDrawHeight = 0; - mKnownDrawSizeChanged = FALSE; - - if (firstinit) - { - mInImageList = 0; - } - - // Only set mIsMissingAsset true when we know for certain that the database - // does not contain this image. - mIsMissingAsset = FALSE; - - mLoadedCallbackDesiredDiscardLevel = S8_MAX; - mPauseLoadedCallBacks = FALSE; - - mNeedsCreateTexture = false; - - mIsRawImageValid = FALSE; - mRawDiscardLevel = INVALID_DISCARD_LEVEL; - mMinDiscardLevel = 0; - - mHasFetcher = FALSE; - mIsFetching = FALSE; - mFetchState = 0; - mFetchPriority = 0; - mDownloadProgress = 0.f; - mFetchDeltaTime = 999999.f; - mRequestDeltaTime = 0.f; - mForSculpt = FALSE; - mIsFetched = FALSE; - mInFastCacheList = FALSE; - - mCachedRawImage = NULL; - mCachedRawDiscardLevel = -1; - mCachedRawImageReady = FALSE; - - mSavedRawImage = NULL; - mForceToSaveRawImage = FALSE; - mSaveRawImage = FALSE; - mSavedRawDiscardLevel = -1; - mDesiredSavedRawDiscardLevel = -1; - mLastReferencedSavedRawImageTime = 0.0f; - mKeptSavedRawImageTime = 0.f; - mLastCallBackActiveTime = 0.f; - mForceCallbackFetch = FALSE; - mInDebug = FALSE; - mUnremovable = FALSE; - - mFTType = FTT_UNKNOWN; + mOrigWidth = 0; + mOrigHeight = 0; + mHasAux = FALSE; + mNeedsAux = FALSE; + mRequestedDiscardLevel = -1; + mRequestedDownloadPriority = 0.f; + mFullyLoaded = FALSE; + mCanUseHTTP = true; + mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; + mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; + + mDecodingAux = FALSE; + + mKnownDrawWidth = 0; + mKnownDrawHeight = 0; + mKnownDrawSizeChanged = FALSE; + + if (firstinit) + { + mInImageList = 0; + } + + // Only set mIsMissingAsset true when we know for certain that the database + // does not contain this image. + mIsMissingAsset = FALSE; + + mLoadedCallbackDesiredDiscardLevel = S8_MAX; + mPauseLoadedCallBacks = FALSE; + + mNeedsCreateTexture = false; + + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + mMinDiscardLevel = 0; + + mHasFetcher = FALSE; + mIsFetching = FALSE; + mFetchState = 0; + mFetchPriority = 0; + mDownloadProgress = 0.f; + mFetchDeltaTime = 999999.f; + mRequestDeltaTime = 0.f; + mForSculpt = FALSE; + mIsFetched = FALSE; + mInFastCacheList = FALSE; + + mCachedRawImage = NULL; + mCachedRawDiscardLevel = -1; + mCachedRawImageReady = FALSE; + + mSavedRawImage = NULL; + mForceToSaveRawImage = FALSE; + mSaveRawImage = FALSE; + mSavedRawDiscardLevel = -1; + mDesiredSavedRawDiscardLevel = -1; + mLastReferencedSavedRawImageTime = 0.0f; + mKeptSavedRawImageTime = 0.f; + mLastCallBackActiveTime = 0.f; + mForceCallbackFetch = FALSE; + mInDebug = FALSE; + mUnremovable = FALSE; + + mFTType = FTT_UNKNOWN; } LLViewerFetchedTexture::~LLViewerFetchedTexture() { assert_main_thread(); - //*NOTE getTextureFetch can return NULL when Viewer is shutting down. - // This is due to LLWearableList is singleton and is destroyed after - // LLAppViewer::cleanup() was called. (see ticket EXT-177) - if (mHasFetcher && LLAppViewer::getTextureFetch()) - { - LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); - } - cleanup(); + //*NOTE getTextureFetch can return NULL when Viewer is shutting down. + // This is due to LLWearableList is singleton and is destroyed after + // LLAppViewer::cleanup() was called. (see ticket EXT-177) + if (mHasFetcher && LLAppViewer::getTextureFetch()) + { + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + } + cleanup(); } -//virtual +//virtual S8 LLViewerFetchedTexture::getType() const { - return LLViewerTexture::FETCHED_TEXTURE; + return LLViewerTexture::FETCHED_TEXTURE; } FTType LLViewerFetchedTexture::getFTType() const { - return mFTType; + return mFTType; } void LLViewerFetchedTexture::cleanup() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter++; - // We never finished loading the image. Indicate failure. - // Note: this allows mLoadedCallbackUserData to be cleaned up. - entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData ); - entryp->removeTexture(this); - delete entryp; - } - mLoadedCallbackList.clear(); - mNeedsAux = FALSE; - - // Clean up image data - destroyRawImage(); - mCachedRawImage = NULL; - mCachedRawDiscardLevel = -1; - mCachedRawImageReady = FALSE; - mSavedRawImage = NULL; - mSavedRawDiscardLevel = -1; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData ); + entryp->removeTexture(this); + delete entryp; + } + mLoadedCallbackList.clear(); + mNeedsAux = FALSE; + + // Clean up image data + destroyRawImage(); + mCachedRawImage = NULL; + mCachedRawDiscardLevel = -1; + mCachedRawImageReady = FALSE; + mSavedRawImage = NULL; + mSavedRawDiscardLevel = -1; } //access the fast cache void LLViewerFetchedTexture::loadFromFastCache() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(!mInFastCacheList) - { - return; //no need to access the fast cache. - } - mInFastCacheList = FALSE; + if(!mInFastCacheList) + { + return; //no need to access the fast cache. + } + mInFastCacheList = FALSE; add(LLTextureFetch::sCacheAttempt, 1.0); LLTimer fastCacheTimer; - mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel); - if(mRawImage.notNull()) - { + mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel); + if(mRawImage.notNull()) + { F32 cachReadTime = fastCacheTimer.getElapsedTimeF32(); add(LLTextureFetch::sCacheHit, 1.0); record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1)); sample(LLTextureFetch::sCacheReadLatency, cachReadTime); - mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; - mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; - setTexelsPerImage(); - - if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) - { - //discard all oversized textures. - destroyRawImage(); - LL_WARNS() << "oversized, setting as missing" << LL_ENDL; - setIsMissingAsset(); - mRawDiscardLevel = INVALID_DISCARD_LEVEL; - } - else - { + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + setTexelsPerImage(); + + if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) + { + //discard all oversized textures. + destroyRawImage(); + LL_WARNS() << "oversized, setting as missing" << LL_ENDL; + setIsMissingAsset(); + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + } + else + { if (mBoostLevel == LLGLTexture::BOOST_ICON) { // Shouldn't do anything usefull since texures in fast cache are 16x16, @@ -1202,11 +1202,11 @@ void LLViewerFetchedTexture::loadFromFastCache() } } - mRequestedDiscardLevel = mDesiredDiscardLevel + 1; - mIsRawImageValid = TRUE; - addToCreateTexture(); - } - } + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture(); + } + } else { record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0)); @@ -1215,197 +1215,197 @@ void LLViewerFetchedTexture::loadFromFastCache() void LLViewerFetchedTexture::setForSculpt() { - static const S32 MAX_INTERVAL = 8; //frames + static const S32 MAX_INTERVAL = 8; //frames - mForSculpt = TRUE; - if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) - { - destroyGLTexture(); //sculpt image does not need gl texture. - mTextureState = ACTIVE; - } - checkCachedRawSculptImage(); - setMaxVirtualSizeResetInterval(MAX_INTERVAL); + mForSculpt = TRUE; + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) + { + destroyGLTexture(); //sculpt image does not need gl texture. + mTextureState = ACTIVE; + } + checkCachedRawSculptImage(); + setMaxVirtualSizeResetInterval(MAX_INTERVAL); } BOOL LLViewerFetchedTexture::isForSculptOnly() const { - return mForSculpt && !mNeedsGLTexture; + return mForSculpt && !mNeedsGLTexture; } -BOOL LLViewerFetchedTexture::isDeleted() -{ - return mTextureState == DELETED; +BOOL LLViewerFetchedTexture::isDeleted() +{ + return mTextureState == DELETED; } -BOOL LLViewerFetchedTexture::isInactive() -{ - return mTextureState == INACTIVE; +BOOL LLViewerFetchedTexture::isInactive() +{ + return mTextureState == INACTIVE; } -BOOL LLViewerFetchedTexture::isDeletionCandidate() -{ - return mTextureState == DELETION_CANDIDATE; +BOOL LLViewerFetchedTexture::isDeletionCandidate() +{ + return mTextureState == DELETION_CANDIDATE; } -void LLViewerFetchedTexture::setDeletionCandidate() -{ - if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE)) - { - mTextureState = DELETION_CANDIDATE; - } +void LLViewerFetchedTexture::setDeletionCandidate() +{ + if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE)) + { + mTextureState = DELETION_CANDIDATE; + } } //set the texture inactive void LLViewerFetchedTexture::setInactive() { - if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently()) - { - mTextureState = INACTIVE; - } + if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently()) + { + mTextureState = INACTIVE; + } } BOOL LLViewerFetchedTexture::isFullyLoaded() const { - // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic - // to check if the texture is there and completely downloaded - return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher; + // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic + // to check if the texture is there and completely downloaded + return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher; } // virtual void LLViewerFetchedTexture::dump() { - LLViewerTexture::dump(); - - LL_INFOS() << "Dump : " << mID - << ", mIsMissingAsset = " << (S32)mIsMissingAsset - << ", mFullWidth = " << (S32)mFullWidth - << ", mFullHeight = " << (S32)mFullHeight - << ", mOrigWidth = " << (S32)mOrigWidth - << ", mOrigHeight = " << (S32)mOrigHeight - << LL_ENDL; - LL_INFOS() << " : " - << " mFullyLoaded = " << (S32)mFullyLoaded - << ", mFetchState = " << (S32)mFetchState - << ", mFetchPriority = " << (S32)mFetchPriority - << ", mDownloadProgress = " << (F32)mDownloadProgress - << LL_ENDL; - LL_INFOS() << " : " - << " mHasFetcher = " << (S32)mHasFetcher - << ", mIsFetching = " << (S32)mIsFetching - << ", mIsFetched = " << (S32)mIsFetched - << ", mBoostLevel = " << (S32)mBoostLevel - << LL_ENDL; + LLViewerTexture::dump(); + + LL_INFOS() << "Dump : " << mID + << ", mIsMissingAsset = " << (S32)mIsMissingAsset + << ", mFullWidth = " << (S32)mFullWidth + << ", mFullHeight = " << (S32)mFullHeight + << ", mOrigWidth = " << (S32)mOrigWidth + << ", mOrigHeight = " << (S32)mOrigHeight + << LL_ENDL; + LL_INFOS() << " : " + << " mFullyLoaded = " << (S32)mFullyLoaded + << ", mFetchState = " << (S32)mFetchState + << ", mFetchPriority = " << (S32)mFetchPriority + << ", mDownloadProgress = " << (F32)mDownloadProgress + << LL_ENDL; + LL_INFOS() << " : " + << " mHasFetcher = " << (S32)mHasFetcher + << ", mIsFetching = " << (S32)mIsFetching + << ", mIsFetched = " << (S32)mIsFetched + << ", mBoostLevel = " << (S32)mBoostLevel + << LL_ENDL; } /////////////////////////////////////////////////////////////////////////////// // ONLY called from LLViewerFetchedTextureList -void LLViewerFetchedTexture::destroyTexture() +void LLViewerFetchedTexture::destroyTexture() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (mNeedsCreateTexture)//return if in the process of generating a new texture. - { - return; - } + if (mNeedsCreateTexture)//return if in the process of generating a new texture. + { + return; + } - //LL_DEBUGS("Avatar") << mID << LL_ENDL; - destroyGLTexture(); - mFullyLoaded = FALSE; + //LL_DEBUGS("Avatar") << mID << LL_ENDL; + destroyGLTexture(); + mFullyLoaded = FALSE; } void LLViewerFetchedTexture::addToCreateTexture() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - bool force_update = false; - if (getComponents() != mRawImage->getComponents()) - { - // We've changed the number of components, so we need to move any - // objects using this pool to a different pool. - mComponents = mRawImage->getComponents(); - mGLTexturep->setComponents(mComponents); - force_update = true; - - for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j) - { - llassert(mNumFaces[j] <= mFaceList[j].size()); - - for(U32 i = 0; i < mNumFaces[j]; i++) - { - mFaceList[j][i]->dirtyTexture(); - } - } - - //discard the cached raw image and the saved raw image - mCachedRawImageReady = FALSE; - mCachedRawDiscardLevel = -1; - mCachedRawImage = NULL; - mSavedRawDiscardLevel = -1; - mSavedRawImage = NULL; - } - - if(isForSculptOnly()) - { - //just update some variables, not to create a real GL texture. - createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE); - mNeedsCreateTexture = false; - destroyRawImage(); - } - else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel) - { - mNeedsCreateTexture = false; - destroyRawImage(); - } - else - { + bool force_update = false; + if (getComponents() != mRawImage->getComponents()) + { + // We've changed the number of components, so we need to move any + // objects using this pool to a different pool. + mComponents = mRawImage->getComponents(); + mGLTexturep->setComponents(mComponents); + force_update = true; + + for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j) + { + llassert(mNumFaces[j] <= mFaceList[j].size()); + + for(U32 i = 0; i < mNumFaces[j]; i++) + { + mFaceList[j][i]->dirtyTexture(); + } + } + + //discard the cached raw image and the saved raw image + mCachedRawImageReady = FALSE; + mCachedRawDiscardLevel = -1; + mCachedRawImage = NULL; + mSavedRawDiscardLevel = -1; + mSavedRawImage = NULL; + } + + if(isForSculptOnly()) + { + //just update some variables, not to create a real GL texture. + createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE); + mNeedsCreateTexture = false; + destroyRawImage(); + } + else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel) + { + mNeedsCreateTexture = false; + destroyRawImage(); + } + else + { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; #if 1 - // - //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up, - //so do not scale down the over qualified image. - //Note: scaling down image is expensensive. Do it only when very necessary. - // - if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !mForceToSaveRawImage) - { - S32 w = mFullWidth >> mRawDiscardLevel; - S32 h = mFullHeight >> mRawDiscardLevel; - - //if big image, do not load extra data - //scale it down to size >= LLViewerTexture::sMinLargeImageSize - if(w * h > LLViewerTexture::sMinLargeImageSize) - { - S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel; - - if(d_level > 0) - { - S32 i = 0; - while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize)) - { - i++; - d_level--; - } - if(i > 0) - { - mRawDiscardLevel += i; - if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0) - { - mNeedsCreateTexture = false; - destroyRawImage(); - return; - } - - { - //make a duplicate in case somebody else is using this raw image - mRawImage = mRawImage->scaled(w >> i, h >> i); - } - } - } - } - } + // + //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up, + //so do not scale down the over qualified image. + //Note: scaling down image is expensensive. Do it only when very necessary. + // + if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !mForceToSaveRawImage) + { + S32 w = mFullWidth >> mRawDiscardLevel; + S32 h = mFullHeight >> mRawDiscardLevel; + + //if big image, do not load extra data + //scale it down to size >= LLViewerTexture::sMinLargeImageSize + if(w * h > LLViewerTexture::sMinLargeImageSize) + { + S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel; + + if(d_level > 0) + { + S32 i = 0; + while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize)) + { + i++; + d_level--; + } + if(i > 0) + { + mRawDiscardLevel += i; + if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0) + { + mNeedsCreateTexture = false; + destroyRawImage(); + return; + } + + { + //make a duplicate in case somebody else is using this raw image + mRawImage = mRawImage->scaled(w >> i, h >> i); + } + } + } + } + } #endif scheduleCreateTexture(); - } - return; + } + return; } // ONLY called from LLViewerTextureList @@ -1433,10 +1433,10 @@ BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/) destroyRawImage(); return FALSE; } - // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", - // mRawDiscardLevel, - // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) - // << mID.getString() << LL_ENDL; + // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", + // mRawDiscardLevel, + // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) + // << mID.getString() << LL_ENDL; BOOL res = TRUE; // store original size only for locally-sourced images @@ -1532,9 +1532,9 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) return FALSE; } - BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); - - return res; + BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + + return res; } void LLViewerFetchedTexture::postCreateTexture() @@ -1640,15 +1640,15 @@ void LLViewerFetchedTexture::scheduleCreateTexture() void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mKnownDrawWidth < width || mKnownDrawHeight < height) - { - mKnownDrawWidth = llmax(mKnownDrawWidth, width); - mKnownDrawHeight = llmax(mKnownDrawHeight, height); + if(mKnownDrawWidth < width || mKnownDrawHeight < height) + { + mKnownDrawWidth = llmax(mKnownDrawWidth, width); + mKnownDrawHeight = llmax(mKnownDrawHeight, height); - mKnownDrawSizeChanged = TRUE; - mFullyLoaded = FALSE; - } - addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight)); + mKnownDrawSizeChanged = TRUE; + mFullyLoaded = FALSE; + } + addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight)); } void LLViewerFetchedTexture::setDebugText(const std::string& text) @@ -1676,25 +1676,25 @@ void LLViewerFetchedTexture::setDebugText(const std::string& text) void LLViewerFetchedTexture::processTextureStats() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mFullyLoaded) - { - if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more - { - mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); - mFullyLoaded = FALSE; - } + if(mFullyLoaded) + { + if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more + { + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); + mFullyLoaded = FALSE; + } //setDebugText("fully loaded"); - } - else - { - updateVirtualSize(); - - static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); - - if (textures_fullres) - { - mDesiredDiscardLevel = 0; - } + } + else + { + updateVirtualSize(); + + static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); + + if (textures_fullres) + { + mDesiredDiscardLevel = 0; + } else if (mDontDiscard && (mBoostLevel == LLGLTexture::BOOST_ICON || mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)) { if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) @@ -1706,96 +1706,96 @@ void LLViewerFetchedTexture::processTextureStats() mDesiredDiscardLevel = 0; } } - else if(!mFullWidth || !mFullHeight) - { - mDesiredDiscardLevel = llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel); - } - else - { - U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 - if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight) - { - if (mFullWidth > desired_size || mFullHeight > desired_size) - { - mDesiredDiscardLevel = 1; - } - else - { - mDesiredDiscardLevel = 0; - } - } - else if(mKnownDrawSizeChanged)//known draw size is set - { - mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, - log((F32)mFullHeight / mKnownDrawHeight) / log_2); - mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()); - mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); - } - mKnownDrawSizeChanged = FALSE; - - if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel)) - { - mFullyLoaded = TRUE; - } - } - } - - if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture. - { - mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel); - if(getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel) - { - mFullyLoaded = FALSE; - } - } -} - -//============================================================================ - -void LLViewerFetchedTexture::updateVirtualSize() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - reorganizeFaceList(); - reorganizeVolumeList(); -} - -S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() -{ - S32 current_discard = getDiscardLevel(); - if(mForceToSaveRawImage) - { - if(mSavedRawDiscardLevel < 0 || current_discard < 0) - { - current_discard = -1; - } - else - { - current_discard = llmax(current_discard, mSavedRawDiscardLevel); - } - } - - return current_discard; + else if(!mFullWidth || !mFullHeight) + { + mDesiredDiscardLevel = llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel); + } + else + { + U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 + if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight) + { + if (mFullWidth > desired_size || mFullHeight > desired_size) + { + mDesiredDiscardLevel = 1; + } + else + { + mDesiredDiscardLevel = 0; + } + } + else if(mKnownDrawSizeChanged)//known draw size is set + { + mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, + log((F32)mFullHeight / mKnownDrawHeight) / log_2); + mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()); + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); + } + mKnownDrawSizeChanged = FALSE; + + if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel)) + { + mFullyLoaded = TRUE; + } + } + } + + if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture. + { + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel); + if(getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel) + { + mFullyLoaded = FALSE; + } + } +} + +//============================================================================ + +void LLViewerFetchedTexture::updateVirtualSize() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + reorganizeFaceList(); + reorganizeVolumeList(); +} + +S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() +{ + S32 current_discard = getDiscardLevel(); + if(mForceToSaveRawImage) + { + if(mSavedRawDiscardLevel < 0 || current_discard < 0) + { + current_discard = -1; + } + else + { + current_discard = llmax(current_discard, mSavedRawDiscardLevel); + } + } + + return current_discard; } bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) { - if(debug_level < 0) - { - mInDebug = FALSE; - return false; - } - mInDebug = TRUE; + if(debug_level < 0) + { + mInDebug = FALSE; + return false; + } + mInDebug = TRUE; - mDesiredDiscardLevel = debug_level; + mDesiredDiscardLevel = debug_level; - return true; + return true; } bool LLViewerFetchedTexture::isActiveFetching() { - static LLCachedControl monitor_enabled(gSavedSettings,"DebugShowTextureInfo"); + static LLCachedControl monitor_enabled(gSavedSettings,"DebugShowTextureInfo"); - return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE. + return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE. } void LLViewerFetchedTexture::setBoostLevel(S32 level) @@ -1811,121 +1811,121 @@ void LLViewerFetchedTexture::setBoostLevel(S32 level) bool LLViewerFetchedTexture::updateFetch() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static LLCachedControl textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); - - if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode - { - return false; - } - - mFetchState = 0; - mFetchPriority = 0; - mFetchDeltaTime = 999999.f; - mRequestDeltaTime = 999999.f; + static LLCachedControl textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); + + if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode + { + return false; + } + + mFetchState = 0; + mFetchPriority = 0; + mFetchDeltaTime = 999999.f; + mRequestDeltaTime = 999999.f; #ifndef LL_RELEASE_FOR_DOWNLOAD - if (mID == LLAppViewer::getTextureFetch()->mDebugID) - { - LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints - } + if (mID == LLAppViewer::getTextureFetch()->mDebugID) + { + LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints + } #endif - if (mNeedsCreateTexture) - { + if (mNeedsCreateTexture) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create"); - // We may be fetching still (e.g. waiting on write) - // but don't check until we've processed the raw data we have - return false; - } - if (mIsMissingAsset) - { + // We may be fetching still (e.g. waiting on write) + // but don't check until we've processed the raw data we have + return false; + } + if (mIsMissingAsset) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset"); - llassert(!mHasFetcher); - return false; // skip - } - if (!mLoadedCallbackList.empty() && mRawImage.notNull()) - { + llassert(!mHasFetcher); + return false; // skip + } + if (!mLoadedCallbackList.empty() && mRawImage.notNull()) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending"); - return false; // process any raw image data in callbacks before replacing - } - if(mInFastCacheList) - { + return false; // process any raw image data in callbacks before replacing + } + if(mInFastCacheList) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache"); - return false; - } + return false; + } if (mGLTexturep.isNull()) { // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening) llassert(false); return false; } - - S32 current_discard = getCurrentDiscardLevelForFetching(); - S32 desired_discard = getDesiredDiscardLevel(); - F32 decode_priority = mMaxVirtualSize; - if (mIsFetching) - { + S32 current_discard = getCurrentDiscardLevelForFetching(); + S32 desired_discard = getDesiredDiscardLevel(); + F32 decode_priority = mMaxVirtualSize; + + if (mIsFetching) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching"); - // Sets mRawDiscardLevel, mRawImage, mAuxRawImage - S32 fetch_discard = current_discard; - - if (mRawImage.notNull()) sRawCount--; - if (mAuxRawImage.notNull()) sAuxCount--; - // keep in mind that fetcher still might need raw image, don't modify original - bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage, - mLastHttpGetStatus); - if (mRawImage.notNull()) sRawCount++; - if (mAuxRawImage.notNull()) - { - mHasAux = TRUE; - sAuxCount++; - } - if (finished) - { - mIsFetching = FALSE; + // Sets mRawDiscardLevel, mRawImage, mAuxRawImage + S32 fetch_discard = current_discard; + + if (mRawImage.notNull()) sRawCount--; + if (mAuxRawImage.notNull()) sAuxCount--; + // keep in mind that fetcher still might need raw image, don't modify original + bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage, + mLastHttpGetStatus); + if (mRawImage.notNull()) sRawCount++; + if (mAuxRawImage.notNull()) + { + mHasAux = TRUE; + sAuxCount++; + } + if (finished) + { + mIsFetching = FALSE; mLastFetchState = -1; - mLastPacketTimer.reset(); - } - else - { - mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); - } - - // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) - if (mRawImage.notNull()) - { + mLastPacketTimer.reset(); + } + else + { + mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); + } + + // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) + if (mRawImage.notNull()) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image"); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - mIsFetched = TRUE; - tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)); - } - mRawDiscardLevel = fetch_discard; - if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && - (current_discard < 0 || mRawDiscardLevel < current_discard)) - { + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); + if (tester) + { + mIsFetched = TRUE; + tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)); + } + mRawDiscardLevel = fetch_discard; + if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && + (current_discard < 0 || mRawDiscardLevel < current_discard)) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good"); - mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; - mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; - setTexelsPerImage(); - - if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) - { - //discard all oversized textures. - destroyRawImage(); - LL_WARNS() << "oversize, setting as missing" << LL_ENDL; - setIsMissingAsset(); - mRawDiscardLevel = INVALID_DISCARD_LEVEL; - mIsFetching = FALSE; - mLastPacketTimer.reset(); - } - else - { - mIsRawImageValid = TRUE; - addToCreateTexture(); - } + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + setTexelsPerImage(); + + if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) + { + //discard all oversized textures. + destroyRawImage(); + LL_WARNS() << "oversize, setting as missing" << LL_ENDL; + setIsMissingAsset(); + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + mIsFetching = FALSE; + mLastPacketTimer.reset(); + } + else + { + mIsRawImageValid = TRUE; + addToCreateTexture(); + } if (mBoostLevel == LLGLTexture::BOOST_ICON) { @@ -1951,802 +1951,802 @@ bool LLViewerFetchedTexture::updateFetch() } } - return TRUE; - } - else - { + return TRUE; + } + else + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed"); - // Data is ready but we don't need it - // (received it already while fetcher was writing to disk) - destroyRawImage(); - return false; // done - } - } - - if (!mIsFetching) - { - if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) - { - // We finished but received no data - if (getDiscardLevel() < 0) - { - if (getFTType() != FTT_MAP_TILE) - { - LL_WARNS() << mID - << " Fetch failure, setting as missing, decode_priority " << decode_priority - << " mRawDiscardLevel " << mRawDiscardLevel - << " current_discard " << current_discard - << " stats " << mLastHttpGetStatus.toHex() - << LL_ENDL; - } - setIsMissingAsset(); - desired_discard = -1; - } - else - { - //LL_WARNS() << mID << ": Setting min discard to " << current_discard << LL_ENDL; - if(current_discard >= 0) - { - mMinDiscardLevel = current_discard; - //desired_discard = current_discard; - } - else - { - S32 dis_level = getDiscardLevel(); - mMinDiscardLevel = dis_level; - //desired_discard = dis_level; - } - } - destroyRawImage(); - } - else if (mRawImage.notNull()) - { - // We have data, but our fetch failed to return raw data - // *TODO: FIgure out why this is happening and fix it - destroyRawImage(); - } - } - else - { - static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f. - if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME) - { - mStopFetchingTimer.reset(); - LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); - } - } - } + // Data is ready but we don't need it + // (received it already while fetcher was writing to disk) + destroyRawImage(); + return false; // done + } + } + + if (!mIsFetching) + { + if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) + { + // We finished but received no data + if (getDiscardLevel() < 0) + { + if (getFTType() != FTT_MAP_TILE) + { + LL_WARNS() << mID + << " Fetch failure, setting as missing, decode_priority " << decode_priority + << " mRawDiscardLevel " << mRawDiscardLevel + << " current_discard " << current_discard + << " stats " << mLastHttpGetStatus.toHex() + << LL_ENDL; + } + setIsMissingAsset(); + desired_discard = -1; + } + else + { + //LL_WARNS() << mID << ": Setting min discard to " << current_discard << LL_ENDL; + if(current_discard >= 0) + { + mMinDiscardLevel = current_discard; + //desired_discard = current_discard; + } + else + { + S32 dis_level = getDiscardLevel(); + mMinDiscardLevel = dis_level; + //desired_discard = dis_level; + } + } + destroyRawImage(); + } + else if (mRawImage.notNull()) + { + // We have data, but our fetch failed to return raw data + // *TODO: FIgure out why this is happening and fix it + destroyRawImage(); + } + } + else + { + static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f. + if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME) + { + mStopFetchingTimer.reset(); + LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); + } + } + } desired_discard = llmin(desired_discard, getMaxDiscardLevel()); - bool make_request = true; - if (decode_priority <= 0) - { + bool make_request = true; + if (decode_priority <= 0) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0"); - make_request = false; - } - else if(mDesiredDiscardLevel > getMaxDiscardLevel()) - { + make_request = false; + } + else if(mDesiredDiscardLevel > getMaxDiscardLevel()) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max"); - make_request = false; - } - else if (mNeedsCreateTexture || mIsMissingAsset) - { + make_request = false; + } + else if (mNeedsCreateTexture || mIsMissingAsset) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing"); - make_request = false; - } - else if (current_discard >= 0 && current_discard <= mMinDiscardLevel) - { + make_request = false; + } + else if (current_discard >= 0 && current_discard <= mMinDiscardLevel) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min"); - make_request = false; - } - else if(mCachedRawImage.notNull() // can be empty - && mCachedRawImageReady - && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) - { - make_request = false; - switchToCachedImage(); //use the cached raw data first - } - - if (make_request) - { - if (mIsFetching) - { + make_request = false; + } + else if(mCachedRawImage.notNull() // can be empty + && mCachedRawImageReady + && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) + { + make_request = false; + switchToCachedImage(); //use the cached raw data first + } + + if (make_request) + { + if (mIsFetching) + { // already requested a higher resolution mip - if (mRequestedDiscardLevel <= desired_discard) - { + if (mRequestedDiscardLevel <= desired_discard) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired"); - make_request = false; - } - } - else - { + make_request = false; + } + } + else + { // already at a higher resolution mip, don't discard - if (current_discard >= 0 && current_discard <= desired_discard) - { + if (current_discard >= 0 && current_discard <= desired_discard) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired"); - make_request = false; - } - } - } - - if (make_request) - { + make_request = false; + } + } + } + + if (make_request) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request"); - S32 w=0, h=0, c=0; - if (getDiscardLevel() >= 0) - { - w = mGLTexturep->getWidth(0); - h = mGLTexturep->getHeight(0); - c = mComponents; - } - - const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); - if (override_tex_discard_level != 0) - { - desired_discard = override_tex_discard_level; - } - - // bypass texturefetch directly by pulling from LLTextureCache - S32 fetch_request_discard = -1; + S32 w=0, h=0, c=0; + if (getDiscardLevel() >= 0) + { + w = mGLTexturep->getWidth(0); + h = mGLTexturep->getHeight(0); + c = mComponents; + } + + const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); + if (override_tex_discard_level != 0) + { + desired_discard = override_tex_discard_level; + } + + // bypass texturefetch directly by pulling from LLTextureCache + S32 fetch_request_discard = -1; fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, - w, h, c, desired_discard, needsAux(), mCanUseHTTP); - - if (fetch_request_discard >= 0) - { + w, h, c, desired_discard, needsAux(), mCanUseHTTP); + + if (fetch_request_discard >= 0) + { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created"); - mHasFetcher = TRUE; - mIsFetching = TRUE; + mHasFetcher = TRUE; + mIsFetching = TRUE; // in some cases createRequest can modify discard, as an example // bake textures are always at discard 0 mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard); - mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); - } + mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); + } // If createRequest() failed, that means one of two things: // 1. We're finishing up a request for this UUID, so we // should wait for it to complete // 2. We've failed a request for this UUID, so there is // no need to create another request - } - else if (mHasFetcher && !mIsFetching) - { - // Only delete requests that haven't received any network data - // for a while. Note - this is the normal mechanism for - // deleting requests, not just a place to handle timeouts. - const F32 FETCH_IDLE_TIME = 0.1f; - if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME) - { - LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL; - LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); - mHasFetcher = FALSE; - } - } - - return mIsFetching ? true : false; + } + else if (mHasFetcher && !mIsFetching) + { + // Only delete requests that haven't received any network data + // for a while. Note - this is the normal mechanism for + // deleting requests, not just a place to handle timeouts. + const F32 FETCH_IDLE_TIME = 0.1f; + if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME) + { + LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL; + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + mHasFetcher = FALSE; + } + } + + return mIsFetching ? true : false; } void LLViewerFetchedTexture::clearFetchedResults() { - if(mNeedsCreateTexture || mIsFetching) - { - return; - } - - cleanup(); - destroyGLTexture(); + if(mNeedsCreateTexture || mIsFetching) + { + return; + } + + cleanup(); + destroyGLTexture(); - if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate - { - mGLTexturep->forceToInvalidateGLTexture(); - } + if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate + { + mGLTexturep->forceToInvalidateGLTexture(); + } } void LLViewerFetchedTexture::forceToDeleteRequest() { - if (mHasFetcher) - { - mHasFetcher = FALSE; - mIsFetching = FALSE; - } - - resetTextureStats(); + if (mHasFetcher) + { + mHasFetcher = FALSE; + mIsFetching = FALSE; + } - mDesiredDiscardLevel = getMaxDiscardLevel() + 1; + resetTextureStats(); + + mDesiredDiscardLevel = getMaxDiscardLevel() + 1; } void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing) { - if (is_missing == mIsMissingAsset) - { - return; - } - if (is_missing) - { - if (mUrl.empty()) - { - LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL; - } - else - { - // This may or may not be an error - it is normal to have no - // map tile on an empty region, but bad if we're failing on a - // server bake texture. - if (getFTType() != FTT_MAP_TILE) - { - LL_WARNS() << mUrl << ": Marking image as missing" << LL_ENDL; - } - } - if (mHasFetcher) - { - LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); - mHasFetcher = FALSE; - mIsFetching = FALSE; - mLastPacketTimer.reset(); - mFetchState = 0; - mFetchPriority = 0; - } - } - else - { - LL_INFOS() << mID << ": un-flagging missing asset" << LL_ENDL; - } - mIsMissingAsset = is_missing; + if (is_missing == mIsMissingAsset) + { + return; + } + if (is_missing) + { + if (mUrl.empty()) + { + LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL; + } + else + { + // This may or may not be an error - it is normal to have no + // map tile on an empty region, but bad if we're failing on a + // server bake texture. + if (getFTType() != FTT_MAP_TILE) + { + LL_WARNS() << mUrl << ": Marking image as missing" << LL_ENDL; + } + } + if (mHasFetcher) + { + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + mHasFetcher = FALSE; + mIsFetching = FALSE; + mLastPacketTimer.reset(); + mFetchState = 0; + mFetchPriority = 0; + } + } + else + { + LL_INFOS() << mID << ": un-flagging missing asset" << LL_ENDL; + } + mIsMissingAsset = is_missing; } void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback, - S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata, - LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause) -{ - // - // Don't do ANYTHING here, just add it to the global callback list - // - if (mLoadedCallbackList.empty()) - { - // Put in list to call this->doLoadedCallbacks() periodically - gTextureList.mCallbackList.insert(this); - mLoadedCallbackDesiredDiscardLevel = (S8)discard_level; - } - else - { - mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level); - } - - if(mPauseLoadedCallBacks) - { - if(!pause) - { - unpauseLoadedCallbacks(src_callback_list); - } - } - else if(pause) - { - pauseLoadedCallbacks(src_callback_list); - } - - LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause); - mLoadedCallbackList.push_back(entryp); - - mNeedsAux |= needs_aux; - if(keep_imageraw) - { - mSaveRawImage = TRUE; - } - if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0) - { - if(mHasAux) - { - //trigger a refetch - forceToRefetchTexture(); - } - else - { - // We need aux data, but we've already loaded the image, and it didn't have any - LL_WARNS() << "No aux data available for callback for image:" << getID() << LL_ENDL; - } - } - mLastCallBackActiveTime = sCurrentTime ; + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata, + LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause) +{ + // + // Don't do ANYTHING here, just add it to the global callback list + // + if (mLoadedCallbackList.empty()) + { + // Put in list to call this->doLoadedCallbacks() periodically + gTextureList.mCallbackList.insert(this); + mLoadedCallbackDesiredDiscardLevel = (S8)discard_level; + } + else + { + mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level); + } + + if(mPauseLoadedCallBacks) + { + if(!pause) + { + unpauseLoadedCallbacks(src_callback_list); + } + } + else if(pause) + { + pauseLoadedCallbacks(src_callback_list); + } + + LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause); + mLoadedCallbackList.push_back(entryp); + + mNeedsAux |= needs_aux; + if(keep_imageraw) + { + mSaveRawImage = TRUE; + } + if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0) + { + if(mHasAux) + { + //trigger a refetch + forceToRefetchTexture(); + } + else + { + // We need aux data, but we've already loaded the image, and it didn't have any + LL_WARNS() << "No aux data available for callback for image:" << getID() << LL_ENDL; + } + } + mLastCallBackActiveTime = sCurrentTime ; mLastReferencedSavedRawImageTime = sCurrentTime; } void LLViewerFetchedTexture::clearCallbackEntryList() { - if(mLoadedCallbackList.empty()) - { - return; - } - - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter; - - // We never finished loading the image. Indicate failure. - // Note: this allows mLoadedCallbackUserData to be cleaned up. - entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); - iter = mLoadedCallbackList.erase(iter); - delete entryp; - } - gTextureList.mCallbackList.erase(this); - - mLoadedCallbackDesiredDiscardLevel = S8_MAX; - if(needsToSaveRawImage()) - { - destroySavedRawImage(); - } - - return; + if(mLoadedCallbackList.empty()) + { + return; + } + + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter; + + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); + iter = mLoadedCallbackList.erase(iter); + delete entryp; + } + gTextureList.mCallbackList.erase(this); + + mLoadedCallbackDesiredDiscardLevel = S8_MAX; + if(needsToSaveRawImage()) + { + destroySavedRawImage(); + } + + return; } void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list) { - if(mLoadedCallbackList.empty() || !callback_list) - { - return; - } - - S32 desired_discard = S8_MAX; - S32 desired_raw_discard = INVALID_DISCARD_LEVEL; - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter; - if(entryp->mSourceCallbackList == callback_list) - { - // We never finished loading the image. Indicate failure. - // Note: this allows mLoadedCallbackUserData to be cleaned up. - entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); - iter = mLoadedCallbackList.erase(iter); - delete entryp; - } - else - { - ++iter; - - desired_discard = llmin(desired_discard, entryp->mDesiredDiscard); - if(entryp->mNeedsImageRaw) - { - desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard); - } - } - } - - mLoadedCallbackDesiredDiscardLevel = desired_discard; - if (mLoadedCallbackList.empty()) - { - // If we have no callbacks, take us off of the image callback list. - gTextureList.mCallbackList.erase(this); - - if(needsToSaveRawImage()) - { - destroySavedRawImage(); - } - } - else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW) - { - if(desired_raw_discard != INVALID_DISCARD_LEVEL) - { - mDesiredSavedRawDiscardLevel = desired_raw_discard; - } - else - { - destroySavedRawImage(); - } - } + if(mLoadedCallbackList.empty() || !callback_list) + { + return; + } + + S32 desired_discard = S8_MAX; + S32 desired_raw_discard = INVALID_DISCARD_LEVEL; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter; + if(entryp->mSourceCallbackList == callback_list) + { + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); + iter = mLoadedCallbackList.erase(iter); + delete entryp; + } + else + { + ++iter; + + desired_discard = llmin(desired_discard, entryp->mDesiredDiscard); + if(entryp->mNeedsImageRaw) + { + desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard); + } + } + } + + mLoadedCallbackDesiredDiscardLevel = desired_discard; + if (mLoadedCallbackList.empty()) + { + // If we have no callbacks, take us off of the image callback list. + gTextureList.mCallbackList.erase(this); + + if(needsToSaveRawImage()) + { + destroySavedRawImage(); + } + } + else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW) + { + if(desired_raw_discard != INVALID_DISCARD_LEVEL) + { + mDesiredSavedRawDiscardLevel = desired_raw_discard; + } + else + { + destroySavedRawImage(); + } + } } void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list) { - if(!callback_list) -{ - mPauseLoadedCallBacks = FALSE; - return; - } - - BOOL need_raw = FALSE; - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter++; - if(entryp->mSourceCallbackList == callback_list) - { - entryp->mPaused = FALSE; - if(entryp->mNeedsImageRaw) - { - need_raw = TRUE; - } - } - } - mPauseLoadedCallBacks = FALSE ; - mLastCallBackActiveTime = sCurrentTime ; - mForceCallbackFetch = TRUE; - if(need_raw) - { - mSaveRawImage = TRUE; - } + if(!callback_list) +{ + mPauseLoadedCallBacks = FALSE; + return; + } + + BOOL need_raw = FALSE; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + if(entryp->mSourceCallbackList == callback_list) + { + entryp->mPaused = FALSE; + if(entryp->mNeedsImageRaw) + { + need_raw = TRUE; + } + } + } + mPauseLoadedCallBacks = FALSE ; + mLastCallBackActiveTime = sCurrentTime ; + mForceCallbackFetch = TRUE; + if(need_raw) + { + mSaveRawImage = TRUE; + } } void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list) { - if(!callback_list) + if(!callback_list) { - return; - } + return; + } - bool paused = true; + bool paused = true; - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter++; - if(entryp->mSourceCallbackList == callback_list) - { - entryp->mPaused = TRUE; - } - else if(!entryp->mPaused) - { - paused = false; - } - } + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + if(entryp->mSourceCallbackList == callback_list) + { + entryp->mPaused = TRUE; + } + else if(!entryp->mPaused) + { + paused = false; + } + } - if(paused) - { - mPauseLoadedCallBacks = TRUE;//when set, loaded callback is paused. - resetTextureStats(); - mSaveRawImage = FALSE; - } + if(paused) + { + mPauseLoadedCallBacks = TRUE;//when set, loaded callback is paused. + resetTextureStats(); + mSaveRawImage = FALSE; + } } bool LLViewerFetchedTexture::doLoadedCallbacks() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds - static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds - - if (mNeedsCreateTexture) - { - return false; - } - if(mPauseLoadedCallBacks) - { - destroyRawImage(); - return false; //paused - } - if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching) - { - if (mFTType == FTT_SERVER_BAKE) - { - //output some debug info - LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL; - LL_INFOS() << mUrl << LL_ENDL; - LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() << - " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL; - } - - clearCallbackEntryList() ; //remove all callbacks. - return false ; - } - - bool res = false; - - if (isMissingAsset()) - { - if (mFTType == FTT_SERVER_BAKE) - { - //output some debug info - LL_INFOS() << "baked texture: " << mID << "is missing." << LL_ENDL; - LL_INFOS() << mUrl << LL_ENDL; - } - - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter++; - // We never finished loading the image. Indicate failure. - // Note: this allows mLoadedCallbackUserData to be cleaned up. - entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); - delete entryp; - } - mLoadedCallbackList.clear(); - - // Remove ourself from the global list of textures with callbacks - gTextureList.mCallbackList.erase(this); - return false; - } - - S32 gl_discard = getDiscardLevel(); - - // If we don't have a legit GL image, set it to be lower than the worst discard level - if (gl_discard == -1) - { - gl_discard = MAX_DISCARD_LEVEL + 1; - } - - // - // Determine the quality levels of textures that we can provide to callbacks - // and whether we need to do decompression/readback to get it - // - S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard - S32 best_raw_discard = gl_discard; // Current GL quality level - S32 current_aux_discard = MAX_DISCARD_LEVEL + 1; - S32 best_aux_discard = MAX_DISCARD_LEVEL + 1; - - if (mIsRawImageValid) - { - // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels. - best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel); - best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw - current_aux_discard = llmin(current_aux_discard, best_aux_discard); - } - else - { - // We have no data at all, we need to get it - // Do this by forcing the best aux discard to be 0. - best_aux_discard = 0; - } - - - // - // See if any of the callbacks would actually run using the data that we can provide, - // and also determine if we need to perform any readbacks or decodes. - // - bool run_gl_callbacks = false; - bool run_raw_callbacks = false; - bool need_readback = false; - - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - LLLoadedCallbackEntry *entryp = *iter++; - - if (entryp->mNeedsImageRaw) - { - if (mNeedsAux) - { - // - // Need raw and auxiliary channels - // - if (entryp->mLastUsedDiscard > current_aux_discard) - { - // We have useful data, run the callbacks - run_raw_callbacks = true; - } - } - else - { - if (entryp->mLastUsedDiscard > current_raw_discard) - { - // We have useful data, just run the callbacks - run_raw_callbacks = true; - } - else if (entryp->mLastUsedDiscard > best_raw_discard) - { - // We can readback data, and then run the callbacks - need_readback = true; - run_raw_callbacks = true; - } - } - } - else - { - // Needs just GL - if (entryp->mLastUsedDiscard > gl_discard) - { - // We have enough data, run this callback requiring GL data - run_gl_callbacks = true; - } - } - } - - // - // Do a readback if required, OR start off a texture decode - // - if (need_readback && (getMaxDiscardLevel() > gl_discard)) - { - // Do a readback to get the GL data into the raw image - // We have GL data. - - destroyRawImage(); - reloadRawImage(mLoadedCallbackDesiredDiscardLevel); - llassert(mRawImage.notNull()); - llassert(!mNeedsAux || mAuxRawImage.notNull()); - } - - // - // Run raw/auxiliary data callbacks - // - if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel())) - { - // Do callbacks which require raw image data. - //LL_INFOS() << "doLoadedCallbacks raw for " << getID() << LL_ENDL; - - // Call each party interested in the raw data. - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - callback_list_t::iterator curiter = iter++; - LLLoadedCallbackEntry *entryp = *curiter; - if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel)) - { - // If we've loaded all the data there is to load or we've loaded enough - // to satisfy the interested party, then this is the last time that - // we're going to call them. - - mLastCallBackActiveTime = sCurrentTime; - if(mNeedsAux && mAuxRawImage.isNull()) - { - LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL; - } - BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE; - //LL_INFOS() << "Running callback for " << getID() << LL_ENDL; - //LL_INFOS() << mRawImage->getWidth() << "x" << mRawImage->getHeight() << LL_ENDL; - entryp->mLastUsedDiscard = mRawDiscardLevel; - entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData); - if (final) - { - iter = mLoadedCallbackList.erase(curiter); - delete entryp; - } - res = true; - } - } - } - - // - // Run GL callbacks - // - if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel())) - { - //LL_INFOS() << "doLoadedCallbacks GL for " << getID() << LL_ENDL; - - // Call the callbacks interested in GL data. - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); - iter != mLoadedCallbackList.end(); ) - { - callback_list_t::iterator curiter = iter++; - LLLoadedCallbackEntry *entryp = *curiter; - if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard)) - { - mLastCallBackActiveTime = sCurrentTime; - BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE; - entryp->mLastUsedDiscard = gl_discard; - entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData); - if (final) - { - iter = mLoadedCallbackList.erase(curiter); - delete entryp; - } - res = true; - } - } - } - - // Done with any raw image data at this point (will be re-created if we still have callbacks) - destroyRawImage(); - - // - // If we have no callbacks, take us off of the image callback list. - // - if (mLoadedCallbackList.empty()) - { - gTextureList.mCallbackList.erase(this); - } - else if(!res && mForceCallbackFetch && sCurrentTime - mLastCallBackActiveTime > MAX_IDLE_WAIT_TIME && !mIsFetching) - { - //wait for long enough but no fetching request issued, force one. - forceToRefetchTexture(mLoadedCallbackDesiredDiscardLevel, 5.f); - mForceCallbackFetch = FALSE; //fire once. - } - - return res; + static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds + static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds + + if (mNeedsCreateTexture) + { + return false; + } + if(mPauseLoadedCallBacks) + { + destroyRawImage(); + return false; //paused + } + if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching) + { + if (mFTType == FTT_SERVER_BAKE) + { + //output some debug info + LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL; + LL_INFOS() << mUrl << LL_ENDL; + LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() << + " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL; + } + + clearCallbackEntryList() ; //remove all callbacks. + return false ; + } + + bool res = false; + + if (isMissingAsset()) + { + if (mFTType == FTT_SERVER_BAKE) + { + //output some debug info + LL_INFOS() << "baked texture: " << mID << "is missing." << LL_ENDL; + LL_INFOS() << mUrl << LL_ENDL; + } + + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + // We never finished loading the image. Indicate failure. + // Note: this allows mLoadedCallbackUserData to be cleaned up. + entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData); + delete entryp; + } + mLoadedCallbackList.clear(); + + // Remove ourself from the global list of textures with callbacks + gTextureList.mCallbackList.erase(this); + return false; + } + + S32 gl_discard = getDiscardLevel(); + + // If we don't have a legit GL image, set it to be lower than the worst discard level + if (gl_discard == -1) + { + gl_discard = MAX_DISCARD_LEVEL + 1; + } + + // + // Determine the quality levels of textures that we can provide to callbacks + // and whether we need to do decompression/readback to get it + // + S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard + S32 best_raw_discard = gl_discard; // Current GL quality level + S32 current_aux_discard = MAX_DISCARD_LEVEL + 1; + S32 best_aux_discard = MAX_DISCARD_LEVEL + 1; + + if (mIsRawImageValid) + { + // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels. + best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel); + best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw + current_aux_discard = llmin(current_aux_discard, best_aux_discard); + } + else + { + // We have no data at all, we need to get it + // Do this by forcing the best aux discard to be 0. + best_aux_discard = 0; + } + + + // + // See if any of the callbacks would actually run using the data that we can provide, + // and also determine if we need to perform any readbacks or decodes. + // + bool run_gl_callbacks = false; + bool run_raw_callbacks = false; + bool need_readback = false; + + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + LLLoadedCallbackEntry *entryp = *iter++; + + if (entryp->mNeedsImageRaw) + { + if (mNeedsAux) + { + // + // Need raw and auxiliary channels + // + if (entryp->mLastUsedDiscard > current_aux_discard) + { + // We have useful data, run the callbacks + run_raw_callbacks = true; + } + } + else + { + if (entryp->mLastUsedDiscard > current_raw_discard) + { + // We have useful data, just run the callbacks + run_raw_callbacks = true; + } + else if (entryp->mLastUsedDiscard > best_raw_discard) + { + // We can readback data, and then run the callbacks + need_readback = true; + run_raw_callbacks = true; + } + } + } + else + { + // Needs just GL + if (entryp->mLastUsedDiscard > gl_discard) + { + // We have enough data, run this callback requiring GL data + run_gl_callbacks = true; + } + } + } + + // + // Do a readback if required, OR start off a texture decode + // + if (need_readback && (getMaxDiscardLevel() > gl_discard)) + { + // Do a readback to get the GL data into the raw image + // We have GL data. + + destroyRawImage(); + reloadRawImage(mLoadedCallbackDesiredDiscardLevel); + llassert(mRawImage.notNull()); + llassert(!mNeedsAux || mAuxRawImage.notNull()); + } + + // + // Run raw/auxiliary data callbacks + // + if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel())) + { + // Do callbacks which require raw image data. + //LL_INFOS() << "doLoadedCallbacks raw for " << getID() << LL_ENDL; + + // Call each party interested in the raw data. + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLLoadedCallbackEntry *entryp = *curiter; + if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel)) + { + // If we've loaded all the data there is to load or we've loaded enough + // to satisfy the interested party, then this is the last time that + // we're going to call them. + + mLastCallBackActiveTime = sCurrentTime; + if(mNeedsAux && mAuxRawImage.isNull()) + { + LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL; + } + BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE; + //LL_INFOS() << "Running callback for " << getID() << LL_ENDL; + //LL_INFOS() << mRawImage->getWidth() << "x" << mRawImage->getHeight() << LL_ENDL; + entryp->mLastUsedDiscard = mRawDiscardLevel; + entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData); + if (final) + { + iter = mLoadedCallbackList.erase(curiter); + delete entryp; + } + res = true; + } + } + } + + // + // Run GL callbacks + // + if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel())) + { + //LL_INFOS() << "doLoadedCallbacks GL for " << getID() << LL_ENDL; + + // Call the callbacks interested in GL data. + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); + iter != mLoadedCallbackList.end(); ) + { + callback_list_t::iterator curiter = iter++; + LLLoadedCallbackEntry *entryp = *curiter; + if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard)) + { + mLastCallBackActiveTime = sCurrentTime; + BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE; + entryp->mLastUsedDiscard = gl_discard; + entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData); + if (final) + { + iter = mLoadedCallbackList.erase(curiter); + delete entryp; + } + res = true; + } + } + } + + // Done with any raw image data at this point (will be re-created if we still have callbacks) + destroyRawImage(); + + // + // If we have no callbacks, take us off of the image callback list. + // + if (mLoadedCallbackList.empty()) + { + gTextureList.mCallbackList.erase(this); + } + else if(!res && mForceCallbackFetch && sCurrentTime - mLastCallBackActiveTime > MAX_IDLE_WAIT_TIME && !mIsFetching) + { + //wait for long enough but no fetching request issued, force one. + forceToRefetchTexture(mLoadedCallbackDesiredDiscardLevel, 5.f); + mForceCallbackFetch = FALSE; //fire once. + } + + return res; } //virtual void LLViewerFetchedTexture::forceImmediateUpdate() { - //only immediately update a deleted texture which is now being re-used. - if(!isDeleted()) - { - return; - } - //if already called forceImmediateUpdate() - if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize) - { - return; - } + //only immediately update a deleted texture which is now being re-used. + if(!isDeleted()) + { + return; + } + //if already called forceImmediateUpdate() + if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize) + { + return; + } - gTextureList.forceImmediateUpdate(this); - return; + gTextureList.forceImmediateUpdate(this); + return; } LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level) { - llassert(mGLTexturep.notNull()); - llassert(discard_level >= 0); - llassert(mComponents > 0); + llassert(mGLTexturep.notNull()); + llassert(discard_level >= 0); + llassert(mComponents > 0); - if (mRawImage.notNull()) - { - //mRawImage is in use by somebody else, do not delete it. - return NULL; - } + if (mRawImage.notNull()) + { + //mRawImage is in use by somebody else, do not delete it. + return NULL; + } - if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level) - { - if (mSavedRawDiscardLevel != discard_level + if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level) + { + if (mSavedRawDiscardLevel != discard_level && mBoostLevel != BOOST_ICON && mBoostLevel != BOOST_THUMBNAIL) - { - mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); - mRawImage->copy(getSavedRawImage()); - } - else - { - mRawImage = getSavedRawImage(); - } - mRawDiscardLevel = discard_level; - } - else - { - //force to fetch raw image again if cached raw image is not good enough. - if(mCachedRawDiscardLevel > discard_level) - { - mRawImage = mCachedRawImage; - mRawDiscardLevel = mCachedRawDiscardLevel; - } - else //cached raw image is good enough, copy it. - { - if(mCachedRawDiscardLevel != discard_level) - { - mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); - mRawImage->copy(mCachedRawImage); - } - else - { - mRawImage = mCachedRawImage; - } - mRawDiscardLevel = discard_level; - } - } - mIsRawImageValid = TRUE; - sRawCount++; - - return mRawImage; + { + mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); + mRawImage->copy(getSavedRawImage()); + } + else + { + mRawImage = getSavedRawImage(); + } + mRawDiscardLevel = discard_level; + } + else + { + //force to fetch raw image again if cached raw image is not good enough. + if(mCachedRawDiscardLevel > discard_level) + { + mRawImage = mCachedRawImage; + mRawDiscardLevel = mCachedRawDiscardLevel; + } + else //cached raw image is good enough, copy it. + { + if(mCachedRawDiscardLevel != discard_level) + { + mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); + mRawImage->copy(mCachedRawImage); + } + else + { + mRawImage = mCachedRawImage; + } + mRawDiscardLevel = discard_level; + } + } + mIsRawImageValid = TRUE; + sRawCount++; + + return mRawImage; } bool LLViewerFetchedTexture::needsToSaveRawImage() { - return mForceToSaveRawImage || mSaveRawImage; + return mForceToSaveRawImage || mSaveRawImage; } void LLViewerFetchedTexture::destroyRawImage() -{ +{ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if (mAuxRawImage.notNull() && !needsToSaveRawImage()) - { - sAuxCount--; - mAuxRawImage = NULL; - } - - if (mRawImage.notNull()) - { - sRawCount--; - - if(mIsRawImageValid) - { - if(needsToSaveRawImage()) - { - saveRawImage(); - } - setCachedRawImage(); - } - - mRawImage = NULL; - - mIsRawImageValid = FALSE; - mRawDiscardLevel = INVALID_DISCARD_LEVEL; - } + if (mAuxRawImage.notNull() && !needsToSaveRawImage()) + { + sAuxCount--; + mAuxRawImage = NULL; + } + + if (mRawImage.notNull()) + { + sRawCount--; + + if(mIsRawImageValid) + { + if(needsToSaveRawImage()) + { + saveRawImage(); + } + setCachedRawImage(); + } + + mRawImage = NULL; + + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + } } //use the mCachedRawImage to (re)generate the gl texture. @@ -2754,32 +2754,32 @@ void LLViewerFetchedTexture::destroyRawImage() void LLViewerFetchedTexture::switchToCachedImage() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mCachedRawImage.notNull() && + if(mCachedRawImage.notNull() && !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it - { - mRawImage = mCachedRawImage; - - if (getComponents() != mRawImage->getComponents()) - { - // We've changed the number of components, so we need to move any - // objects using this pool to a different pool. - mComponents = mRawImage->getComponents(); - mGLTexturep->setComponents(mComponents); - gTextureList.dirtyImage(this); - } - - mIsRawImageValid = TRUE; - mRawDiscardLevel = mCachedRawDiscardLevel; + { + mRawImage = mCachedRawImage; + + if (getComponents() != mRawImage->getComponents()) + { + // We've changed the number of components, so we need to move any + // objects using this pool to a different pool. + mComponents = mRawImage->getComponents(); + mGLTexturep->setComponents(mComponents); + gTextureList.dirtyImage(this); + } + + mIsRawImageValid = TRUE; + mRawDiscardLevel = mCachedRawDiscardLevel; scheduleCreateTexture(); - } + } } //cache the imageraw forcefully. -//virtual -void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) +//virtual +void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) { - if(imageraw != mRawImage.get()) + if(imageraw != mRawImage.get()) { if (mBoostLevel == LLGLTexture::BOOST_ICON) { @@ -2813,96 +2813,96 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im { mCachedRawImage = imageraw; } - mCachedRawDiscardLevel = discard_level; - mCachedRawImageReady = TRUE; - } + mCachedRawDiscardLevel = discard_level; + mCachedRawImageReady = TRUE; + } } void LLViewerFetchedTexture::setCachedRawImage() -{ +{ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mRawImage == mCachedRawImage) - { - return; - } - if(!mIsRawImageValid) - { - return; - } - - if(mCachedRawImageReady) - { - return; - } - - if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel) - { - S32 i = 0; - S32 w = mRawImage->getWidth(); - S32 h = mRawImage->getHeight(); - - S32 max_size = MAX_CACHED_RAW_IMAGE_AREA; - if(LLGLTexture::BOOST_TERRAIN == mBoostLevel) - { - max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA; - } - if(mForSculpt) - { - max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA; - mCachedRawImageReady = !mRawDiscardLevel; - } - else - { - mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)); - } - - while(((w >> i) * (h >> i)) > max_size) - { - ++i; - } - - if(i) - { - if(!(w >> i) || !(h >> i)) - { - --i; - } - - { - //make a duplicate in case somebody else is using this raw image - mRawImage = mRawImage->scaled(w >> i, h >> i); - } - } - mCachedRawImage = mRawImage; - mRawDiscardLevel += i; - mCachedRawDiscardLevel = mRawDiscardLevel; - } + if(mRawImage == mCachedRawImage) + { + return; + } + if(!mIsRawImageValid) + { + return; + } + + if(mCachedRawImageReady) + { + return; + } + + if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel) + { + S32 i = 0; + S32 w = mRawImage->getWidth(); + S32 h = mRawImage->getHeight(); + + S32 max_size = MAX_CACHED_RAW_IMAGE_AREA; + if(LLGLTexture::BOOST_TERRAIN == mBoostLevel) + { + max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA; + } + if(mForSculpt) + { + max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA; + mCachedRawImageReady = !mRawDiscardLevel; + } + else + { + mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)); + } + + while(((w >> i) * (h >> i)) > max_size) + { + ++i; + } + + if(i) + { + if(!(w >> i) || !(h >> i)) + { + --i; + } + + { + //make a duplicate in case somebody else is using this raw image + mRawImage = mRawImage->scaled(w >> i, h >> i); + } + } + mCachedRawImage = mRawImage; + mRawDiscardLevel += i; + mCachedRawDiscardLevel = mRawDiscardLevel; + } } void LLViewerFetchedTexture::checkCachedRawSculptImage() { - if(mCachedRawImageReady && mCachedRawDiscardLevel > 0) - { - if(getDiscardLevel() != 0) - { - mCachedRawImageReady = FALSE; - } - else if(isForSculptOnly()) - { - resetTextureStats(); //do not update this image any more. - } - } + if(mCachedRawImageReady && mCachedRawDiscardLevel > 0) + { + if(getDiscardLevel() != 0) + { + mCachedRawImageReady = FALSE; + } + else if(isForSculptOnly()) + { + resetTextureStats(); //do not update this image any more. + } + } } -void LLViewerFetchedTexture::saveRawImage() +void LLViewerFetchedTexture::saveRawImage() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel)) - { - return; - } + if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel)) + { + return; + } - mSavedRawDiscardLevel = mRawDiscardLevel; + mSavedRawDiscardLevel = mRawDiscardLevel; if (mBoostLevel == LLGLTexture::BOOST_ICON) { S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS; @@ -2936,102 +2936,102 @@ void LLViewerFetchedTexture::saveRawImage() mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); } - if(mForceToSaveRawImage && mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel) - { - mForceToSaveRawImage = FALSE; - } + if(mForceToSaveRawImage && mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel) + { + mForceToSaveRawImage = FALSE; + } - mLastReferencedSavedRawImageTime = sCurrentTime; + mLastReferencedSavedRawImageTime = sCurrentTime; } -//force to refetch the texture to the discard level +//force to refetch the texture to the discard level void LLViewerFetchedTexture::forceToRefetchTexture(S32 desired_discard, F32 kept_time) { - if(mForceToSaveRawImage) - { - desired_discard = llmin(desired_discard, mDesiredSavedRawDiscardLevel); - kept_time = llmax(kept_time, mKeptSavedRawImageTime); - } - - //trigger a new fetch. - mForceToSaveRawImage = TRUE ; - mDesiredSavedRawDiscardLevel = desired_discard ; - mKeptSavedRawImageTime = kept_time ; - mLastReferencedSavedRawImageTime = sCurrentTime ; - mSavedRawImage = NULL ; - mSavedRawDiscardLevel = -1 ; -} - -void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time) -{ - mKeptSavedRawImageTime = kept_time; - mLastReferencedSavedRawImageTime = sCurrentTime; - - if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard) - { - return; //raw imge is ready. - } - - if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard) - { - mForceToSaveRawImage = TRUE; - mDesiredSavedRawDiscardLevel = desired_discard; - - //copy from the cached raw image if exists. - if(mCachedRawImage.notNull() && mRawImage.isNull() ) - { - mRawImage = mCachedRawImage; - mRawDiscardLevel = mCachedRawDiscardLevel; - - saveRawImage(); - - mRawImage = NULL; - mRawDiscardLevel = INVALID_DISCARD_LEVEL; - } - } + if(mForceToSaveRawImage) + { + desired_discard = llmin(desired_discard, mDesiredSavedRawDiscardLevel); + kept_time = llmax(kept_time, mKeptSavedRawImageTime); + } + + //trigger a new fetch. + mForceToSaveRawImage = TRUE ; + mDesiredSavedRawDiscardLevel = desired_discard ; + mKeptSavedRawImageTime = kept_time ; + mLastReferencedSavedRawImageTime = sCurrentTime ; + mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1 ; +} + +void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time) +{ + mKeptSavedRawImageTime = kept_time; + mLastReferencedSavedRawImageTime = sCurrentTime; + + if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard) + { + return; //raw imge is ready. + } + + if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard) + { + mForceToSaveRawImage = TRUE; + mDesiredSavedRawDiscardLevel = desired_discard; + + //copy from the cached raw image if exists. + if(mCachedRawImage.notNull() && mRawImage.isNull() ) + { + mRawImage = mCachedRawImage; + mRawDiscardLevel = mCachedRawDiscardLevel; + + saveRawImage(); + + mRawImage = NULL; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + } + } } void LLViewerFetchedTexture::destroySavedRawImage() { - if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime) - { - return; //keep the saved raw image. - } + if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime) + { + return; //keep the saved raw image. + } + + mForceToSaveRawImage = FALSE; + mSaveRawImage = FALSE; + + clearCallbackEntryList(); - mForceToSaveRawImage = FALSE; - mSaveRawImage = FALSE; + mSavedRawImage = NULL ; + mForceToSaveRawImage = FALSE ; + mSaveRawImage = FALSE ; + mSavedRawDiscardLevel = -1 ; + mDesiredSavedRawDiscardLevel = -1 ; + mLastReferencedSavedRawImageTime = 0.0f ; + mKeptSavedRawImageTime = 0.f ; - clearCallbackEntryList(); - - mSavedRawImage = NULL ; - mForceToSaveRawImage = FALSE ; - mSaveRawImage = FALSE ; - mSavedRawDiscardLevel = -1 ; - mDesiredSavedRawDiscardLevel = -1 ; - mLastReferencedSavedRawImageTime = 0.0f ; - mKeptSavedRawImageTime = 0.f ; - - if(mAuxRawImage.notNull()) - { - sAuxCount--; - mAuxRawImage = NULL; - } + if(mAuxRawImage.notNull()) + { + sAuxCount--; + mAuxRawImage = NULL; + } } -LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() +LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() { - mLastReferencedSavedRawImageTime = sCurrentTime; + mLastReferencedSavedRawImageTime = sCurrentTime; - return mSavedRawImage; + return mSavedRawImage; } - + BOOL LLViewerFetchedTexture::hasSavedRawImage() const { - return mSavedRawImage.notNull(); + return mSavedRawImage.notNull(); } - + F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const -{ - return sCurrentTime - mLastReferencedSavedRawImageTime; +{ + return sCurrentTime - mLastReferencedSavedRawImageTime; } //---------------------------------------------------------------------------------------------- @@ -3042,33 +3042,33 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const //start of LLViewerLODTexture //---------------------------------------------------------------------------------------------- LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps) - : LLViewerFetchedTexture(id, f_type, host, usemipmaps) + : LLViewerFetchedTexture(id, f_type, host, usemipmaps) { - init(TRUE); + init(TRUE); } LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps) - : LLViewerFetchedTexture(url, f_type, id, usemipmaps) + : LLViewerFetchedTexture(url, f_type, id, usemipmaps) { - init(TRUE); + init(TRUE); } void LLViewerLODTexture::init(bool firstinit) { - mTexelsPerImage = 64.f*64.f; - mDiscardVirtualSize = 0.f; - mCalculatedDiscardLevel = -1.f; + mTexelsPerImage = 64.f*64.f; + mDiscardVirtualSize = 0.f; + mCalculatedDiscardLevel = -1.f; } -//virtual +//virtual S8 LLViewerLODTexture::getType() const { - return LLViewerTexture::LOD_TEXTURE; + return LLViewerTexture::LOD_TEXTURE; } bool LLViewerLODTexture::isUpdateFrozen() { - return LLViewerTexture::sFreezeImageUpdates; + return LLViewerTexture::sFreezeImageUpdates; } // This is gauranteed to get called periodically for every texture @@ -3076,9 +3076,9 @@ bool LLViewerLODTexture::isUpdateFrozen() void LLViewerLODTexture::processTextureStats() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - updateVirtualSize(); - - static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); + updateVirtualSize(); + + static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); { // restrict texture resolution to download based on RenderMaxTextureResolution static LLCachedControl max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); @@ -3088,26 +3088,26 @@ void LLViewerLODTexture::processTextureStats() mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res); } - if (textures_fullres) - { - mDesiredDiscardLevel = 0; - } - // Generate the request priority and render priority - else if (mDontDiscard || !mUseMipMaps) - { - mDesiredDiscardLevel = 0; - if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) - mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 - } - else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) - { - // If the image has not been significantly visible in a while, we don't want it - mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); - } - else if (!mFullWidth || !mFullHeight) - { - mDesiredDiscardLevel = getMaxDiscardLevel(); - } + if (textures_fullres) + { + mDesiredDiscardLevel = 0; + } + // Generate the request priority and render priority + else if (mDontDiscard || !mUseMipMaps) + { + mDesiredDiscardLevel = 0; + if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) + mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 + } + else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) + { + // If the image has not been significantly visible in a while, we don't want it + mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); + } + else if (!mFullWidth || !mFullHeight) + { + mDesiredDiscardLevel = getMaxDiscardLevel(); + } else { //static const F64 log_2 = log(2.0); @@ -3164,7 +3164,7 @@ void LLViewerLODTexture::processTextureStats() // S32 current_discard = getDiscardLevel(); - if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED && + if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED && current_discard >= 0) { if (current_discard < (mDesiredDiscardLevel-1) && !mForceToSaveRawImage) @@ -3173,19 +3173,19 @@ void LLViewerLODTexture::processTextureStats() } } - if (isUpdateFrozen() // we are out of memory and nearing max allowed bias - && mBoostLevel < LLGLTexture::BOOST_SCULPTED - && mDesiredDiscardLevel < current_discard) - { - // stop requesting more - mDesiredDiscardLevel = current_discard; - } - } + if (isUpdateFrozen() // we are out of memory and nearing max allowed bias + && mBoostLevel < LLGLTexture::BOOST_SCULPTED + && mDesiredDiscardLevel < current_discard) + { + // stop requesting more + mDesiredDiscardLevel = current_discard; + } + } - if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) - { - mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel); - } + if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) + { + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel); + } // decay max virtual size over time mMaxVirtualSize *= 0.8f; @@ -3200,19 +3200,19 @@ void LLViewerLODTexture::processTextureStats() bool LLViewerLODTexture::scaleDown() { - if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel()) - { - switchToCachedImage(); + if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel()) + { + switchToCachedImage(); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->setStablizingTime(); - } + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); + if (tester) + { + tester->setStablizingTime(); + } - return true; - } - return false; + return true; + } + return false; } //---------------------------------------------------------------------------------------------- //end of LLViewerLODTexture @@ -3225,182 +3225,182 @@ bool LLViewerLODTexture::scaleDown() void LLViewerMediaTexture::updateClass() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static const F32 MAX_INACTIVE_TIME = 30.f; + static const F32 MAX_INACTIVE_TIME = 30.f; #if 0 - //force to play media. - gSavedSettings.setBOOL("AudioStreamingMedia", true); + //force to play media. + gSavedSettings.setBOOL("AudioStreamingMedia", true); #endif - for(media_map_t::iterator iter = sMediaMap.begin(); iter != sMediaMap.end(); ) - { - LLViewerMediaTexture* mediap = iter->second; - - if(mediap->getNumRefs() == 1) //one reference by sMediaMap - { - // - //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture. - // - if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) - { - media_map_t::iterator cur = iter++; - sMediaMap.erase(cur); - continue; - } - } - ++iter; - } -} - -//static -void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id) -{ - LLViewerMediaTexture* media_tex = findMediaTexture(media_id); - if(media_tex) - { - media_tex->invalidateMediaImpl(); - } + for(media_map_t::iterator iter = sMediaMap.begin(); iter != sMediaMap.end(); ) + { + LLViewerMediaTexture* mediap = iter->second; + + if(mediap->getNumRefs() == 1) //one reference by sMediaMap + { + // + //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture. + // + if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) + { + media_map_t::iterator cur = iter++; + sMediaMap.erase(cur); + continue; + } + } + ++iter; + } +} + +//static +void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id) +{ + LLViewerMediaTexture* media_tex = findMediaTexture(media_id); + if(media_tex) + { + media_tex->invalidateMediaImpl(); + } } //static void LLViewerMediaTexture::cleanUpClass() { - sMediaMap.clear(); + sMediaMap.clear(); } //static LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id) { - media_map_t::iterator iter = sMediaMap.find(media_id); - if(iter == sMediaMap.end()) - { - return NULL; - } + media_map_t::iterator iter = sMediaMap.find(media_id); + if(iter == sMediaMap.end()) + { + return NULL; + } - LLViewerMediaTexture* media_tex = iter->second; - media_tex->setMediaImpl(); - media_tex->getLastReferencedTimer()->reset(); + LLViewerMediaTexture* media_tex = iter->second; + media_tex->setMediaImpl(); + media_tex->getLastReferencedTimer()->reset(); - return media_tex; + return media_tex; } -LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) - : LLViewerTexture(id, usemipmaps), - mMediaImplp(NULL), - mUpdateVirtualSizeTime(0) +LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) + : LLViewerTexture(id, usemipmaps), + mMediaImplp(NULL), + mUpdateVirtualSizeTime(0) { - sMediaMap.insert(std::make_pair(id, this)); + sMediaMap.insert(std::make_pair(id, this)); - mGLTexturep = gl_image; + mGLTexturep = gl_image; - if(mGLTexturep.isNull()) - { - generateGLTexture(); - } + if(mGLTexturep.isNull()) + { + generateGLTexture(); + } - mGLTexturep->setAllowCompression(false); + mGLTexturep->setAllowCompression(false); - mGLTexturep->setNeedsAlphaAndPickMask(FALSE); + mGLTexturep->setNeedsAlphaAndPickMask(FALSE); - mIsPlaying = FALSE; + mIsPlaying = FALSE; - setMediaImpl(); + setMediaImpl(); - setCategory(LLGLTexture::MEDIA); - - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); - if(tex) //this media is a parcel media for tex. - { - tex->setParcelMedia(this); - } -} + setCategory(LLGLTexture::MEDIA); -//virtual -LLViewerMediaTexture::~LLViewerMediaTexture() -{ - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); - if(tex) //this media is a parcel media for tex. - { - tex->setParcelMedia(NULL); - } + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); + if(tex) //this media is a parcel media for tex. + { + tex->setParcelMedia(this); + } } -void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) +//virtual +LLViewerMediaTexture::~LLViewerMediaTexture() { - llassert(mGLTexturep.notNull()); + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); + if(tex) //this media is a parcel media for tex. + { + tex->setParcelMedia(NULL); + } +} + +void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) +{ + llassert(mGLTexturep.notNull()); - mUseMipMaps = usemipmaps; - getLastReferencedTimer()->reset(); - mGLTexturep->setUseMipMaps(mUseMipMaps); - mGLTexturep->setNeedsAlphaAndPickMask(FALSE); + mUseMipMaps = usemipmaps; + getLastReferencedTimer()->reset(); + mGLTexturep->setUseMipMaps(mUseMipMaps); + mGLTexturep->setNeedsAlphaAndPickMask(FALSE); } -void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap) +void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap) { - mUseMipMaps = mipmap; + mUseMipMaps = mipmap; - if(mGLTexturep.notNull()) - { - mGLTexturep->setUseMipMaps(mipmap); - } + if(mGLTexturep.notNull()) + { + mGLTexturep->setUseMipMaps(mipmap); + } } -//virtual +//virtual S8 LLViewerMediaTexture::getType() const { - return LLViewerTexture::MEDIA_TEXTURE; + return LLViewerTexture::MEDIA_TEXTURE; } -void LLViewerMediaTexture::invalidateMediaImpl() +void LLViewerMediaTexture::invalidateMediaImpl() { - mMediaImplp = NULL; + mMediaImplp = NULL; } void LLViewerMediaTexture::setMediaImpl() { - if(!mMediaImplp) - { - mMediaImplp = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mID); - } + if(!mMediaImplp) + { + mMediaImplp = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mID); + } } //return true if all faces to reference to this media texture are found -//Note: mMediaFaceList is valid only for the current instant +//Note: mMediaFaceList is valid only for the current instant // because it does not check the face validity after the current frame. BOOL LLViewerMediaTexture::findFaces() -{ - mMediaFaceList.clear(); - - BOOL ret = TRUE; - - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); - if(tex) //this media is a parcel media for tex. - { - for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) - { - const ll_face_list_t* face_list = tex->getFaceList(ch); - U32 end = tex->getNumFaces(ch); - for(U32 i = 0; i < end; i++) - { - if ((*face_list)[i]->isMediaAllowed()) - { - mMediaFaceList.push_back((*face_list)[i]); - } - } - } - } - - if(!mMediaImplp) - { - return TRUE; - } - - //for media on a face. - const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList(); - std::list< LLVOVolume* >::const_iterator iter = obj_list->begin(); - for(; iter != obj_list->end(); ++iter) - { - LLVOVolume* obj = *iter; +{ + mMediaFaceList.clear(); + + BOOL ret = TRUE; + + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); + if(tex) //this media is a parcel media for tex. + { + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + const ll_face_list_t* face_list = tex->getFaceList(ch); + U32 end = tex->getNumFaces(ch); + for(U32 i = 0; i < end; i++) + { + if ((*face_list)[i]->isMediaAllowed()) + { + mMediaFaceList.push_back((*face_list)[i]); + } + } + } + } + + if(!mMediaImplp) + { + return TRUE; + } + + //for media on a face. + const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList(); + std::list< LLVOVolume* >::const_iterator iter = obj_list->begin(); + for(; iter != obj_list->end(); ++iter) + { + LLVOVolume* obj = *iter; if (obj->isDead()) { // Isn't supposed to happen, objects are supposed to detach @@ -3418,343 +3418,343 @@ BOOL LLViewerMediaTexture::findFaces() continue; } - S32 face_id = -1; - S32 num_faces = obj->mDrawable->getNumFaces(); - while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces) - { - LLFace* facep = obj->mDrawable->getFace(face_id); - if(facep) - { - mMediaFaceList.push_back(facep); - } - else - { - ret = FALSE; - } - } - } - - return ret; + S32 face_id = -1; + S32 num_faces = obj->mDrawable->getNumFaces(); + while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces) + { + LLFace* facep = obj->mDrawable->getFace(face_id); + if(facep) + { + mMediaFaceList.push_back(facep); + } + else + { + ret = FALSE; + } + } + } + + return ret; } void LLViewerMediaTexture::initVirtualSize() { - if(mIsPlaying) - { - return; - } - - findFaces(); - for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) - { - addTextureStats((*iter)->getVirtualSize()); - } -} - -void LLViewerMediaTexture::addMediaToFace(LLFace* facep) -{ - if(facep) - { - facep->setHasMedia(true); - } - if(!mIsPlaying) - { - return; //no need to add the face because the media is not in playing. - } - - switchTexture(LLRender::DIFFUSE_MAP, facep); -} - -void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep) -{ - if(!facep) - { - return; - } - facep->setHasMedia(false); - - if(!mIsPlaying) - { - return; //no need to remove the face because the media is not in playing. - } - - mIsPlaying = FALSE; //set to remove the media from the face. - switchTexture(LLRender::DIFFUSE_MAP, facep); - mIsPlaying = TRUE; //set the flag back. - - if(getTotalNumFaces() < 1) //no face referencing to this media - { - stopPlaying(); - } -} - -//virtual -void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep) -{ - LLViewerTexture::addFace(ch, facep); - - const LLTextureEntry* te = facep->getTextureEntry(); - if(te && te->getID().notNull()) - { - LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); - if(tex) - { - mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it. - return; - } - } - - //check if it is a parcel media - if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID) - { - mTextureList.push_back(facep->getTexture()); //a parcel media. - return; - } - - if(te && te->getID().notNull()) //should have a texture - { + if(mIsPlaying) + { + return; + } + + findFaces(); + for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) + { + addTextureStats((*iter)->getVirtualSize()); + } +} + +void LLViewerMediaTexture::addMediaToFace(LLFace* facep) +{ + if(facep) + { + facep->setHasMedia(true); + } + if(!mIsPlaying) + { + return; //no need to add the face because the media is not in playing. + } + + switchTexture(LLRender::DIFFUSE_MAP, facep); +} + +void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep) +{ + if(!facep) + { + return; + } + facep->setHasMedia(false); + + if(!mIsPlaying) + { + return; //no need to remove the face because the media is not in playing. + } + + mIsPlaying = FALSE; //set to remove the media from the face. + switchTexture(LLRender::DIFFUSE_MAP, facep); + mIsPlaying = TRUE; //set the flag back. + + if(getTotalNumFaces() < 1) //no face referencing to this media + { + stopPlaying(); + } +} + +//virtual +void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep) +{ + LLViewerTexture::addFace(ch, facep); + + const LLTextureEntry* te = facep->getTextureEntry(); + if(te && te->getID().notNull()) + { + LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); + if(tex) + { + mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it. + return; + } + } + + //check if it is a parcel media + if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID) + { + mTextureList.push_back(facep->getTexture()); //a parcel media. + return; + } + + if(te && te->getID().notNull()) //should have a texture + { LL_WARNS_ONCE() << "The face's texture " << te->getID() << " is not valid. Face must have a valid texture before media texture." << LL_ENDL; // This might break the object, but it likely isn't a 'recoverable' situation. LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(te->getID()); mTextureList.push_back(tex); - } -} - -//virtual -void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep) -{ - LLViewerTexture::removeFace(ch, facep); - - const LLTextureEntry* te = facep->getTextureEntry(); - if(te && te->getID().notNull()) - { - LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); - if(tex) - { - for(std::list< LLPointer >::iterator iter = mTextureList.begin(); - iter != mTextureList.end(); ++iter) - { - if(*iter == tex) - { - mTextureList.erase(iter); //decrease the reference number for tex by one. - return; - } - } - - std::vector te_list; - - for (U32 ch = 0; ch < 3; ++ch) - { - // - //we have some trouble here: the texture of the face is changed. - //we need to find the former texture, and remove it from the list to avoid memory leaking. - - llassert(mNumFaces[ch] <= mFaceList[ch].size()); - - for(U32 j = 0; j < mNumFaces[ch]; j++) - { - te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use. - } - } - - if (te_list.empty()) - { - mTextureList.clear(); - return; - } - - S32 end = te_list.size(); - - for(std::list< LLPointer >::iterator iter = mTextureList.begin(); - iter != mTextureList.end(); ++iter) - { - S32 i = 0; - - for(i = 0; i < end; i++) - { - if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use. - { - te_list[i] = NULL; - break; - } - } - if(i == end) //no hit for this texture, remove it. - { - mTextureList.erase(iter); //decrease the reference number for tex by one. - return; - } - } - } - } - - //check if it is a parcel media - for(std::list< LLPointer >::iterator iter = mTextureList.begin(); - iter != mTextureList.end(); ++iter) - { - if((*iter)->getID() == mID) - { - mTextureList.erase(iter); //decrease the reference number for tex by one. - return; - } - } - - if(te && te->getID().notNull()) //should have a texture but none found - { - LL_ERRS() << "mTextureList texture reference number is corrupted. Texture id: " << te->getID() << " List size: " << (U32)mTextureList.size() << LL_ENDL; - } + } +} + +//virtual +void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep) +{ + LLViewerTexture::removeFace(ch, facep); + + const LLTextureEntry* te = facep->getTextureEntry(); + if(te && te->getID().notNull()) + { + LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); + if(tex) + { + for(std::list< LLPointer >::iterator iter = mTextureList.begin(); + iter != mTextureList.end(); ++iter) + { + if(*iter == tex) + { + mTextureList.erase(iter); //decrease the reference number for tex by one. + return; + } + } + + std::vector te_list; + + for (U32 ch = 0; ch < 3; ++ch) + { + // + //we have some trouble here: the texture of the face is changed. + //we need to find the former texture, and remove it from the list to avoid memory leaking. + + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + + for(U32 j = 0; j < mNumFaces[ch]; j++) + { + te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use. + } + } + + if (te_list.empty()) + { + mTextureList.clear(); + return; + } + + S32 end = te_list.size(); + + for(std::list< LLPointer >::iterator iter = mTextureList.begin(); + iter != mTextureList.end(); ++iter) + { + S32 i = 0; + + for(i = 0; i < end; i++) + { + if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use. + { + te_list[i] = NULL; + break; + } + } + if(i == end) //no hit for this texture, remove it. + { + mTextureList.erase(iter); //decrease the reference number for tex by one. + return; + } + } + } + } + + //check if it is a parcel media + for(std::list< LLPointer >::iterator iter = mTextureList.begin(); + iter != mTextureList.end(); ++iter) + { + if((*iter)->getID() == mID) + { + mTextureList.erase(iter); //decrease the reference number for tex by one. + return; + } + } + + if(te && te->getID().notNull()) //should have a texture but none found + { + LL_ERRS() << "mTextureList texture reference number is corrupted. Texture id: " << te->getID() << " List size: " << (U32)mTextureList.size() << LL_ENDL; + } } void LLViewerMediaTexture::stopPlaying() { - // Don't stop the media impl playing here -- this breaks non-inworld media (login screen, search, and media browser). -// if(mMediaImplp) -// { -// mMediaImplp->stop(); -// } - mIsPlaying = FALSE; + // Don't stop the media impl playing here -- this breaks non-inworld media (login screen, search, and media browser). +// if(mMediaImplp) +// { +// mMediaImplp->stop(); +// } + mIsPlaying = FALSE; } void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep) { - if(facep) - { - //check if another media is playing on this face. - if(facep->getTexture() && facep->getTexture() != this - && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE) - { - if(mID == facep->getTexture()->getID()) //this is a parcel media - { - return; //let the prim media win. - } - } - - if(mIsPlaying) //old textures switch to the media texture - { - facep->switchTexture(ch, this); - } - else //switch to old textures. - { - const LLTextureEntry* te = facep->getTextureEntry(); - if(te) - { - LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; - if(!tex && te->getID() != mID)//try parcel media. - { - tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); - } - if(!tex) - { - tex = LLViewerFetchedTexture::sDefaultImagep; - } - facep->switchTexture(ch, tex); - } - } - } -} - -void LLViewerMediaTexture::setPlaying(BOOL playing) -{ - if(!mMediaImplp) - { - return; - } - if(!playing && !mIsPlaying) - { - return; //media is already off - } - - if(playing == mIsPlaying && !mMediaImplp->isUpdated()) - { - return; //nothing has changed since last time. - } - - mIsPlaying = playing; - if(mIsPlaying) //is about to play this media - { - if(findFaces()) - { - //about to update all faces. - mMediaImplp->setUpdated(FALSE); - } - - if(mMediaFaceList.empty())//no face pointing to this media - { - stopPlaying(); - return; - } - - for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) - { - switchTexture(LLRender::DIFFUSE_MAP, *iter); - } - } - else //stop playing this media - { - U32 ch = LLRender::DIFFUSE_MAP; - - llassert(mNumFaces[ch] <= mFaceList[ch].size()); - for(U32 i = mNumFaces[ch]; i; i--) - { - switchTexture(ch, mFaceList[ch][i - 1]); //current face could be removed in this function. - } - } - return; -} - -//virtual -F32 LLViewerMediaTexture::getMaxVirtualSize() -{ - if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime) - { - return mMaxVirtualSize; - } - mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount(); - - if(!mMaxVirtualSizeResetCounter) - { - addTextureStats(0.f, FALSE);//reset - } - - if(mIsPlaying) //media is playing - { - for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) - { - llassert(mNumFaces[ch] <= mFaceList[ch].size()); - for(U32 i = 0; i < mNumFaces[ch]; i++) - { - LLFace* facep = mFaceList[ch][i]; - if(facep->getDrawable()->isRecentlyVisible()) - { - addTextureStats(facep->getVirtualSize()); - } - } - } - } - else //media is not in playing - { - findFaces(); - - if(!mMediaFaceList.empty()) - { - for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) - { - LLFace* facep = *iter; - if(facep->getDrawable()->isRecentlyVisible()) - { - addTextureStats(facep->getVirtualSize()); - } - } - } - } - - if(mMaxVirtualSizeResetCounter > 0) - { - mMaxVirtualSizeResetCounter--; - } - reorganizeFaceList(); - reorganizeVolumeList(); - - return mMaxVirtualSize; + if(facep) + { + //check if another media is playing on this face. + if(facep->getTexture() && facep->getTexture() != this + && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE) + { + if(mID == facep->getTexture()->getID()) //this is a parcel media + { + return; //let the prim media win. + } + } + + if(mIsPlaying) //old textures switch to the media texture + { + facep->switchTexture(ch, this); + } + else //switch to old textures. + { + const LLTextureEntry* te = facep->getTextureEntry(); + if(te) + { + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; + if(!tex && te->getID() != mID)//try parcel media. + { + tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); + } + if(!tex) + { + tex = LLViewerFetchedTexture::sDefaultImagep; + } + facep->switchTexture(ch, tex); + } + } + } +} + +void LLViewerMediaTexture::setPlaying(BOOL playing) +{ + if(!mMediaImplp) + { + return; + } + if(!playing && !mIsPlaying) + { + return; //media is already off + } + + if(playing == mIsPlaying && !mMediaImplp->isUpdated()) + { + return; //nothing has changed since last time. + } + + mIsPlaying = playing; + if(mIsPlaying) //is about to play this media + { + if(findFaces()) + { + //about to update all faces. + mMediaImplp->setUpdated(FALSE); + } + + if(mMediaFaceList.empty())//no face pointing to this media + { + stopPlaying(); + return; + } + + for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) + { + switchTexture(LLRender::DIFFUSE_MAP, *iter); + } + } + else //stop playing this media + { + U32 ch = LLRender::DIFFUSE_MAP; + + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + for(U32 i = mNumFaces[ch]; i; i--) + { + switchTexture(ch, mFaceList[ch][i - 1]); //current face could be removed in this function. + } + } + return; +} + +//virtual +F32 LLViewerMediaTexture::getMaxVirtualSize() +{ + if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime) + { + return mMaxVirtualSize; + } + mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount(); + + if(!mMaxVirtualSizeResetCounter) + { + addTextureStats(0.f, FALSE);//reset + } + + if(mIsPlaying) //media is playing + { + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + for(U32 i = 0; i < mNumFaces[ch]; i++) + { + LLFace* facep = mFaceList[ch][i]; + if(facep->getDrawable()->isRecentlyVisible()) + { + addTextureStats(facep->getVirtualSize()); + } + } + } + } + else //media is not in playing + { + findFaces(); + + if(!mMediaFaceList.empty()) + { + for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) + { + LLFace* facep = *iter; + if(facep->getDrawable()->isRecentlyVisible()) + { + addTextureStats(facep->getVirtualSize()); + } + } + } + } + + if(mMaxVirtualSizeResetCounter > 0) + { + mMaxVirtualSizeResetCounter--; + } + reorganizeFaceList(); + reorganizeVolumeList(); + + return mMaxVirtualSize; } //---------------------------------------------------------------------------------------------- //end of LLViewerMediaTexture @@ -3763,391 +3763,391 @@ F32 LLViewerMediaTexture::getMaxVirtualSize() //---------------------------------------------------------------------------------------------- //start of LLTexturePipelineTester //---------------------------------------------------------------------------------------------- -LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName) -{ - addMetric("TotalBytesLoaded"); - addMetric("TotalBytesLoadedFromCache"); - addMetric("TotalBytesLoadedForLargeImage"); - addMetric("TotalBytesLoadedForSculpties"); - addMetric("StartFetchingTime"); - addMetric("TotalGrayTime"); - addMetric("TotalStablizingTime"); - addMetric("StartTimeLoadingSculpties"); - addMetric("EndTimeLoadingSculpties"); - - addMetric("Time"); - addMetric("TotalBytesBound"); - addMetric("TotalBytesBoundForLargeImage"); - addMetric("PercentageBytesBound"); - - mTotalBytesLoaded = (S32Bytes)0; - mTotalBytesLoadedFromCache = (S32Bytes)0; - mTotalBytesLoadedForLargeImage = (S32Bytes)0; - mTotalBytesLoadedForSculpties = (S32Bytes)0; - - reset(); +LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName) +{ + addMetric("TotalBytesLoaded"); + addMetric("TotalBytesLoadedFromCache"); + addMetric("TotalBytesLoadedForLargeImage"); + addMetric("TotalBytesLoadedForSculpties"); + addMetric("StartFetchingTime"); + addMetric("TotalGrayTime"); + addMetric("TotalStablizingTime"); + addMetric("StartTimeLoadingSculpties"); + addMetric("EndTimeLoadingSculpties"); + + addMetric("Time"); + addMetric("TotalBytesBound"); + addMetric("TotalBytesBoundForLargeImage"); + addMetric("PercentageBytesBound"); + + mTotalBytesLoaded = (S32Bytes)0; + mTotalBytesLoadedFromCache = (S32Bytes)0; + mTotalBytesLoadedForLargeImage = (S32Bytes)0; + mTotalBytesLoadedForSculpties = (S32Bytes)0; + + reset(); } LLTexturePipelineTester::~LLTexturePipelineTester() { - LLViewerTextureManager::sTesterp = NULL; + LLViewerTextureManager::sTesterp = NULL; } void LLTexturePipelineTester::update() { - mLastTotalBytesUsed = mTotalBytesUsed; - mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage; - mTotalBytesUsed = (S32Bytes)0; - mTotalBytesUsedForLargeImage = (S32Bytes)0; - - if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty - { - if(mPause) - { - //start a new fetching session - reset(); - mStartFetchingTime = LLImageGL::sLastFrameTime; - mPause = FALSE; - } - - //update total gray time - if(mUsingDefaultTexture) - { - mUsingDefaultTexture = FALSE; - mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime; - } - - //update the stablizing timer. - updateStablizingTime(); - - outputTestResults(); - } - else if(!mPause) - { - //stop the current fetching session - mPause = TRUE; - outputTestResults(); - reset(); - } -} - -void LLTexturePipelineTester::reset() -{ - mPause = TRUE; - - mUsingDefaultTexture = FALSE; - mStartStablizingTime = 0.0f; - mEndStablizingTime = 0.0f; - - mTotalBytesUsed = (S32Bytes)0; - mTotalBytesUsedForLargeImage = (S32Bytes)0; - mLastTotalBytesUsed = (S32Bytes)0; - mLastTotalBytesUsedForLargeImage = (S32Bytes)0; - - mStartFetchingTime = 0.0f; - - mTotalGrayTime = 0.0f; - mTotalStablizingTime = 0.0f; - - mStartTimeLoadingSculpties = 1.0f; - mEndTimeLoadingSculpties = 0.0f; -} - -//virtual -void LLTexturePipelineTester::outputTestRecord(LLSD *sd) -{ - std::string currentLabel = getCurrentLabelName(); - (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value(); - (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value(); - (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value(); - (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value(); - - (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime; - (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime; - (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime; - - (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties; - (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties; - - (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime; - (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value(); - (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value(); - (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded); -} - -void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) -{ - U32Bytes mem_size = imagep->getTextureMemory(); - mTotalBytesUsed += mem_size; - - if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents())) - { - mTotalBytesUsedForLargeImage += mem_size; - } -} - -void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) -{ - U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize(); - mTotalBytesLoaded += data_size; - - if(from_cache) - { - mTotalBytesLoadedFromCache += data_size; - } - - if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents())) - { - mTotalBytesLoadedForLargeImage += data_size; - } - - if(imagep->forSculpt()) - { - mTotalBytesLoadedForSculpties += data_size; - - if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties) - { - mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime; - } - mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime; - } + mLastTotalBytesUsed = mTotalBytesUsed; + mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage; + mTotalBytesUsed = (S32Bytes)0; + mTotalBytesUsedForLargeImage = (S32Bytes)0; + + if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty + { + if(mPause) + { + //start a new fetching session + reset(); + mStartFetchingTime = LLImageGL::sLastFrameTime; + mPause = FALSE; + } + + //update total gray time + if(mUsingDefaultTexture) + { + mUsingDefaultTexture = FALSE; + mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime; + } + + //update the stablizing timer. + updateStablizingTime(); + + outputTestResults(); + } + else if(!mPause) + { + //stop the current fetching session + mPause = TRUE; + outputTestResults(); + reset(); + } +} + +void LLTexturePipelineTester::reset() +{ + mPause = TRUE; + + mUsingDefaultTexture = FALSE; + mStartStablizingTime = 0.0f; + mEndStablizingTime = 0.0f; + + mTotalBytesUsed = (S32Bytes)0; + mTotalBytesUsedForLargeImage = (S32Bytes)0; + mLastTotalBytesUsed = (S32Bytes)0; + mLastTotalBytesUsedForLargeImage = (S32Bytes)0; + + mStartFetchingTime = 0.0f; + + mTotalGrayTime = 0.0f; + mTotalStablizingTime = 0.0f; + + mStartTimeLoadingSculpties = 1.0f; + mEndTimeLoadingSculpties = 0.0f; +} + +//virtual +void LLTexturePipelineTester::outputTestRecord(LLSD *sd) +{ + std::string currentLabel = getCurrentLabelName(); + (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value(); + (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value(); + (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value(); + (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value(); + + (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime; + (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime; + (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime; + + (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties; + (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties; + + (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime; + (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value(); + (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value(); + (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded); +} + +void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) +{ + U32Bytes mem_size = imagep->getTextureMemory(); + mTotalBytesUsed += mem_size; + + if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents())) + { + mTotalBytesUsedForLargeImage += mem_size; + } +} + +void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) +{ + U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize(); + mTotalBytesLoaded += data_size; + + if(from_cache) + { + mTotalBytesLoadedFromCache += data_size; + } + + if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents())) + { + mTotalBytesLoadedForLargeImage += data_size; + } + + if(imagep->forSculpt()) + { + mTotalBytesLoadedForSculpties += data_size; + + if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties) + { + mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime; + } + mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime; + } } void LLTexturePipelineTester::updateGrayTextureBinding() { - mUsingDefaultTexture = TRUE; + mUsingDefaultTexture = TRUE; } void LLTexturePipelineTester::setStablizingTime() { - if(mStartStablizingTime <= mStartFetchingTime) - { - mStartStablizingTime = LLImageGL::sLastFrameTime; - } - mEndStablizingTime = LLImageGL::sLastFrameTime; + if(mStartStablizingTime <= mStartFetchingTime) + { + mStartStablizingTime = LLImageGL::sLastFrameTime; + } + mEndStablizingTime = LLImageGL::sLastFrameTime; } void LLTexturePipelineTester::updateStablizingTime() { - if(mStartStablizingTime > mStartFetchingTime) - { - F32 t = mEndStablizingTime - mStartStablizingTime; - - if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO) - { - //already stablized - mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime; - - //cancel the timer - mStartStablizingTime = 0.f; - mEndStablizingTime = 0.f; - } - else - { - mTotalStablizingTime = t; - } - } - mTotalStablizingTime = 0.f; -} - -//virtual -void LLTexturePipelineTester::compareTestSessions(llofstream* os) -{ - LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast(mBaseSessionp); - LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast(mCurrentSessionp); - if(!base_sessionp || !current_sessionp) - { - LL_ERRS() << "type of test session does not match!" << LL_ENDL; - } - - //compare and output the comparison - *os << llformat("%s\n", getTesterName().c_str()); - *os << llformat("AggregateResults\n"); - - compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime); - compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); - compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties); - compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties); - - compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded); - compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache); - compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage); - compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties); - - *os << llformat("InstantResults\n"); - S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter); - for(S32 i = 0; i < size; i++) - { - *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime); - - compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond, - current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - - compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond, - current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - - compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond, - current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - - if(size < base_sessionp->mInstantPerformanceListCounter) - { - for(S32 i = size; i < base_sessionp->mInstantPerformanceListCounter; i++) - { - *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime); - - *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - } - else if(size < current_sessionp->mInstantPerformanceListCounter) - { - for(S32 i = size; i < current_sessionp->mInstantPerformanceListCounter; i++) - { - *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime); - - *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - } -} - -//virtual + if(mStartStablizingTime > mStartFetchingTime) + { + F32 t = mEndStablizingTime - mStartStablizingTime; + + if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO) + { + //already stablized + mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime; + + //cancel the timer + mStartStablizingTime = 0.f; + mEndStablizingTime = 0.f; + } + else + { + mTotalStablizingTime = t; + } + } + mTotalStablizingTime = 0.f; +} + +//virtual +void LLTexturePipelineTester::compareTestSessions(llofstream* os) +{ + LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast(mBaseSessionp); + LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast(mCurrentSessionp); + if(!base_sessionp || !current_sessionp) + { + LL_ERRS() << "type of test session does not match!" << LL_ENDL; + } + + //compare and output the comparison + *os << llformat("%s\n", getTesterName().c_str()); + *os << llformat("AggregateResults\n"); + + compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime); + compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); + compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties); + compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties); + + compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded); + compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache); + compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage); + compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties); + + *os << llformat("InstantResults\n"); + S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter); + for(S32 i = 0; i < size; i++) + { + *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime); + + compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond, + current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); + + compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond, + current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); + + compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond, + current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); + } + + if(size < base_sessionp->mInstantPerformanceListCounter) + { + for(S32 i = size; i < base_sessionp->mInstantPerformanceListCounter; i++) + { + *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime); + + *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); + *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); + *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); + } + } + else if(size < current_sessionp->mInstantPerformanceListCounter) + { + for(S32 i = size; i < current_sessionp->mInstantPerformanceListCounter; i++) + { + *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime); + + *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); + *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); + *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); + } + } +} + +//virtual LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) { - LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession(); - if(!sessionp) - { - return NULL; - } - - F32 total_gray_time = 0.f; - F32 total_stablizing_time = 0.f; - F32 total_loading_sculpties_time = 0.f; - - F32 start_fetching_time = -1.f; - F32 start_fetching_sculpties_time = 0.f; - - F32 last_time = 0.0f; - S32 frame_count = 0; - - sessionp->mInstantPerformanceListCounter = 0; - sessionp->mInstantPerformanceList.resize(128); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; - - //load a session - std::string currentLabel = getCurrentLabelName(); - BOOL in_log = (*log).has(currentLabel); - while (in_log) - { - LLSD::String label = currentLabel; - - if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size()) - { - sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128); - } - - //time - F32 start_time = (*log)[label]["StartFetchingTime"].asReal(); - F32 cur_time = (*log)[label]["Time"].asReal(); - if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while - { - sessionp->mTotalGrayTime += total_gray_time; - sessionp->mTotalStablizingTime += total_stablizing_time; - - sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; - sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; - - start_fetching_time = start_time; - total_gray_time = 0.f; - total_stablizing_time = 0.f; - total_loading_sculpties_time = 0.f; - } - else - { - total_gray_time = (*log)[label]["TotalGrayTime"].asReal(); - total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal(); - - total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal(); - if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f) - { - start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal(); - } - } - - //total loaded bytes - sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger(); - sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger(); - sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger(); - sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger(); - - //instant metrics - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond += - (*log)[label]["TotalBytesBound"].asInteger(); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond += - (*log)[label]["TotalBytesBoundForLargeImage"].asInteger(); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond += - (*log)[label]["PercentageBytesBound"].asReal(); - frame_count++; - if(cur_time - last_time >= 1.0f) - { - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time; - - frame_count = 0; - last_time = cur_time; - sessionp->mInstantPerformanceListCounter++; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; - } - // Next label - incrementCurrentCount(); - currentLabel = getCurrentLabelName(); - in_log = (*log).has(currentLabel); - } - - sessionp->mTotalGrayTime += total_gray_time; - sessionp->mTotalStablizingTime += total_stablizing_time; - - if(sessionp->mStartTimeLoadingSculpties < 0.f) - { - sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; - } - sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; - - return sessionp; -} - -LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession() -{ - reset(); -} -LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession() -{ -} -void LLTexturePipelineTester::LLTextureTestSession::reset() -{ - mTotalGrayTime = 0.0f; - mTotalStablizingTime = 0.0f; - - mStartTimeLoadingSculpties = 0.0f; - mTotalTimeLoadingSculpties = 0.0f; - - mTotalBytesLoaded = 0; - mTotalBytesLoadedFromCache = 0; - mTotalBytesLoadedForLargeImage = 0; - mTotalBytesLoadedForSculpties = 0; - - mInstantPerformanceListCounter = 0; + LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession(); + if(!sessionp) + { + return NULL; + } + + F32 total_gray_time = 0.f; + F32 total_stablizing_time = 0.f; + F32 total_loading_sculpties_time = 0.f; + + F32 start_fetching_time = -1.f; + F32 start_fetching_sculpties_time = 0.f; + + F32 last_time = 0.0f; + S32 frame_count = 0; + + sessionp->mInstantPerformanceListCounter = 0; + sessionp->mInstantPerformanceList.resize(128); + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; + + //load a session + std::string currentLabel = getCurrentLabelName(); + BOOL in_log = (*log).has(currentLabel); + while (in_log) + { + LLSD::String label = currentLabel; + + if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size()) + { + sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128); + } + + //time + F32 start_time = (*log)[label]["StartFetchingTime"].asReal(); + F32 cur_time = (*log)[label]["Time"].asReal(); + if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while + { + sessionp->mTotalGrayTime += total_gray_time; + sessionp->mTotalStablizingTime += total_stablizing_time; + + sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; + sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; + + start_fetching_time = start_time; + total_gray_time = 0.f; + total_stablizing_time = 0.f; + total_loading_sculpties_time = 0.f; + } + else + { + total_gray_time = (*log)[label]["TotalGrayTime"].asReal(); + total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal(); + + total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal(); + if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f) + { + start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal(); + } + } + + //total loaded bytes + sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger(); + sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger(); + sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger(); + sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger(); + + //instant metrics + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond += + (*log)[label]["TotalBytesBound"].asInteger(); + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond += + (*log)[label]["TotalBytesBoundForLargeImage"].asInteger(); + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond += + (*log)[label]["PercentageBytesBound"].asReal(); + frame_count++; + if(cur_time - last_time >= 1.0f) + { + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time; + + frame_count = 0; + last_time = cur_time; + sessionp->mInstantPerformanceListCounter++; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; + sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; + } + // Next label + incrementCurrentCount(); + currentLabel = getCurrentLabelName(); + in_log = (*log).has(currentLabel); + } + + sessionp->mTotalGrayTime += total_gray_time; + sessionp->mTotalStablizingTime += total_stablizing_time; + + if(sessionp->mStartTimeLoadingSculpties < 0.f) + { + sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; + } + sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; + + return sessionp; +} + +LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession() +{ + reset(); +} +LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession() +{ +} +void LLTexturePipelineTester::LLTextureTestSession::reset() +{ + mTotalGrayTime = 0.0f; + mTotalStablizingTime = 0.0f; + + mStartTimeLoadingSculpties = 0.0f; + mTotalTimeLoadingSculpties = 0.0f; + + mTotalBytesLoaded = 0; + mTotalBytesLoadedFromCache = 0; + mTotalBytesLoadedForLargeImage = 0; + mTotalBytesLoadedForSculpties = 0; + + mInstantPerformanceListCounter = 0; } //---------------------------------------------------------------------------------------------- //end of LLTexturePipelineTester diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 52b2f19ada..b1983445a6 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -1,30 +1,30 @@ -/** +/** * @file llviewertexture.h * @brief Object for managing images and their textures * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_LLVIEWERTEXTURE_H +#ifndef LL_LLVIEWERTEXTURE_H #define LL_LLVIEWERTEXTURE_H #include "llatomic.h" @@ -54,7 +54,7 @@ class LLViewerMediaTexture ; class LLTexturePipelineTester ; -typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); +typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); class LLFileSystem; class LLMessageSystem; @@ -68,26 +68,26 @@ public: typedef std::set< LLTextureKey > source_callback_list_t; public: - LLLoadedCallbackEntry(loaded_callback_func cb, - S32 discard_level, - BOOL need_imageraw, // Needs image raw for the callback - void* userdata, - source_callback_list_t* src_callback_list, - LLViewerFetchedTexture* target, - BOOL pause); - ~LLLoadedCallbackEntry(); - void removeTexture(LLViewerFetchedTexture* tex) ; - - loaded_callback_func mCallback; - S32 mLastUsedDiscard; - S32 mDesiredDiscard; - BOOL mNeedsImageRaw; - BOOL mPaused; - void* mUserData; - source_callback_list_t* mSourceCallbackList; - + LLLoadedCallbackEntry(loaded_callback_func cb, + S32 discard_level, + BOOL need_imageraw, // Needs image raw for the callback + void* userdata, + source_callback_list_t* src_callback_list, + LLViewerFetchedTexture* target, + BOOL pause); + ~LLLoadedCallbackEntry(); + void removeTexture(LLViewerFetchedTexture* tex) ; + + loaded_callback_func mCallback; + S32 mLastUsedDiscard; + S32 mDesiredDiscard; + BOOL mNeedsImageRaw; + BOOL mPaused; + void* mUserData; + source_callback_list_t* mSourceCallbackList; + public: - static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ; + static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ; }; class LLTextureBar; @@ -95,163 +95,163 @@ class LLTextureBar; class LLViewerTexture : public LLGLTexture { public: - enum - { - LOCAL_TEXTURE, - MEDIA_TEXTURE, - DYNAMIC_TEXTURE, - FETCHED_TEXTURE, - LOD_TEXTURE, - ATLAS_TEXTURE, - INVALID_TEXTURE_TYPE - }; + enum + { + LOCAL_TEXTURE, + MEDIA_TEXTURE, + DYNAMIC_TEXTURE, + FETCHED_TEXTURE, + LOD_TEXTURE, + ATLAS_TEXTURE, + INVALID_TEXTURE_TYPE + }; - typedef std::vector ll_face_list_t; - typedef std::vector ll_volume_list_t; + typedef std::vector ll_face_list_t; + typedef std::vector ll_volume_list_t; protected: - virtual ~LLViewerTexture(); - LOG_CLASS(LLViewerTexture); - -public: - static void initClass(); - static void updateClass(); - - LLViewerTexture(BOOL usemipmaps = TRUE); - LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; - LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; - LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; - - virtual S8 getType() const; - virtual BOOL isMissingAsset() const ; - virtual void dump(); // debug info to LL_INFOS() - + virtual ~LLViewerTexture(); + LOG_CLASS(LLViewerTexture); + +public: + static void initClass(); + static void updateClass(); + + LLViewerTexture(BOOL usemipmaps = TRUE); + LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; + LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual S8 getType() const; + virtual BOOL isMissingAsset() const ; + virtual void dump(); // debug info to LL_INFOS() + virtual bool isViewerMediaTexture() const { return false; } - /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; - /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; - /*virtual*/ void forceImmediateUpdate() ; - /*virtual*/ bool isActiveFetching(); - - /*virtual*/ const LLUUID& getID() const { return mID; } - virtual void setBoostLevel(S32 level); - S32 getBoostLevel() { return mBoostLevel; } - void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } - S32 getTextureListType() { return mTextureListType; } - - void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; - void resetTextureStats(); - void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;} - void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} - S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; } - - virtual F32 getMaxVirtualSize() ; - - LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} - - S32 getFullWidth() const { return mFullWidth; } - S32 getFullHeight() const { return mFullHeight; } - /*virtual*/ void setKnownDrawSize(S32 width, S32 height); - - virtual void addFace(U32 channel, LLFace* facep) ; - virtual void removeFace(U32 channel, LLFace* facep) ; - S32 getTotalNumFaces() const; - S32 getNumFaces(U32 ch) const; - const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];} - - virtual void addVolume(U32 channel, LLVOVolume* volumep); - virtual void removeVolume(U32 channel, LLVOVolume* volumep); - S32 getNumVolumes(U32 channel) const; - const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } - - - virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; - BOOL isLargeImage() ; - - void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} - BOOL hasParcelMedia() const { return mParcelMedia != NULL;} - LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} - - /*virtual*/ void updateBindStatsForTester() ; + /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; + /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; + /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ bool isActiveFetching(); + + /*virtual*/ const LLUUID& getID() const { return mID; } + virtual void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } + void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } + S32 getTextureListType() { return mTextureListType; } + + void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; + void resetTextureStats(); + void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;} + void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} + S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; } + + virtual F32 getMaxVirtualSize() ; + + LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} + + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } + /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + + virtual void addFace(U32 channel, LLFace* facep) ; + virtual void removeFace(U32 channel, LLFace* facep) ; + S32 getTotalNumFaces() const; + S32 getNumFaces(U32 ch) const; + const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];} + + virtual void addVolume(U32 channel, LLVOVolume* volumep); + virtual void removeVolume(U32 channel, LLVOVolume* volumep); + S32 getNumVolumes(U32 channel) const; + const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } + + + virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + BOOL isLargeImage() ; + + void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} + BOOL hasParcelMedia() const { return mParcelMedia != NULL;} + LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} + + /*virtual*/ void updateBindStatsForTester() ; protected: - void cleanup() ; - void init(bool firstinit) ; - void reorganizeFaceList() ; - void reorganizeVolumeList(); + void cleanup() ; + void init(bool firstinit) ; + void reorganizeFaceList() ; + void reorganizeVolumeList(); private: - friend class LLBumpImageList; - friend class LLUIImageList; + friend class LLBumpImageList; + friend class LLUIImageList; - virtual void switchToCachedImage(); - - static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); + virtual void switchToCachedImage(); + + static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); public: static bool isMemoryForTextureLow(); protected: friend class LLViewerTextureList; - LLUUID mID; - S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList + LLUUID mID; + S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList - mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need? - mutable S32 mMaxVirtualSizeResetCounter; - mutable S32 mMaxVirtualSizeResetInterval; - LLFrameTimer mLastReferencedTimer; + mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need? + mutable S32 mMaxVirtualSizeResetCounter; + mutable S32 mMaxVirtualSizeResetInterval; + LLFrameTimer mLastReferencedTimer; - ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture - U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS]; - LLFrameTimer mLastFaceListUpdateTimer ; + ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture + U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS]; + LLFrameTimer mLastFaceListUpdateTimer ; - ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; - U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; - LLFrameTimer mLastVolumeListUpdateTimer; + ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; + U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; + LLFrameTimer mLastVolumeListUpdateTimer; - //do not use LLPointer here. - LLViewerMediaTexture* mParcelMedia ; + //do not use LLPointer here. + LLViewerMediaTexture* mParcelMedia ; - LL::WorkQueue::weak_t mMainQueue; - LL::WorkQueue::weak_t mImageQueue; + LL::WorkQueue::weak_t mMainQueue; + LL::WorkQueue::weak_t mImageQueue; public: - static const U32 sCurrentFileVersion; - static S32 sImageCount; - static S32 sRawCount; - static S32 sAuxCount; - static LLFrameTimer sEvaluationTimer; - static F32 sDesiredDiscardBias; - static F32 sDesiredDiscardScale; - static S32 sMaxSculptRez ; - static U32 sMinLargeImageSize ; - static U32 sMaxSmallImageSize ; - static bool sFreezeImageUpdates; - static F32 sCurrentTime ; - - enum EDebugTexels - { - DEBUG_TEXELS_OFF, - DEBUG_TEXELS_CURRENT, - DEBUG_TEXELS_DESIRED, - DEBUG_TEXELS_FULL - }; - - static EDebugTexels sDebugTexelsMode; - - static LLPointer sNullImagep; // Null texture for non-textured objects. - static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) - static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) + static const U32 sCurrentFileVersion; + static S32 sImageCount; + static S32 sRawCount; + static S32 sAuxCount; + static LLFrameTimer sEvaluationTimer; + static F32 sDesiredDiscardBias; + static F32 sDesiredDiscardScale; + static S32 sMaxSculptRez ; + static U32 sMinLargeImageSize ; + static U32 sMaxSmallImageSize ; + static bool sFreezeImageUpdates; + static F32 sCurrentTime ; + + enum EDebugTexels + { + DEBUG_TEXELS_OFF, + DEBUG_TEXELS_CURRENT, + DEBUG_TEXELS_DESIRED, + DEBUG_TEXELS_FULL + }; + + static EDebugTexels sDebugTexelsMode; + + static LLPointer sNullImagep; // Null texture for non-textured objects. + static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) + static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) }; enum FTType { - FTT_UNKNOWN = -1, - FTT_DEFAULT = 0, // standard texture fetched by id. - FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. - FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. - FTT_MAP_TILE, // tiles are fetched from map server directly. - FTT_LOCAL_FILE // fetch directly from a local file. + FTT_UNKNOWN = -1, + FTT_DEFAULT = 0, // standard texture fetched by id. + FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. + FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. + FTT_MAP_TILE, // tiles are fetched from map server directly. + FTT_LOCAL_FILE // fetch directly from a local file. }; const std::string& fttype_to_string(const FTType& fttype); @@ -263,269 +263,269 @@ const std::string& fttype_to_string(const FTType& fttype); // class LLViewerFetchedTexture : public LLViewerTexture { - friend class LLTextureBar; // debug info only - friend class LLTextureView; // debug info only + friend class LLTextureBar; // debug info only + friend class LLTextureView; // debug info only protected: - /*virtual*/ ~LLViewerFetchedTexture(); + /*virtual*/ ~LLViewerFetchedTexture(); public: - LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); - LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); - LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); + LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); + LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); public: - - struct Compare - { - // lhs < rhs - bool operator()(const LLPointer &lhs, const LLPointer &rhs) const - { - const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; - const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; - - // greater priority is "less" - const F32 lpriority = lhsp->mMaxVirtualSize; - const F32 rpriority = rhsp->mMaxVirtualSize; - if (lpriority > rpriority) // higher priority - return true; - if (lpriority < rpriority) - return false; - return lhsp < rhsp; - } - }; + + struct Compare + { + // lhs < rhs + bool operator()(const LLPointer &lhs, const LLPointer &rhs) const + { + const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; + const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; + + // greater priority is "less" + const F32 lpriority = lhsp->mMaxVirtualSize; + const F32 rpriority = rhsp->mMaxVirtualSize; + if (lpriority > rpriority) // higher priority + return true; + if (lpriority < rpriority) + return false; + return lhsp < rhsp; + } + }; public: - /*virtual*/ S8 getType() const override; - FTType getFTType() const; - /*virtual*/ void forceImmediateUpdate() override; - /*virtual*/ void dump() override; - - // Set callbacks to get called when the image gets updated with higher - // resolution versions. - void setLoadedCallback(loaded_callback_func cb, - S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, - void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE); - bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } - void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - bool doLoadedCallbacks(); - void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - void clearCallbackEntryList() ; - - void addToCreateTexture(); + /*virtual*/ S8 getType() const override; + FTType getFTType() const; + /*virtual*/ void forceImmediateUpdate() override; + /*virtual*/ void dump() override; + + // Set callbacks to get called when the image gets updated with higher + // resolution versions. + void setLoadedCallback(loaded_callback_func cb, + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, + void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE); + bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } + void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + bool doLoadedCallbacks(); + void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + void clearCallbackEntryList() ; + + void addToCreateTexture(); //call to determine if createTexture is necessary BOOL preCreateTexture(S32 usename = 0); - // ONLY call from LLViewerTextureList or ImageGL background thread - BOOL createTexture(S32 usename = 0); + // ONLY call from LLViewerTextureList or ImageGL background thread + BOOL createTexture(S32 usename = 0); void postCreateTexture(); void scheduleCreateTexture(); - void destroyTexture() ; + void destroyTexture() ; - virtual void processTextureStats() ; + virtual void processTextureStats() ; - BOOL needsAux() const { return mNeedsAux; } + BOOL needsAux() const { return mNeedsAux; } - // Host we think might have this image, used for baked av textures. - void setTargetHost(LLHost host) { mTargetHost = host; } - LLHost getTargetHost() const { return mTargetHost; } - - void updateVirtualSize() ; + // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } + LLHost getTargetHost() const { return mTargetHost; } - S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } - void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + void updateVirtualSize() ; + + S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } + void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } void setBoostLevel(S32 level) override; - bool updateFetch(); - bool setDebugFetching(S32 debug_level); - bool isInDebug() const { return mInDebug; } + bool updateFetch(); + bool setDebugFetching(S32 debug_level); + bool isInDebug() const { return mInDebug; } + + void setUnremovable(BOOL value) { mUnremovable = value; } + bool isUnremovable() const { return mUnremovable; } - void setUnremovable(BOOL value) { mUnremovable = value; } - bool isUnremovable() const { return mUnremovable; } - - void clearFetchedResults(); //clear all fetched results, for debug use. + void clearFetchedResults(); //clear all fetched results, for debug use. - // Override the computation of discard levels if we know the exact output - // size of the image. Used for UI textures to not decode, even if we have - // more data. - /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override; + // Override the computation of discard levels if we know the exact output + // size of the image. Used for UI textures to not decode, even if we have + // more data. + /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override; // Set the debug text of all Viewer Objects associated with this texture // to the specified text void setDebugText(const std::string& text); - void setIsMissingAsset(BOOL is_missing = true); - /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; } - - // returns dimensions of original image for local files (before power of two scaling) - // and returns 0 for all asset system images - S32 getOriginalWidth() { return mOrigWidth; } - S32 getOriginalHeight() { return mOrigHeight; } - - BOOL isInImageList() const {return mInImageList ;} - void setInImageList(BOOL flag) {mInImageList = flag ;} - - LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} - - U32 getFetchPriority() const { return mFetchPriority ;} - F32 getDownloadProgress() const {return mDownloadProgress ;} - - LLImageRaw* reloadRawImage(S8 discard_level) ; - void destroyRawImage(); - bool needsToSaveRawImage(); - - const std::string& getUrl() const {return mUrl;} - //--------------- - BOOL isDeleted() ; - BOOL isInactive() ; - BOOL isDeletionCandidate(); - void setDeletionCandidate() ; - void setInactive() ; - BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } - //--------------- - - void setForSculpt(); - BOOL forSculpt() const {return mForSculpt;} - BOOL isForSculptOnly() const; - - //raw image management - void checkCachedRawSculptImage() ; - LLImageRaw* getRawImage()const { return mRawImage ;} - S32 getRawImageLevel() const {return mRawDiscardLevel;} - LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} - S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} - BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;} - BOOL isRawImageValid()const { return mIsRawImageValid ; } - void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; - /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override; - void destroySavedRawImage() ; - LLImageRaw* getSavedRawImage() ; - BOOL hasSavedRawImage() const ; - F32 getElapsedLastReferencedSavedRawImageTime() const ; - BOOL isFullyLoaded() const; - - BOOL hasFetcher() const { return mHasFetcher;} - bool isFetching() const { return mIsFetching;} - void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} - - void forceToDeleteRequest(); - void loadFromFastCache(); - void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } - bool isInFastCacheList() { return mInFastCacheList; } - - /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline. + void setIsMissingAsset(BOOL is_missing = true); + /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; } + + // returns dimensions of original image for local files (before power of two scaling) + // and returns 0 for all asset system images + S32 getOriginalWidth() { return mOrigWidth; } + S32 getOriginalHeight() { return mOrigHeight; } + + BOOL isInImageList() const {return mInImageList ;} + void setInImageList(BOOL flag) {mInImageList = flag ;} + + LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} + + U32 getFetchPriority() const { return mFetchPriority ;} + F32 getDownloadProgress() const {return mDownloadProgress ;} + + LLImageRaw* reloadRawImage(S8 discard_level) ; + void destroyRawImage(); + bool needsToSaveRawImage(); + + const std::string& getUrl() const {return mUrl;} + //--------------- + BOOL isDeleted() ; + BOOL isInactive() ; + BOOL isDeletionCandidate(); + void setDeletionCandidate() ; + void setInactive() ; + BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } + //--------------- + + void setForSculpt(); + BOOL forSculpt() const {return mForSculpt;} + BOOL isForSculptOnly() const; + + //raw image management + void checkCachedRawSculptImage() ; + LLImageRaw* getRawImage()const { return mRawImage ;} + S32 getRawImageLevel() const {return mRawDiscardLevel;} + LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} + S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} + BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;} + BOOL isRawImageValid()const { return mIsRawImageValid ; } + void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; + /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override; + void destroySavedRawImage() ; + LLImageRaw* getSavedRawImage() ; + BOOL hasSavedRawImage() const ; + F32 getElapsedLastReferencedSavedRawImageTime() const ; + BOOL isFullyLoaded() const; + + BOOL hasFetcher() const { return mHasFetcher;} + bool isFetching() const { return mIsFetching;} + void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} + + void forceToDeleteRequest(); + void loadFromFastCache(); + void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } + bool isInFastCacheList() { return mInFastCacheList; } + + /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline. protected: - /*virtual*/ void switchToCachedImage() override; - S32 getCurrentDiscardLevelForFetching() ; - void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); + /*virtual*/ void switchToCachedImage() override; + S32 getCurrentDiscardLevelForFetching() ; + void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); private: - void init(bool firstinit) ; - void cleanup() ; + void init(bool firstinit) ; + void cleanup() ; - void saveRawImage() ; - void setCachedRawImage() ; + void saveRawImage() ; + void setCachedRawImage() ; - //for atlas - void resetFaceAtlas() ; - void invalidateAtlas(BOOL rebuild_geom) ; - BOOL insertToAtlas() ; + //for atlas + void resetFaceAtlas() ; + void invalidateAtlas(BOOL rebuild_geom) ; + BOOL insertToAtlas() ; private: - BOOL mFullyLoaded; - BOOL mInDebug; - BOOL mUnremovable; - BOOL mInFastCacheList; - BOOL mForceCallbackFetch; - -protected: - std::string mLocalFileName; - - S32 mOrigWidth; - S32 mOrigHeight; - - // Override the computation of discard levels if we know the exact output size of the image. - // Used for UI textures to not decode, even if we have more data. - S32 mKnownDrawWidth; - S32 mKnownDrawHeight; - BOOL mKnownDrawSizeChanged ; - std::string mUrl; - - S32 mRequestedDiscardLevel; - F32 mRequestedDownloadPriority; - S32 mFetchState; + BOOL mFullyLoaded; + BOOL mInDebug; + BOOL mUnremovable; + BOOL mInFastCacheList; + BOOL mForceCallbackFetch; + +protected: + std::string mLocalFileName; + + S32 mOrigWidth; + S32 mOrigHeight; + + // Override the computation of discard levels if we know the exact output size of the image. + // Used for UI textures to not decode, even if we have more data. + S32 mKnownDrawWidth; + S32 mKnownDrawHeight; + BOOL mKnownDrawSizeChanged ; + std::string mUrl; + + S32 mRequestedDiscardLevel; + F32 mRequestedDownloadPriority; + S32 mFetchState; S32 mLastFetchState = -1; // DEBUG - U32 mFetchPriority; - F32 mDownloadProgress; - F32 mFetchDeltaTime; - F32 mRequestDeltaTime; - S32 mMinDiscardLevel; - S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space - S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have - - S8 mNeedsAux; // We need to decode the auxiliary channels - S8 mHasAux; // We have aux channels - S8 mDecodingAux; // Are we decoding high components - S8 mIsRawImageValid; - S8 mHasFetcher; // We've made a fecth request - S8 mIsFetching; // Fetch request is active - bool mCanUseHTTP; //This texture can be fetched through http if true. - LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture. - - FTType mFTType; // What category of image is this - map tile, server bake, etc? - mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. - - typedef std::list callback_list_t; - S8 mLoadedCallbackDesiredDiscardLevel; - BOOL mPauseLoadedCallBacks; - callback_list_t mLoadedCallbackList; - F32 mLastCallBackActiveTime; - - LLPointer mRawImage; - S32 mRawDiscardLevel = -1; - - // Used ONLY for cloth meshes right now. Make SURE you know what you're - // doing if you use it for anything else! - djs - LLPointer mAuxRawImage; - - //keep a copy of mRawImage for some special purposes - //when mForceToSaveRawImage is set. - BOOL mForceToSaveRawImage ; - BOOL mSaveRawImage; - LLPointer mSavedRawImage; - S32 mSavedRawDiscardLevel; - S32 mDesiredSavedRawDiscardLevel; - F32 mLastReferencedSavedRawImageTime ; - F32 mKeptSavedRawImageTime ; - - //a small version of the copy of the raw image (<= 64 * 64) - LLPointer mCachedRawImage; - S32 mCachedRawDiscardLevel; - BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit. - - LLHost mTargetHost; // if invalid, just request from agent's simulator - - // Timers - LLFrameTimer mLastPacketTimer; // Time since last packet. - LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f. - - BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) - // This needs to be atomic, since it is written both in the main thread - // and in the GL image worker thread... HB - LLAtomicBool mNeedsCreateTexture; - - BOOL mForSculpt ; //a flag if the texture is used as sculpt data. - BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. + U32 mFetchPriority; + F32 mDownloadProgress; + F32 mFetchDeltaTime; + F32 mRequestDeltaTime; + S32 mMinDiscardLevel; + S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space + S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have + + S8 mNeedsAux; // We need to decode the auxiliary channels + S8 mHasAux; // We have aux channels + S8 mDecodingAux; // Are we decoding high components + S8 mIsRawImageValid; + S8 mHasFetcher; // We've made a fecth request + S8 mIsFetching; // Fetch request is active + bool mCanUseHTTP; //This texture can be fetched through http if true. + LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture. + + FTType mFTType; // What category of image is this - map tile, server bake, etc? + mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. + + typedef std::list callback_list_t; + S8 mLoadedCallbackDesiredDiscardLevel; + BOOL mPauseLoadedCallBacks; + callback_list_t mLoadedCallbackList; + F32 mLastCallBackActiveTime; + + LLPointer mRawImage; + S32 mRawDiscardLevel = -1; + + // Used ONLY for cloth meshes right now. Make SURE you know what you're + // doing if you use it for anything else! - djs + LLPointer mAuxRawImage; + + //keep a copy of mRawImage for some special purposes + //when mForceToSaveRawImage is set. + BOOL mForceToSaveRawImage ; + BOOL mSaveRawImage; + LLPointer mSavedRawImage; + S32 mSavedRawDiscardLevel; + S32 mDesiredSavedRawDiscardLevel; + F32 mLastReferencedSavedRawImageTime ; + F32 mKeptSavedRawImageTime ; + + //a small version of the copy of the raw image (<= 64 * 64) + LLPointer mCachedRawImage; + S32 mCachedRawDiscardLevel; + BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit. + + LLHost mTargetHost; // if invalid, just request from agent's simulator + + // Timers + LLFrameTimer mLastPacketTimer; // Time since last packet. + LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f. + + BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) + // This needs to be atomic, since it is written both in the main thread + // and in the GL image worker thread... HB + LLAtomicBool mNeedsCreateTexture; + + BOOL mForSculpt ; //a flag if the texture is used as sculpt data. + BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. public: static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize - static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database - static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) - static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. - static LLPointer sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface - static LLPointer sDefaultIrradiancePBRp; // PBR: irradiance + static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database + static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) + static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. + static LLPointer sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface + static LLPointer sDefaultIrradiancePBRp; // PBR: irradiance // not sure why, but something is iffy about the loading of this particular texture, use the accessor instead of accessing directly static LLPointer sSmokeImagep; // Old "Default" translucent texture @@ -539,24 +539,24 @@ public: class LLViewerLODTexture : public LLViewerFetchedTexture { protected: - /*virtual*/ ~LLViewerLODTexture(){} + /*virtual*/ ~LLViewerLODTexture(){} public: - LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); - LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); + LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); - /*virtual*/ S8 getType() const; - // Process image stats to determine priority/quality requirements. - /*virtual*/ void processTextureStats(); - bool isUpdateFrozen() ; + /*virtual*/ S8 getType() const; + // Process image stats to determine priority/quality requirements. + /*virtual*/ void processTextureStats(); + bool isUpdateFrozen() ; private: - void init(bool firstinit) ; - bool scaleDown() ; + void init(bool firstinit) ; + bool scaleDown() ; private: - F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard - F32 mCalculatedDiscardLevel; // Last calculated discard level + F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard + F32 mCalculatedDiscardLevel; // Last calculated discard level }; // @@ -566,135 +566,135 @@ private: class LLViewerMediaTexture : public LLViewerTexture { protected: - /*virtual*/ ~LLViewerMediaTexture() ; + /*virtual*/ ~LLViewerMediaTexture() ; public: - LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - /*virtual*/ S8 getType() const; - void reinit(BOOL usemipmaps = TRUE); + /*virtual*/ S8 getType() const; + void reinit(BOOL usemipmaps = TRUE); - BOOL getUseMipMaps() {return mUseMipMaps ; } - void setUseMipMaps(BOOL mipmap) ; - - void setPlaying(BOOL playing) ; - BOOL isPlaying() const {return mIsPlaying;} - void setMediaImpl() ; + BOOL getUseMipMaps() {return mUseMipMaps ; } + void setUseMipMaps(BOOL mipmap) ; + + void setPlaying(BOOL playing) ; + BOOL isPlaying() const {return mIsPlaying;} + void setMediaImpl() ; virtual bool isViewerMediaTexture() const { return true; } - void initVirtualSize() ; - void invalidateMediaImpl() ; + void initVirtualSize() ; + void invalidateMediaImpl() ; - void addMediaToFace(LLFace* facep) ; - void removeMediaFromFace(LLFace* facep) ; + void addMediaToFace(LLFace* facep) ; + void removeMediaFromFace(LLFace* facep) ; - /*virtual*/ void addFace(U32 ch, LLFace* facep) ; - /*virtual*/ void removeFace(U32 ch, LLFace* facep) ; + /*virtual*/ void addFace(U32 ch, LLFace* facep) ; + /*virtual*/ void removeFace(U32 ch, LLFace* facep) ; - /*virtual*/ F32 getMaxVirtualSize() ; + /*virtual*/ F32 getMaxVirtualSize() ; private: - void switchTexture(U32 ch, LLFace* facep) ; - BOOL findFaces() ; - void stopPlaying() ; + void switchTexture(U32 ch, LLFace* facep) ; + BOOL findFaces() ; + void stopPlaying() ; private: - // - //an instant list, recording all faces referencing or can reference to this media texture. - //NOTE: it is NOT thread safe. - // - std::list< LLFace* > mMediaFaceList ; + // + //an instant list, recording all faces referencing or can reference to this media texture. + //NOTE: it is NOT thread safe. + // + std::list< LLFace* > mMediaFaceList ; - //an instant list keeping all textures which are replaced by the current media texture, - //is only used to avoid the removal of those textures from memory. - std::list< LLPointer > mTextureList ; + //an instant list keeping all textures which are replaced by the current media texture, + //is only used to avoid the removal of those textures from memory. + std::list< LLPointer > mTextureList ; - LLViewerMediaImpl* mMediaImplp ; - BOOL mIsPlaying ; - U32 mUpdateVirtualSizeTime ; + LLViewerMediaImpl* mMediaImplp ; + BOOL mIsPlaying ; + U32 mUpdateVirtualSizeTime ; public: - static void updateClass() ; - static void cleanUpClass() ; + static void updateClass() ; + static void cleanUpClass() ; - static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ; - static void removeMediaImplFromTexture(const LLUUID& media_id) ; + static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ; + static void removeMediaImplFromTexture(const LLUUID& media_id) ; private: - typedef std::map< LLUUID, LLPointer > media_map_t ; - static media_map_t sMediaMap ; + typedef std::map< LLUUID, LLPointer > media_map_t ; + static media_map_t sMediaMap ; }; //just an interface class, do not create instance from this class. class LLViewerTextureManager { private: - //make the constructor private to preclude creating instances from this class. - LLViewerTextureManager(){} + //make the constructor private to preclude creating instances from this class. + LLViewerTextureManager(){} public: //texture pipeline tester - static LLTexturePipelineTester* sTesterp ; - - //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. - static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; - - // - //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. - // - static void findFetchedTextures(const LLUUID& id, std::vector &output); - static void findTextures(const LLUUID& id, std::vector &output); - static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type); - static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; - - static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - - // - //"get-texture" will create a new texture if the texture does not exist. - // - static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - - static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); - static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; - static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; - static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + static LLTexturePipelineTester* sTesterp ; + + //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. + static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; + + // + //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. + // + static void findFetchedTextures(const LLUUID& id, std::vector &output); + static void findTextures(const LLUUID& id, std::vector &output); + static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type); + static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; + + static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + // + //"get-texture" will create a new texture if the texture does not exist. + // + static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); + static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps); - static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, - FTType f_type = FTT_DEFAULT, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - LLHost request_from_host = LLHost() - ); - - static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, - FTType f_type = FTT_LOCAL_FILE, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - const LLUUID& force_id = LLUUID::null - ); - - static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url, - FTType f_type, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - const LLUUID& force_id = LLUUID::null - ); - - static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ; - - static void init() ; - static void cleanup() ; + static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, + FTType f_type = FTT_DEFAULT, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, + FTType f_type = FTT_LOCAL_FILE, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url, + FTType f_type, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ; + + static void init() ; + static void cleanup() ; }; // //this class is used for test/debug only @@ -703,91 +703,91 @@ public: // class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession { - enum - { - MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 - }; + enum + { + MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 + }; public: - LLTexturePipelineTester() ; - ~LLTexturePipelineTester() ; + LLTexturePipelineTester() ; + ~LLTexturePipelineTester() ; - void update(); - void updateTextureBindingStats(const LLViewerTexture* imagep) ; - void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; - void updateGrayTextureBinding() ; - void setStablizingTime() ; + void update(); + void updateTextureBindingStats(const LLViewerTexture* imagep) ; + void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; + void updateGrayTextureBinding() ; + void setStablizingTime() ; private: - void reset() ; - void updateStablizingTime() ; + void reset() ; + void updateStablizingTime() ; - /*virtual*/ void outputTestRecord(LLSD* sd) ; + /*virtual*/ void outputTestRecord(LLSD* sd) ; private: - BOOL mPause ; + BOOL mPause ; private: - BOOL mUsingDefaultTexture; //if set, some textures are still gray. - - U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. - U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. - U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. - U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. - - // - //data size - // - U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline - U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache - U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. - U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties - - // - //time - //NOTE: the error tolerances of the following timers is one frame time. - // - F32 mStartFetchingTime ; - F32 mTotalGrayTime ; //total loading time when no gray textures. - F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows - F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. - F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. - F32 mStartStablizingTime ; - F32 mEndStablizingTime ; + BOOL mUsingDefaultTexture; //if set, some textures are still gray. + + U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. + U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. + U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. + U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. + + // + //data size + // + U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline + U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache + U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. + U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties + + // + //time + //NOTE: the error tolerances of the following timers is one frame time. + // + F32 mStartFetchingTime ; + F32 mTotalGrayTime ; //total loading time when no gray textures. + F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows + F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. + F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. + F32 mStartStablizingTime ; + F32 mEndStablizingTime ; private: - // - //The following members are used for performance analyzing - // - class LLTextureTestSession : public LLTestSession - { - public: - LLTextureTestSession() ; - /*virtual*/ ~LLTextureTestSession() ; - - void reset() ; - - F32 mTotalGrayTime ; - F32 mTotalStablizingTime ; - F32 mStartTimeLoadingSculpties ; - F32 mTotalTimeLoadingSculpties ; - - S32 mTotalBytesLoaded ; - S32 mTotalBytesLoadedFromCache ; - S32 mTotalBytesLoadedForLargeImage ; - S32 mTotalBytesLoadedForSculpties ; - - typedef struct _texture_instant_preformance_t - { - S32 mAverageBytesUsedPerSecond ; - S32 mAverageBytesUsedForLargeImagePerSecond ; - F32 mAveragePercentageBytesUsedPerSecond ; - F32 mTime ; - }texture_instant_preformance_t ; - std::vector mInstantPerformanceList ; - S32 mInstantPerformanceListCounter ; - }; - - /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; - /*virtual*/ void compareTestSessions(llofstream* os) ; + // + //The following members are used for performance analyzing + // + class LLTextureTestSession : public LLTestSession + { + public: + LLTextureTestSession() ; + /*virtual*/ ~LLTextureTestSession() ; + + void reset() ; + + F32 mTotalGrayTime ; + F32 mTotalStablizingTime ; + F32 mStartTimeLoadingSculpties ; + F32 mTotalTimeLoadingSculpties ; + + S32 mTotalBytesLoaded ; + S32 mTotalBytesLoadedFromCache ; + S32 mTotalBytesLoadedForLargeImage ; + S32 mTotalBytesLoadedForSculpties ; + + typedef struct _texture_instant_preformance_t + { + S32 mAverageBytesUsedPerSecond ; + S32 mAverageBytesUsedForLargeImagePerSecond ; + F32 mAveragePercentageBytesUsedPerSecond ; + F32 mTime ; + }texture_instant_preformance_t ; + std::vector mInstantPerformanceList ; + S32 mInstantPerformanceListCounter ; + }; + + /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; + /*virtual*/ void compareTestSessions(llofstream* os) ; }; #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a0b0fabb66..9f91ecf41c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llviewerwindow.cpp * @brief Implementation of the LLViewerWindow class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -62,7 +62,7 @@ // // linden library includes -#include "llaudioengine.h" // mute on minimize +#include "llaudioengine.h" // mute on minimize #include "llchatentry.h" #include "indra_constants.h" #include "llassetstorage.h" @@ -166,7 +166,7 @@ #include "lltoolselectland.h" #include "lltrans.h" #include "lluictrlfactory.h" -#include "llurldispatcher.h" // SLURL from other app instance +#include "llurldispatcher.h" // SLURL from other app instance #include "llversioninfo.h" #include "llvieweraudio.h" #include "llviewercamera.h" @@ -231,31 +231,31 @@ extern BOOL gResizeScreenTexture; extern BOOL gCubeSnapshot; extern BOOL gSnapshotNoPost; -LLViewerWindow *gViewerWindow = NULL; +LLViewerWindow *gViewerWindow = NULL; -LLFrameTimer gAwayTimer; -LLFrameTimer gAwayTriggerTimer; +LLFrameTimer gAwayTimer; +LLFrameTimer gAwayTriggerTimer; -BOOL gShowOverlayTitle = FALSE; +BOOL gShowOverlayTitle = FALSE; LLViewerObject* gDebugRaycastObject = NULL; LLVOPartGroup* gDebugRaycastParticle = NULL; LLVector4a gDebugRaycastIntersection; -LLVector4a gDebugRaycastParticleIntersection; +LLVector4a gDebugRaycastParticleIntersection; LLVector2 gDebugRaycastTexCoord; LLVector4a gDebugRaycastNormal; LLVector4a gDebugRaycastTangent; -S32 gDebugRaycastFaceHit; +S32 gDebugRaycastFaceHit; S32 gDebugRaycastGLTFNodeHit; S32 gDebugRaycastGLTFPrimitiveHit; -LLVector4a gDebugRaycastStart; -LLVector4a gDebugRaycastEnd; +LLVector4a gDebugRaycastStart; +LLVector4a gDebugRaycastEnd; // HUD display lines in lower right -BOOL gDisplayWindInfo = FALSE; -BOOL gDisplayCameraPos = FALSE; -BOOL gDisplayFOV = FALSE; -BOOL gDisplayBadge = FALSE; +BOOL gDisplayWindInfo = FALSE; +BOOL gDisplayCameraPos = FALSE; +BOOL gDisplayFOV = FALSE; +BOOL gDisplayBadge = FALSE; static const U8 NO_FACE = 255; BOOL gQuietSnapshot = FALSE; @@ -269,8 +269,8 @@ static const F32 MIN_DISPLAY_SCALE = 0.75f; static const char KEY_MOUSELOOK = 'M'; -static LLCachedControl sSnapshotBaseName(LLCachedControl(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot")); -static LLCachedControl sSnapshotDir(LLCachedControl(gSavedPerAccountSettings, "SnapshotBaseDir", "")); +static LLCachedControl sSnapshotBaseName(LLCachedControl(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot")); +static LLCachedControl sSnapshotDir(LLCachedControl(gSavedPerAccountSettings, "SnapshotBaseDir", "")); LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); @@ -278,40 +278,40 @@ LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity") class RecordToChatConsoleRecorder : public LLError::Recorder { public: - virtual void recordMessage(LLError::ELevel level, - const std::string& message) - { - //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread - - // only log warnings to chat console - //if (level == LLError::LEVEL_WARN) - //{ - //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance("chat"); - //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat")) - //{ - // LLChat chat; - // chat.mText = message; - // chat.mSourceType = CHAT_SOURCE_SYSTEM; - - // chat_floater->addChat(chat, FALSE, FALSE); - //} - //} - } + virtual void recordMessage(LLError::ELevel level, + const std::string& message) + { + //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread + + // only log warnings to chat console + //if (level == LLError::LEVEL_WARN) + //{ + //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance("chat"); + //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat")) + //{ + // LLChat chat; + // chat.mText = message; + // chat.mSourceType = CHAT_SOURCE_SYSTEM; + + // chat_floater->addChat(chat, FALSE, FALSE); + //} + //} + } }; class RecordToChatConsole : public LLSingleton { - LLSINGLETON(RecordToChatConsole); + LLSINGLETON(RecordToChatConsole); public: - void startRecorder() { LLError::addRecorder(mRecorder); } - void stopRecorder() { LLError::removeRecorder(mRecorder); } + void startRecorder() { LLError::addRecorder(mRecorder); } + void stopRecorder() { LLError::removeRecorder(mRecorder); } private: - LLError::RecorderPtr mRecorder; + LLError::RecorderPtr mRecorder; }; RecordToChatConsole::RecordToChatConsole(): - mRecorder(new RecordToChatConsoleRecorder()) + mRecorder(new RecordToChatConsoleRecorder()) { mRecorder->showTags(false); mRecorder->showLocation(false); @@ -421,214 +421,214 @@ static LLTrace::BlockTimerStatHandle FTM_DISPLAY_DEBUG_TEXT("Display Debug Text" class LLDebugText { private: - struct Line - { - Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {} - std::string text; - S32 x,y; - }; - - LLViewerWindow *mWindow; - - typedef std::vector line_list_t; - line_list_t mLineList; - LLColor4 mTextColor; - - LLColor4 mBackColor; - LLRect mBackRectCamera1; - LLRect mBackRectCamera2; - - void addText(S32 x, S32 y, const std::string &text) - { - mLineList.push_back(Line(text, x, y)); - } - - void clearText() { mLineList.clear(); } - + struct Line + { + Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {} + std::string text; + S32 x,y; + }; + + LLViewerWindow *mWindow; + + typedef std::vector line_list_t; + line_list_t mLineList; + LLColor4 mTextColor; + + LLColor4 mBackColor; + LLRect mBackRectCamera1; + LLRect mBackRectCamera2; + + void addText(S32 x, S32 y, const std::string &text) + { + mLineList.push_back(Line(text, x, y)); + } + + void clearText() { mLineList.clear(); } + public: - LLDebugText(LLViewerWindow* window) : mWindow(window) {} - - void update() - { - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - clearText(); - return; - } - - static LLCachedControl log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - std::string wind_vel_text; - std::string wind_vector_text; - std::string rwind_vel_text; - std::string rwind_vector_text; - std::string audio_text; - - static const std::string beacon_particle = LLTrans::getString("BeaconParticle"); - static const std::string beacon_physical = LLTrans::getString("BeaconPhysical"); - static const std::string beacon_scripted = LLTrans::getString("BeaconScripted"); - static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch"); - static const std::string beacon_sound = LLTrans::getString("BeaconSound"); - static const std::string beacon_media = LLTrans::getString("BeaconMedia"); - static const std::string beacon_sun = LLTrans::getString("BeaconSun"); - static const std::string beacon_moon = LLTrans::getString("BeaconMoon"); - static const std::string particle_hiding = LLTrans::getString("ParticleHiding"); - - // Draw the statistics in a light gray - // and in a thin font - mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f ); - - // Draw stuff growing up from right lower corner of screen - S32 x_right = mWindow->getWorldViewWidthScaled(); - S32 xpos = x_right - 400; - xpos = llmax(xpos, 0); - S32 ypos = 64; - const S32 y_inc = 20; - - // Camera matrix text is hard to see again a white background - // Add a dark background underneath the matrices for readability (contrast) - mBackRectCamera1.mLeft = xpos; - mBackRectCamera1.mRight = x_right; - mBackRectCamera1.mTop = -1; - mBackRectCamera1.mBottom = -1; - mBackRectCamera2 = mBackRectCamera1; - - mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" ); - - clearText(); - - if (gSavedSettings.getBOOL("DebugShowTime")) - { - F32 time = gFrameTimeSeconds; - S32 hours = (S32)(time / (60*60)); - S32 mins = (S32)((time - hours*(60*60)) / 60); - S32 secs = (S32)((time - hours*(60*60) - mins*60)); - addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; - } - - if (gSavedSettings.getBOOL("DebugShowMemory")) - { - addText(xpos, ypos, - STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)")); - ypos += y_inc; - } - - if (gDisplayCameraPos) - { - std::string camera_view_text; - std::string camera_center_text; - std::string agent_view_text; - std::string agent_left_text; - std::string agent_center_text; - std::string agent_root_center_text; - - LLVector3d tvector; // Temporary vector to hold data for printing. - - // Update camera center, camera view, wind info every other frame - tvector = gAgent.getPositionGlobal(); - agent_center_text = llformat("AgentCenter %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - - if (isAgentAvatarValid()) - { - tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition()); - agent_root_center_text = llformat("AgentRootCenter %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - } - else - { - agent_root_center_text = "---"; - } - - - tvector = LLVector4(gAgent.getFrameAgent().getAtAxis()); - agent_view_text = llformat("AgentAtAxis %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - - tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis()); - agent_left_text = llformat("AgentLeftAxis %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - - tvector = gAgentCamera.getCameraPositionGlobal(); - camera_center_text = llformat("CameraCenter %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - - tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis()); - camera_view_text = llformat("CameraAtAxis %f %f %f", - (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); - - addText(xpos, ypos, agent_center_text); ypos += y_inc; - addText(xpos, ypos, agent_root_center_text); ypos += y_inc; - addText(xpos, ypos, agent_view_text); ypos += y_inc; - addText(xpos, ypos, agent_left_text); ypos += y_inc; - addText(xpos, ypos, camera_center_text); ypos += y_inc; - addText(xpos, ypos, camera_view_text); ypos += y_inc; - } - - if (gDisplayWindInfo) - { - wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec()); - wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]); - rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec()); - rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]); - - addText(xpos, ypos, wind_vel_text); ypos += y_inc; - addText(xpos, ypos, wind_vector_text); ypos += y_inc; - addText(xpos, ypos, rwind_vel_text); ypos += y_inc; - addText(xpos, ypos, rwind_vector_text); ypos += y_inc; - } - if (gDisplayWindInfo) - { - audio_text = llformat("Audio for wind: %d", gAudiop ? gAudiop->isWindEnabled() : -1); - addText(xpos, ypos, audio_text); ypos += y_inc; - } - if (gDisplayFOV) - { - addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); - ypos += y_inc; - } - if (gDisplayBadge) - { - addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); - ypos += y_inc * 2; - } - - /*if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - addText(xpos + 200, ypos, llformat("Flycam")); - ypos += y_inc; - }*/ - - if (gSavedSettings.getBOOL("DebugShowRenderInfo")) - { - LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - - //show streaming cost/triangle count of known prims in current region OR selection - { - F32 cost = 0.f; - S32 count = 0; - S32 vcount = 0; - S32 object_count = 0; - S32 total_bytes = 0; - S32 visible_bytes = 0; - - const char* label = "Region"; - if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0) - { //region - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - for (U32 i = 0; i < gObjectList.getNumObjects(); ++i) - { - LLViewerObject* object = gObjectList.getObject(i); - if (object && - object->getRegion() == region && - object->getVolume()) - { - object_count++; - S32 bytes = 0; - S32 visible = 0; - cost += object->getStreamingCost(); + LLDebugText(LLViewerWindow* window) : mWindow(window) {} + + void update() + { + if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + clearText(); + return; + } + + static LLCachedControl log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; + + std::string wind_vel_text; + std::string wind_vector_text; + std::string rwind_vel_text; + std::string rwind_vector_text; + std::string audio_text; + + static const std::string beacon_particle = LLTrans::getString("BeaconParticle"); + static const std::string beacon_physical = LLTrans::getString("BeaconPhysical"); + static const std::string beacon_scripted = LLTrans::getString("BeaconScripted"); + static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch"); + static const std::string beacon_sound = LLTrans::getString("BeaconSound"); + static const std::string beacon_media = LLTrans::getString("BeaconMedia"); + static const std::string beacon_sun = LLTrans::getString("BeaconSun"); + static const std::string beacon_moon = LLTrans::getString("BeaconMoon"); + static const std::string particle_hiding = LLTrans::getString("ParticleHiding"); + + // Draw the statistics in a light gray + // and in a thin font + mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f ); + + // Draw stuff growing up from right lower corner of screen + S32 x_right = mWindow->getWorldViewWidthScaled(); + S32 xpos = x_right - 400; + xpos = llmax(xpos, 0); + S32 ypos = 64; + const S32 y_inc = 20; + + // Camera matrix text is hard to see again a white background + // Add a dark background underneath the matrices for readability (contrast) + mBackRectCamera1.mLeft = xpos; + mBackRectCamera1.mRight = x_right; + mBackRectCamera1.mTop = -1; + mBackRectCamera1.mBottom = -1; + mBackRectCamera2 = mBackRectCamera1; + + mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" ); + + clearText(); + + if (gSavedSettings.getBOOL("DebugShowTime")) + { + F32 time = gFrameTimeSeconds; + S32 hours = (S32)(time / (60*60)); + S32 mins = (S32)((time - hours*(60*60)) / 60); + S32 secs = (S32)((time - hours*(60*60) - mins*60)); + addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; + } + + if (gSavedSettings.getBOOL("DebugShowMemory")) + { + addText(xpos, ypos, + STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)")); + ypos += y_inc; + } + + if (gDisplayCameraPos) + { + std::string camera_view_text; + std::string camera_center_text; + std::string agent_view_text; + std::string agent_left_text; + std::string agent_center_text; + std::string agent_root_center_text; + + LLVector3d tvector; // Temporary vector to hold data for printing. + + // Update camera center, camera view, wind info every other frame + tvector = gAgent.getPositionGlobal(); + agent_center_text = llformat("AgentCenter %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + + if (isAgentAvatarValid()) + { + tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition()); + agent_root_center_text = llformat("AgentRootCenter %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + } + else + { + agent_root_center_text = "---"; + } + + + tvector = LLVector4(gAgent.getFrameAgent().getAtAxis()); + agent_view_text = llformat("AgentAtAxis %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + + tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis()); + agent_left_text = llformat("AgentLeftAxis %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + + tvector = gAgentCamera.getCameraPositionGlobal(); + camera_center_text = llformat("CameraCenter %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + + tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis()); + camera_view_text = llformat("CameraAtAxis %f %f %f", + (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); + + addText(xpos, ypos, agent_center_text); ypos += y_inc; + addText(xpos, ypos, agent_root_center_text); ypos += y_inc; + addText(xpos, ypos, agent_view_text); ypos += y_inc; + addText(xpos, ypos, agent_left_text); ypos += y_inc; + addText(xpos, ypos, camera_center_text); ypos += y_inc; + addText(xpos, ypos, camera_view_text); ypos += y_inc; + } + + if (gDisplayWindInfo) + { + wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec()); + wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]); + rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec()); + rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]); + + addText(xpos, ypos, wind_vel_text); ypos += y_inc; + addText(xpos, ypos, wind_vector_text); ypos += y_inc; + addText(xpos, ypos, rwind_vel_text); ypos += y_inc; + addText(xpos, ypos, rwind_vector_text); ypos += y_inc; + } + if (gDisplayWindInfo) + { + audio_text = llformat("Audio for wind: %d", gAudiop ? gAudiop->isWindEnabled() : -1); + addText(xpos, ypos, audio_text); ypos += y_inc; + } + if (gDisplayFOV) + { + addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); + ypos += y_inc; + } + if (gDisplayBadge) + { + addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView())); + ypos += y_inc * 2; + } + + /*if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + addText(xpos + 200, ypos, llformat("Flycam")); + ypos += y_inc; + }*/ + + if (gSavedSettings.getBOOL("DebugShowRenderInfo")) + { + LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); + + //show streaming cost/triangle count of known prims in current region OR selection + { + F32 cost = 0.f; + S32 count = 0; + S32 vcount = 0; + S32 object_count = 0; + S32 total_bytes = 0; + S32 visible_bytes = 0; + + const char* label = "Region"; + if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0) + { //region + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + for (U32 i = 0; i < gObjectList.getNumObjects(); ++i) + { + LLViewerObject* object = gObjectList.getObject(i); + if (object && + object->getRegion() == region && + object->getVolume()) + { + object_count++; + S32 bytes = 0; + S32 visible = 0; + cost += object->getStreamingCost(); LLMeshCostData costs; if (object->getCostData(costs)) { @@ -636,96 +636,96 @@ public: visible = costs.getSizeByLOD(object->getLOD()); } - S32 vt = 0; - count += object->getTriangleCount(&vt); - vcount += vt; - total_bytes += bytes; - visible_bytes += visible; - } - } - } - } - else - { - label = "Selection"; - cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); - count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount); - object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - } - - addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); - ypos += y_inc; - - addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects", - count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); - ypos += y_inc; - - } - - addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount)); - ypos += y_inc; - - addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); - ypos += y_inc; - - addText(xpos, ypos, llformat("%d Render Calls", (U32)last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); + S32 vt = 0; + count += object->getTriangleCount(&vt); + vcount += vt; + total_bytes += bytes; + visible_bytes += visible; + } + } + } + } + else + { + label = "Selection"; + cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); + count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount); + object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + } + + addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); + ypos += y_inc; + + addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects", + count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); + ypos += y_inc; + + } + + addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount)); ypos += y_inc; - addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); - ypos += y_inc; + addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Render Calls", (U32)last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); + ypos += y_inc; - addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount)); - ypos += y_inc; + addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount)); + ypos += y_inc; - addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps)); - ypos += y_inc; + addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps)); + ypos += y_inc; - gPipeline.mTextureMatrixOps = 0; - gPipeline.mMatrixOpCount = 0; + gPipeline.mTextureMatrixOps = 0; + gPipeline.mMatrixOpCount = 0; - if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) - { + if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) + { addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", (U32)last_frame_recording.getMin(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMax(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMean(LLPipeline::sStatBatchSize))); - } + } + ypos += y_inc; + + addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); + LLRender::sUICalls = LLRender::sUIVerts = 0; + ypos += y_inc; + + addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount)); + ypos += y_inc; - addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); - LLRender::sUICalls = LLRender::sUIVerts = 0; - ypos += y_inc; + if (!LLOcclusionCullingGroup::sPendingQueries.empty()) + { + addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size())); + ypos += y_inc; + } + - addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount)); - - ypos += y_inc; + addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars)); + + ypos += y_inc; - if (!LLOcclusionCullingGroup::sPendingQueries.empty()) - { - addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size())); - ypos += y_inc; - } + addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount)); + ypos += y_inc; - addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars)); - - ypos += y_inc; + if (gMeshRepo.meshRezEnabled()) + { + addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f))); - addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount)); - - ypos += y_inc; + ypos += y_inc; - if (gMeshRepo.meshRezEnabled()) - { - addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f))); - - ypos += y_inc; - - addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount, - LLMeshRepository::sHTTPRetryCount)); - ypos += y_inc; + addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount, + LLMeshRepository::sHTTPRetryCount)); + ypos += y_inc; - addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing)); - ypos += y_inc; + addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing)); + ypos += y_inc; - addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); + addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); ypos += y_inc; addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f))); @@ -733,72 +733,72 @@ public: addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f))); - ypos += y_inc; - } + ypos += y_inc; + } gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; - } - if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) - { - std::map sorted_avs; - - std::vector::iterator sort_iter = LLCharacter::sInstances.begin(); - while (sort_iter != LLCharacter::sInstances.end()) - { - LLVOAvatar* avatar = dynamic_cast(*sort_iter); - if (avatar && - !avatar->isDead()) // Not dead yet - { - // Stuff into a sorted map so the display is ordered - sorted_avs[avatar->getFullname()] = avatar; - } - sort_iter++; - } - - std::string trunc_name; - std::map::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top - while (av_iter != sorted_avs.rend()) - { - LLVOAvatar* avatar = av_iter->second; - - avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date - - trunc_name = utf8str_truncate(avatar->getFullname(), 16); - addText(xpos, ypos, llformat("%s : %s, complexity %d, area %.2f", - trunc_name.c_str(), + } + if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) + { + std::map sorted_avs; + + std::vector::iterator sort_iter = LLCharacter::sInstances.begin(); + while (sort_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar* avatar = dynamic_cast(*sort_iter); + if (avatar && + !avatar->isDead()) // Not dead yet + { + // Stuff into a sorted map so the display is ordered + sorted_avs[avatar->getFullname()] = avatar; + } + sort_iter++; + } + + std::string trunc_name; + std::map::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top + while (av_iter != sorted_avs.rend()) + { + LLVOAvatar* avatar = av_iter->second; + + avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date + + trunc_name = utf8str_truncate(avatar->getFullname(), 16); + addText(xpos, ypos, llformat("%s : %s, complexity %d, area %.2f", + trunc_name.c_str(), LLVOAvatar::rezStatusToString(avatar->getRezzedStatus()).c_str(), - avatar->getVisualComplexity(), - avatar->getAttachmentSurfaceArea())); - ypos += y_inc; - av_iter++; - } - } - if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) - { - char camera_lines[8][32]; - memset(camera_lines, ' ', sizeof(camera_lines)); - - // Projection last column is always <0,0,-1.0001,0> - // Projection last row is always <0,0,-0.2> - mBackRectCamera1.mBottom = ypos - y_inc + 2; - MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc; - MATRIX_ROW_N32_TO_STR(gGLProjection, 8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc; - MATRIX_ROW_N32_TO_STR(gGLProjection, 4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop = ypos + 2; - MATRIX_ROW_N32_TO_STR(gGLProjection, 0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2; - - addText(xpos, ypos, "Projection Matrix"); - ypos += y_inc; - - // View last column is always <0,0,0,1> - MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc; - MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc; - MATRIX_ROW_N32_TO_STR(gGLModelView, 4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2; - MATRIX_ROW_N32_TO_STR(gGLModelView, 0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc; - - addText(xpos, ypos, "View Matrix"); - ypos += y_inc; - } - // disable use of glReadPixels which messes up nVidia nSight graphics debugging + avatar->getVisualComplexity(), + avatar->getAttachmentSurfaceArea())); + ypos += y_inc; + av_iter++; + } + } + if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) + { + char camera_lines[8][32]; + memset(camera_lines, ' ', sizeof(camera_lines)); + + // Projection last column is always <0,0,-1.0001,0> + // Projection last row is always <0,0,-0.2> + mBackRectCamera1.mBottom = ypos - y_inc + 2; + MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc; + MATRIX_ROW_N32_TO_STR(gGLProjection, 8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc; + MATRIX_ROW_N32_TO_STR(gGLProjection, 4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop = ypos + 2; + MATRIX_ROW_N32_TO_STR(gGLProjection, 0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2; + + addText(xpos, ypos, "Projection Matrix"); + ypos += y_inc; + + // View last column is always <0,0,0,1> + MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc; + MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc; + MATRIX_ROW_N32_TO_STR(gGLModelView, 4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2; + MATRIX_ROW_N32_TO_STR(gGLModelView, 0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc; + + addText(xpos, ypos, "View Matrix"); + ypos += y_inc; + } + // disable use of glReadPixels which messes up nVidia nSight graphics debugging if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport) { U8 color[4]; @@ -807,165 +807,165 @@ public: // Convert x,y to raw pixel coords S32 x_raw = llround(coord.mX * gViewerWindow->getWindowWidthRaw() / (F32) gViewerWindow->getWindowWidthScaled()); S32 y_raw = llround(coord.mY * gViewerWindow->getWindowHeightRaw() / (F32) gViewerWindow->getWindowHeightScaled()); - + glReadPixels(x_raw, y_raw, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color); addText(xpos, ypos, llformat("Pixel <%1d, %1d> R:%1d G:%1d B:%1d A:%1d", x_raw, y_raw, color[0], color[1], color[2], color[3])); ypos += y_inc; } // only display these messages if we are actually rendering beacons at this moment - if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons")) - { - if (LLPipeline::getRenderMOAPBeacons()) - { - addText(xpos, ypos, "Viewing media beacons (white)"); - ypos += y_inc; - } - - if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES)) - { - addText(xpos, ypos, particle_hiding); - ypos += y_inc; - } - - if (LLPipeline::getRenderParticleBeacons()) - { - addText(xpos, ypos, "Viewing particle beacons (blue)"); - ypos += y_inc; - } - - if (LLPipeline::getRenderSoundBeacons()) - { - addText(xpos, ypos, "Viewing sound beacons (yellow)"); - ypos += y_inc; - } - - if (LLPipeline::getRenderScriptedBeacons()) - { - addText(xpos, ypos, beacon_scripted); - ypos += y_inc; - } - else - if (LLPipeline::getRenderScriptedTouchBeacons()) - { - addText(xpos, ypos, beacon_scripted_touch); - ypos += y_inc; - } - - if (LLPipeline::getRenderPhysicalBeacons()) - { - addText(xpos, ypos, "Viewing physical object beacons (green)"); - ypos += y_inc; - } - } - - static LLUICachedControl show_sun_beacon("sunbeacon", false); - static LLUICachedControl show_moon_beacon("moonbeacon", false); - - if (show_sun_beacon) - { - addText(xpos, ypos, beacon_sun); - ypos += y_inc; - } - if (show_moon_beacon) - { - addText(xpos, ypos, beacon_moon); - ypos += y_inc; - } - - if(log_texture_traffic) - { - U32 old_y = ypos ; - for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++) - { - if(gTotalTextureBytesPerBoostLevel[i] > (S32Bytes)0) - { - addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, F32Megabytes(gTotalTextureBytesPerBoostLevel[i]).value())); - ypos += y_inc; - } - } - if(ypos != old_y) - { - addText(xpos, ypos, "Network traffic for textures:"); - ypos += y_inc; - } - } - - if (gSavedSettings.getBOOL("DebugShowTextureInfo")) - { - LLViewerObject* objectp = NULL ; - - LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); - if (nodep) - { - objectp = nodep->getObject(); - } - - if (objectp && !objectp->isDead()) - { - S32 num_faces = objectp->mDrawable->getNumFaces() ; - std::set tex_list; - - for(S32 i = 0 ; i < num_faces; i++) - { - LLFace* facep = objectp->mDrawable->getFace(i) ; - if(facep) - { - LLViewerFetchedTexture* tex = dynamic_cast(facep->getTexture()) ; - if(tex) - { - if(tex_list.find(tex) != tex_list.end()) - { - continue ; //already displayed. - } - tex_list.insert(tex); - - std::string uuid_str; - tex->getID().toString(uuid_str); - uuid_str = uuid_str.substr(0,7); - - addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize())); - ypos += y_inc; - - addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(), - tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N")); - ypos += y_inc; - } - } - } - } - } - } - - void draw() - { - LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT); - - // Camera matrix text is hard to see again a white background - // Add a dark background underneath the matrices for readability (contrast) - if (mBackRectCamera1.mTop >= 0) - { - mBackColor.setAlpha( 0.75f ); - gl_rect_2d(mBackRectCamera1, mBackColor, true); - - mBackColor.setAlpha( 0.66f ); - gl_rect_2d(mBackRectCamera2, mBackColor, true); - } - - for (line_list_t::iterator iter = mLineList.begin(); - iter != mLineList.end(); ++iter) - { - const Line& line = *iter; - LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor, - LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); - } - } + if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons")) + { + if (LLPipeline::getRenderMOAPBeacons()) + { + addText(xpos, ypos, "Viewing media beacons (white)"); + ypos += y_inc; + } + + if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES)) + { + addText(xpos, ypos, particle_hiding); + ypos += y_inc; + } + + if (LLPipeline::getRenderParticleBeacons()) + { + addText(xpos, ypos, "Viewing particle beacons (blue)"); + ypos += y_inc; + } + + if (LLPipeline::getRenderSoundBeacons()) + { + addText(xpos, ypos, "Viewing sound beacons (yellow)"); + ypos += y_inc; + } + + if (LLPipeline::getRenderScriptedBeacons()) + { + addText(xpos, ypos, beacon_scripted); + ypos += y_inc; + } + else + if (LLPipeline::getRenderScriptedTouchBeacons()) + { + addText(xpos, ypos, beacon_scripted_touch); + ypos += y_inc; + } + + if (LLPipeline::getRenderPhysicalBeacons()) + { + addText(xpos, ypos, "Viewing physical object beacons (green)"); + ypos += y_inc; + } + } + + static LLUICachedControl show_sun_beacon("sunbeacon", false); + static LLUICachedControl show_moon_beacon("moonbeacon", false); + + if (show_sun_beacon) + { + addText(xpos, ypos, beacon_sun); + ypos += y_inc; + } + if (show_moon_beacon) + { + addText(xpos, ypos, beacon_moon); + ypos += y_inc; + } + + if(log_texture_traffic) + { + U32 old_y = ypos ; + for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++) + { + if(gTotalTextureBytesPerBoostLevel[i] > (S32Bytes)0) + { + addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, F32Megabytes(gTotalTextureBytesPerBoostLevel[i]).value())); + ypos += y_inc; + } + } + if(ypos != old_y) + { + addText(xpos, ypos, "Network traffic for textures:"); + ypos += y_inc; + } + } + + if (gSavedSettings.getBOOL("DebugShowTextureInfo")) + { + LLViewerObject* objectp = NULL ; + + LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); + if (nodep) + { + objectp = nodep->getObject(); + } + + if (objectp && !objectp->isDead()) + { + S32 num_faces = objectp->mDrawable->getNumFaces() ; + std::set tex_list; + + for(S32 i = 0 ; i < num_faces; i++) + { + LLFace* facep = objectp->mDrawable->getFace(i) ; + if(facep) + { + LLViewerFetchedTexture* tex = dynamic_cast(facep->getTexture()) ; + if(tex) + { + if(tex_list.find(tex) != tex_list.end()) + { + continue ; //already displayed. + } + tex_list.insert(tex); + + std::string uuid_str; + tex->getID().toString(uuid_str); + uuid_str = uuid_str.substr(0,7); + + addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize())); + ypos += y_inc; + + addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(), + tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N")); + ypos += y_inc; + } + } + } + } + } + } + + void draw() + { + LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT); + + // Camera matrix text is hard to see again a white background + // Add a dark background underneath the matrices for readability (contrast) + if (mBackRectCamera1.mTop >= 0) + { + mBackColor.setAlpha( 0.75f ); + gl_rect_2d(mBackRectCamera1, mBackColor, true); + + mBackColor.setAlpha( 0.66f ); + gl_rect_2d(mBackRectCamera2, mBackColor, true); + } + + for (line_list_t::iterator iter = mLineList.begin(); + iter != mLineList.end(); ++iter) + { + const Line& line = *iter; + LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor, + LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); + } + } }; void LLViewerWindow::updateDebugText() { - mDebugText->update(); + mDebugText->update(); } //////////////////////////////////////////////////////////////////////////// @@ -974,16 +974,16 @@ void LLViewerWindow::updateDebugText() // LLViewerWindow::Params::Params() -: title("title"), - name("name"), - x("x"), - y("y"), - width("width"), - height("height"), - min_width("min_width"), - min_height("min_height"), - fullscreen("fullscreen", false), - ignore_pixel_depth("ignore_pixel_depth", false) +: title("title"), + name("name"), + x("x"), + y("y"), + width("width"), + height("height"), + min_width("min_width"), + min_height("min_height"), + fullscreen("fullscreen", false), + ignore_pixel_depth("ignore_pixel_depth", false) {} @@ -1000,167 +1000,167 @@ void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask) BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool& is_toolmgr_action) { - const char* buttonname = ""; - const char* buttonstatestr = ""; - S32 x = pos.mX; - S32 y = pos.mY; - x = ll_round((F32)x / mDisplayScale.mV[VX]); - y = ll_round((F32)y / mDisplayScale.mV[VY]); + const char* buttonname = ""; + const char* buttonstatestr = ""; + S32 x = pos.mX; + S32 y = pos.mY; + x = ll_round((F32)x / mDisplayScale.mV[VX]); + y = ll_round((F32)y / mDisplayScale.mV[VY]); - // Handle non-consuming global keybindings, like voice + // Handle non-consuming global keybindings, like voice gViewerInput.handleGlobalBindsMouse(clicktype, mask, down); - // only send mouse clicks to UI if UI is visible - if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - - if (down) - { - buttonstatestr = "down" ; - } - else - { - buttonstatestr = "up" ; - } - - switch (clicktype) - { - case CLICK_LEFT: - mLeftMouseDown = down; - buttonname = "Left"; - break; - case CLICK_RIGHT: - mRightMouseDown = down; - buttonname = "Right"; - break; - case CLICK_MIDDLE: - mMiddleMouseDown = down; - buttonname = "Middle"; - break; - case CLICK_DOUBLELEFT: - mLeftMouseDown = down; - buttonname = "Left Double Click"; - break; - case CLICK_BUTTON4: - buttonname = "Button 4"; - break; - case CLICK_BUTTON5: - buttonname = "Button 5"; - break; - default: - break; // COUNT and NONE - } - - LLView::sMouseHandlerMessage.clear(); - - if (gMenuBarView) - { - // stop ALT-key access to menu - gMenuBarView->resetMenuTrigger(); - } - - if (gDebugClicks) - { - LL_INFOS() << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << LL_ENDL; - } - - // Make sure we get a corresponding mouseup event, even if the mouse leaves the window - if (down) - mWindow->captureMouse(); - else - mWindow->releaseMouse(); - - // Indicate mouse was active - LLUI::getInstance()->resetMouseIdleTimer(); - - // Don't let the user move the mouse out of the window until mouse up. - if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) - { - mWindow->setMouseClipping(down); - } - - LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); - if( mouse_captor ) - { - S32 local_x; - S32 local_y; - mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); - if (LLView::sDebugMouseHandling) - { - LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << LL_ENDL; - } - - BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down); - if (r) { - - LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << LL_ENDL; - - LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y); - LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname)); - - } - else if (down && clicktype == CLICK_RIGHT) - { - handlePieMenu(x, y, mask); - r = TRUE; - } - return r; - } - - // Mark the click as handled and return if we aren't within the root view to avoid spurious bugs - if( !mRootView->pointInView(x, y) ) - { - return TRUE; - } - // Give the UI views a chance to process the click - - BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ; - if (r) - { - - LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << LL_ENDL; - - LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y); - - // Clear local coords - this was a click on root window so these are not needed - // By not including them, this allows the test skeleton generation tool to be smarter when generating code - // the code generator can be smarter because when local coords are present it can try the xui path with local coords - // and fallback to global coordinates only if needed. - // The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element - // (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA) - // For this reason it's best to provide hints where possible here by leaving out local coordinates - LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1); - LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname); - - if (LLView::sDebugMouseHandling) - { - LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << LL_ENDL; - } - return TRUE; - } else if (LLView::sDebugMouseHandling) - { - LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " not handled by view" << LL_ENDL; - } - } - - // Do not allow tool manager to handle mouseclicks if we have disconnected - if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) - { - LLViewerEventRecorder::instance().clear_xui(); + // only send mouse clicks to UI if UI is visible + if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + + if (down) + { + buttonstatestr = "down" ; + } + else + { + buttonstatestr = "up" ; + } + + switch (clicktype) + { + case CLICK_LEFT: + mLeftMouseDown = down; + buttonname = "Left"; + break; + case CLICK_RIGHT: + mRightMouseDown = down; + buttonname = "Right"; + break; + case CLICK_MIDDLE: + mMiddleMouseDown = down; + buttonname = "Middle"; + break; + case CLICK_DOUBLELEFT: + mLeftMouseDown = down; + buttonname = "Left Double Click"; + break; + case CLICK_BUTTON4: + buttonname = "Button 4"; + break; + case CLICK_BUTTON5: + buttonname = "Button 5"; + break; + default: + break; // COUNT and NONE + } + + LLView::sMouseHandlerMessage.clear(); + + if (gMenuBarView) + { + // stop ALT-key access to menu + gMenuBarView->resetMenuTrigger(); + } + + if (gDebugClicks) + { + LL_INFOS() << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << LL_ENDL; + } + + // Make sure we get a corresponding mouseup event, even if the mouse leaves the window + if (down) + mWindow->captureMouse(); + else + mWindow->releaseMouse(); + + // Indicate mouse was active + LLUI::getInstance()->resetMouseIdleTimer(); + + // Don't let the user move the mouse out of the window until mouse up. + if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) + { + mWindow->setMouseClipping(down); + } + + LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); + if( mouse_captor ) + { + S32 local_x; + S32 local_y; + mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << LL_ENDL; + } + + BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down); + if (r) { + + LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << LL_ENDL; + + LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y); + LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname)); + + } + else if (down && clicktype == CLICK_RIGHT) + { + handlePieMenu(x, y, mask); + r = TRUE; + } + return r; + } + + // Mark the click as handled and return if we aren't within the root view to avoid spurious bugs + if( !mRootView->pointInView(x, y) ) + { + return TRUE; + } + // Give the UI views a chance to process the click + + BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ; + if (r) + { + + LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << LL_ENDL; + + LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y); + + // Clear local coords - this was a click on root window so these are not needed + // By not including them, this allows the test skeleton generation tool to be smarter when generating code + // the code generator can be smarter because when local coords are present it can try the xui path with local coords + // and fallback to global coordinates only if needed. + // The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element + // (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA) + // For this reason it's best to provide hints where possible here by leaving out local coordinates + LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1); + LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname); + + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << LL_ENDL; + } + return TRUE; + } else if (LLView::sDebugMouseHandling) + { + LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " not handled by view" << LL_ENDL; + } + } + + // Do not allow tool manager to handle mouseclicks if we have disconnected + if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) + { + LLViewerEventRecorder::instance().clear_xui(); is_toolmgr_action = true; - return TRUE; - } + return TRUE; + } - if (down && clicktype == CLICK_RIGHT) - { - handlePieMenu(x, y, mask); - return TRUE; - } + if (down && clicktype == CLICK_RIGHT) + { + handlePieMenu(x, y, mask); + return TRUE; + } - // If we got this far on a down-click, it wasn't handled. - // Up-clicks, though, are always handled as far as the OS is concerned. - BOOL default_rtn = !down; - return default_rtn; + // If we got this far on a down-click, it wasn't handled. + // Up-clicks, though, are always handled as far as the OS is concerned. + BOOL default_rtn = !down; + return default_rtn; } BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1173,7 +1173,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask else { mMouseDownTimer.reset(); - } + } BOOL down = TRUE; //handleMouse() loops back to LLViewerWindow::handleAnyMouseClick return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down); @@ -1181,14 +1181,14 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) { - // try handling as a double-click first, then a single-click if that - // wasn't handled. - BOOL down = TRUE; - if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down)) - { - return TRUE; - } - return handleMouseDown(window, pos, mask); + // try handling as a double-click first, then a single-click if that + // wasn't handled. + BOOL down = TRUE; + if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down)) + { + return TRUE; + } + return handleMouseDown(window, pos, mask); } BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1202,177 +1202,177 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) } BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = TRUE; - return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); + BOOL down = TRUE; + return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); } BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = FALSE; - return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); + BOOL down = FALSE; + return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); } BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = TRUE; - gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); - - // Always handled as far as the OS is concerned. - return TRUE; + BOOL down = TRUE; + gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); + + // Always handled as far as the OS is concerned. + return TRUE; } LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data) { - LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE; - - const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop"); - const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop"); - - if ( prim_media_dnd_enabled || slurl_dnd_enabled ) - { - switch(action) - { - // Much of the handling for these two cases is the same. - case LLWindowCallbacks::DNDA_TRACK: - case LLWindowCallbacks::DNDA_DROPPED: - case LLWindowCallbacks::DNDA_START_TRACKING: - { - bool drop = (LLWindowCallbacks::DNDA_DROPPED == action); - - if (slurl_dnd_enabled) - { - LLSLURL dropped_slurl(data); - if(dropped_slurl.isSpatial()) - { - if (drop) - { - LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), LLCommandHandler::NAV_TYPE_CLICKED, NULL, true ); - return LLWindowCallbacks::DND_MOVE; - } - return LLWindowCallbacks::DND_COPY; - } - } - - if (prim_media_dnd_enabled) - { - LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, - TRUE /* pick_transparent */, + LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE; + + const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop"); + const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop"); + + if ( prim_media_dnd_enabled || slurl_dnd_enabled ) + { + switch(action) + { + // Much of the handling for these two cases is the same. + case LLWindowCallbacks::DNDA_TRACK: + case LLWindowCallbacks::DNDA_DROPPED: + case LLWindowCallbacks::DNDA_START_TRACKING: + { + bool drop = (LLWindowCallbacks::DNDA_DROPPED == action); + + if (slurl_dnd_enabled) + { + LLSLURL dropped_slurl(data); + if(dropped_slurl.isSpatial()) + { + if (drop) + { + LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), LLCommandHandler::NAV_TYPE_CLICKED, NULL, true ); + return LLWindowCallbacks::DND_MOVE; + } + return LLWindowCallbacks::DND_COPY; + } + } + + if (prim_media_dnd_enabled) + { + LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, + TRUE /* pick_transparent */, FALSE /* pick_rigged */); - S32 object_face = pick_info.mObjectFace; - std::string url = data; - - LL_DEBUGS() << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << LL_ENDL; - - LLVOVolume *obj = dynamic_cast(static_cast(pick_info.getObject())); - - if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty()) - { - LLTextureEntry *te = obj->getTE(object_face); - - // can modify URL if we can modify the object or we have navigate permissions - bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT ); - - if (te && allow_modify_url ) - { - if (drop) - { - // object does NOT have media already - if ( ! te->hasMedia() ) - { - // we are allowed to modify the object - if ( obj->permModify() ) - { - // Create new media entry - LLSD media_data; - // XXX Should we really do Home URL too? - media_data[LLMediaEntry::HOME_URL_KEY] = url; - media_data[LLMediaEntry::CURRENT_URL_KEY] = url; - media_data[LLMediaEntry::AUTO_PLAY_KEY] = true; - obj->syncMediaData(object_face, media_data, true, true); - // XXX This shouldn't be necessary, should it ?!? - if (obj->getMediaImpl(object_face)) - obj->getMediaImpl(object_face)->navigateReload(); - obj->sendMediaDataUpdate(); - - result = LLWindowCallbacks::DND_COPY; - } - } - else - // object HAS media already - { - // URL passes the whitelist - if (te->getMediaData()->checkCandidateUrl( url ) ) - { - // just navigate to the URL - if (obj->getMediaImpl(object_face)) - { - obj->getMediaImpl(object_face)->navigateTo(url); - } - else - { - // This is very strange. Navigation should - // happen via the Impl, but we don't have one. - // This sends it to the server, which /should/ - // trigger us getting it. Hopefully. - LLSD media_data; - media_data[LLMediaEntry::CURRENT_URL_KEY] = url; - obj->syncMediaData(object_face, media_data, true, true); - obj->sendMediaDataUpdate(); - } - result = LLWindowCallbacks::DND_LINK; - - } - } - LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); - mDragHoveredObject = NULL; - - } - else - { - // Check the whitelist, if there's media (otherwise just show it) - if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url)) - { - if ( obj != mDragHoveredObject) - { - // Highlight the dragged object - LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); - mDragHoveredObject = obj; - LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject); - } - result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK; - - } - } - } - } - } - } - break; - - case LLWindowCallbacks::DNDA_STOP_TRACKING: - // The cleanup case below will make sure things are unhilighted if necessary. - break; - } - - if (prim_media_dnd_enabled && - result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull()) - { - LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); - mDragHoveredObject = NULL; - } - } - - return result; + S32 object_face = pick_info.mObjectFace; + std::string url = data; + + LL_DEBUGS() << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << LL_ENDL; + + LLVOVolume *obj = dynamic_cast(static_cast(pick_info.getObject())); + + if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty()) + { + LLTextureEntry *te = obj->getTE(object_face); + + // can modify URL if we can modify the object or we have navigate permissions + bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT ); + + if (te && allow_modify_url ) + { + if (drop) + { + // object does NOT have media already + if ( ! te->hasMedia() ) + { + // we are allowed to modify the object + if ( obj->permModify() ) + { + // Create new media entry + LLSD media_data; + // XXX Should we really do Home URL too? + media_data[LLMediaEntry::HOME_URL_KEY] = url; + media_data[LLMediaEntry::CURRENT_URL_KEY] = url; + media_data[LLMediaEntry::AUTO_PLAY_KEY] = true; + obj->syncMediaData(object_face, media_data, true, true); + // XXX This shouldn't be necessary, should it ?!? + if (obj->getMediaImpl(object_face)) + obj->getMediaImpl(object_face)->navigateReload(); + obj->sendMediaDataUpdate(); + + result = LLWindowCallbacks::DND_COPY; + } + } + else + // object HAS media already + { + // URL passes the whitelist + if (te->getMediaData()->checkCandidateUrl( url ) ) + { + // just navigate to the URL + if (obj->getMediaImpl(object_face)) + { + obj->getMediaImpl(object_face)->navigateTo(url); + } + else + { + // This is very strange. Navigation should + // happen via the Impl, but we don't have one. + // This sends it to the server, which /should/ + // trigger us getting it. Hopefully. + LLSD media_data; + media_data[LLMediaEntry::CURRENT_URL_KEY] = url; + obj->syncMediaData(object_face, media_data, true, true); + obj->sendMediaDataUpdate(); + } + result = LLWindowCallbacks::DND_LINK; + + } + } + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = NULL; + + } + else + { + // Check the whitelist, if there's media (otherwise just show it) + if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url)) + { + if ( obj != mDragHoveredObject) + { + // Highlight the dragged object + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = obj; + LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject); + } + result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK; + + } + } + } + } + } + } + break; + + case LLWindowCallbacks::DNDA_STOP_TRACKING: + // The cleanup case below will make sure things are unhilighted if necessary. + break; + } + + if (prim_media_dnd_enabled && + result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull()) + { + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); + mDragHoveredObject = NULL; + } + } + + return result; } BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = FALSE; - gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); - - // Always handled as far as the OS is concerned. - return TRUE; + BOOL down = FALSE; + gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); + + // Always handled as far as the OS is concerned. + return TRUE; } BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down) @@ -1406,32 +1406,32 @@ BOOL LLViewerWindow::handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK ma // WARNING: this is potentially called multiple times per frame void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask) { - S32 x = pos.mX; - S32 y = pos.mY; + S32 x = pos.mX; + S32 y = pos.mY; - x = ll_round((F32)x / mDisplayScale.mV[VX]); - y = ll_round((F32)y / mDisplayScale.mV[VY]); + x = ll_round((F32)x / mDisplayScale.mV[VX]); + y = ll_round((F32)y / mDisplayScale.mV[VY]); - mMouseInWindow = TRUE; + mMouseInWindow = TRUE; - // Save mouse point for access during idle() and display() + // Save mouse point for access during idle() and display() - LLCoordGL mouse_point(x, y); + LLCoordGL mouse_point(x, y); - if (mouse_point != mCurrentMousePoint) - { - LLUI::getInstance()->resetMouseIdleTimer(); - } + if (mouse_point != mCurrentMousePoint) + { + LLUI::getInstance()->resetMouseIdleTimer(); + } - saveLastMouse(mouse_point); + saveLastMouse(mouse_point); - mWindow->showCursorFromMouseMove(); + mWindow->showCursorFromMouseMove(); - if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME - && !gDisconnected) - { - gAgent.clearAFK(); - } + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME + && !gDisconnected) + { + gAgent.clearAFK(); + } } void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1452,114 +1452,114 @@ void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK m void LLViewerWindow::handleMouseLeave(LLWindow *window) { - // Note: we won't get this if we have captured the mouse. - llassert( gFocusMgr.getMouseCapture() == NULL ); - mMouseInWindow = FALSE; - LLToolTipMgr::instance().blockToolTips(); + // Note: we won't get this if we have captured the mouse. + llassert( gFocusMgr.getMouseCapture() == NULL ); + mMouseInWindow = FALSE; + LLToolTipMgr::instance().blockToolTips(); } BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) { - // User has indicated they want to close, but we may need to ask - // about modified documents. - LLAppViewer::instance()->userQuit(); - // Don't quit immediately - return FALSE; + // User has indicated they want to close, but we may need to ask + // about modified documents. + LLAppViewer::instance()->userQuit(); + // Don't quit immediately + return FALSE; } void LLViewerWindow::handleQuit(LLWindow *window) { - if (gNonInteractive) - { - LLAppViewer::instance()->requestQuit(); - } - else - { - LL_INFOS() << "Window forced quit" << LL_ENDL; - LLAppViewer::instance()->forceQuit(); - } + if (gNonInteractive) + { + LLAppViewer::instance()->requestQuit(); + } + else + { + LL_INFOS() << "Window forced quit" << LL_ENDL; + LLAppViewer::instance()->forceQuit(); + } } void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height) { - reshape(width, height); - mResDirty = true; + reshape(width, height); + mResDirty = true; } // The top-level window has gained focus (e.g. via ALT-TAB) void LLViewerWindow::handleFocus(LLWindow *window) { - gFocusMgr.setAppHasFocus(TRUE); - LLModalDialog::onAppFocusGained(); + gFocusMgr.setAppHasFocus(TRUE); + LLModalDialog::onAppFocusGained(); - gAgent.onAppFocusGained(); - LLToolMgr::getInstance()->onAppFocusGained(); + gAgent.onAppFocusGained(); + LLToolMgr::getInstance()->onAppFocusGained(); - // See if we're coming in with modifier keys held down - if (gKeyboard) - { - gKeyboard->resetMaskKeys(); - } + // See if we're coming in with modifier keys held down + if (gKeyboard) + { + gKeyboard->resetMaskKeys(); + } - // resume foreground running timer - // since we artifically limit framerate when not frontmost - gForegroundTime.unpause(); + // resume foreground running timer + // since we artifically limit framerate when not frontmost + gForegroundTime.unpause(); } // The top-level window has lost focus (e.g. via ALT-TAB) void LLViewerWindow::handleFocusLost(LLWindow *window) { - gFocusMgr.setAppHasFocus(FALSE); - //LLModalDialog::onAppFocusLost(); - LLToolMgr::getInstance()->onAppFocusLost(); - gFocusMgr.setMouseCapture( NULL ); + gFocusMgr.setAppHasFocus(FALSE); + //LLModalDialog::onAppFocusLost(); + LLToolMgr::getInstance()->onAppFocusLost(); + gFocusMgr.setMouseCapture( NULL ); - if (gMenuBarView) - { - // stop ALT-key access to menu - gMenuBarView->resetMenuTrigger(); - } + if (gMenuBarView) + { + // stop ALT-key access to menu + gMenuBarView->resetMenuTrigger(); + } - // restore mouse cursor - showCursor(); - getWindow()->setMouseClipping(FALSE); + // restore mouse cursor + showCursor(); + getWindow()->setMouseClipping(FALSE); - // If losing focus while keys are down, handle them as + // If losing focus while keys are down, handle them as // an 'up' to correctly release states, then reset states - if (gKeyboard) - { + if (gKeyboard) + { gKeyboard->resetKeyDownAndHandle(); - gKeyboard->resetKeys(); - } + gKeyboard->resetKeys(); + } - // pause timer that tracks total foreground running time - gForegroundTime.pause(); + // pause timer that tracks total foreground running time + gForegroundTime.pause(); } BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) { - // Handle non-consuming global keybindings, like voice + // Handle non-consuming global keybindings, like voice // Never affects event processing. gViewerInput.handleGlobalBindsKeyDown(key, mask); - if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) - { - gAgent.clearAFK(); - } - - // *NOTE: We want to interpret KEY_RETURN later when it arrives as - // a Unicode char, not as a keydown. Otherwise when client frame - // rate is really low, hitting return sends your chat text before - // it's all entered/processed. - if (key == KEY_RETURN && mask == MASK_NONE) - { + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) + { + gAgent.clearAFK(); + } + + // *NOTE: We want to interpret KEY_RETURN later when it arrives as + // a Unicode char, not as a keydown. Otherwise when client frame + // rate is really low, hitting return sends your chat text before + // it's all entered/processed. + if (key == KEY_RETURN && mask == MASK_NONE) + { // RIDER: although, at times some of the controlls (in particular the CEF viewer // would like to know about the KEYDOWN for an enter key... so ask and pass it along. LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if (keyboard_focus && !keyboard_focus->wantsReturnKey()) - return FALSE; - } + return FALSE; + } // remaps, handles ignored cases and returns back to viewer window. return gViewerInput.handleKey(key, mask, repeated); @@ -1567,25 +1567,25 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) { - // Handle non-consuming global keybindings, like voice + // Handle non-consuming global keybindings, like voice // Never affects event processing. gViewerInput.handleGlobalBindsKeyUp(key, mask); - // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera - LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); - if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) - { - tool_inspectp->keyUp(key, mask); - } + // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera + LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); + if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) + { + tool_inspectp->keyUp(key, mask); + } - return gViewerInput.handleKeyUp(key, mask); + return gViewerInput.handleKeyUp(key, mask); } void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) { - LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); - gViewerInput.scanKey(key, key_down, key_up, key_level); - return; // Be clear this function returns nothing + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); + gViewerInput.scanKey(key, key_down, key_up, key_level); + return; // Be clear this function returns nothing } @@ -1593,45 +1593,45 @@ void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) { - if (activated) - { - mActive = true; - send_agent_resume(); - gAgent.clearAFK(); - - // Unmute audio - audio_update_volume(); - } - else - { - mActive = false; - - // if the user has chosen to go Away automatically after some time, then go Away when minimizing - if (gSavedSettings.getS32("AFKTimeout")) - { - gAgent.setAFK(); - } - - // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues - if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) - { - gAgentCamera.changeCameraToDefault(); - } - - send_agent_pause(); - - // Mute audio - audio_update_volume(); - } - return TRUE; + if (activated) + { + mActive = true; + send_agent_resume(); + gAgent.clearAFK(); + + // Unmute audio + audio_update_volume(); + } + else + { + mActive = false; + + // if the user has chosen to go Away automatically after some time, then go Away when minimizing + if (gSavedSettings.getS32("AFKTimeout")) + { + gAgent.setAFK(); + } + + // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + gAgentCamera.changeCameraToDefault(); + } + + send_agent_pause(); + + // Mute audio + audio_update_volume(); + } + return TRUE; } BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating) { - //if (!activating) gAgentCamera.changeCameraToDefault(); + //if (!activating) gAgentCamera.changeCameraToDefault(); - LLViewerJoystick::getInstance()->setNeedsReset(true); - return FALSE; + LLViewerJoystick::getInstance()->setNeedsReset(true); + return FALSE; } @@ -1642,108 +1642,108 @@ void LLViewerWindow::handleMenuSelect(LLWindow *window, S32 menu_item) BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height) { - // *TODO: Enable similar information output for other platforms? DK 2011-02-18 + // *TODO: Enable similar information output for other platforms? DK 2011-02-18 #if LL_WINDOWS - if (gHeadlessClient) - { - HWND window_handle = (HWND)window->getPlatformWindow(); - PAINTSTRUCT ps; - HDC hdc; - - RECT wnd_rect; - wnd_rect.left = 0; - wnd_rect.top = 0; - wnd_rect.bottom = 200; - wnd_rect.right = 500; - - hdc = BeginPaint(window_handle, &ps); - //SetBKColor(hdc, RGB(255, 255, 255)); - FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); - - std::string temp_str; - LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); - temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ - recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), - recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS), - recording.getLastValue(LLStatViewer::SIM_TIME_DILATION)); - S32 len = temp_str.length(); - TextOutA(hdc, 0, 0, temp_str.c_str(), len); - - - LLVector3d pos_global = gAgent.getPositionGlobal(); - temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]); - len = temp_str.length(); - TextOutA(hdc, 0, 25, temp_str.c_str(), len); - - TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61); - EndPaint(window_handle, &ps); - return TRUE; - } + if (gHeadlessClient) + { + HWND window_handle = (HWND)window->getPlatformWindow(); + PAINTSTRUCT ps; + HDC hdc; + + RECT wnd_rect; + wnd_rect.left = 0; + wnd_rect.top = 0; + wnd_rect.bottom = 200; + wnd_rect.right = 500; + + hdc = BeginPaint(window_handle, &ps); + //SetBKColor(hdc, RGB(255, 255, 255)); + FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); + + std::string temp_str; + LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); + temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ + recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), + recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS), + recording.getLastValue(LLStatViewer::SIM_TIME_DILATION)); + S32 len = temp_str.length(); + TextOutA(hdc, 0, 0, temp_str.c_str(), len); + + + LLVector3d pos_global = gAgent.getPositionGlobal(); + temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]); + len = temp_str.length(); + TextOutA(hdc, 0, 25, temp_str.c_str(), len); + + TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61); + EndPaint(window_handle, &ps); + return TRUE; + } #endif - return FALSE; + return FALSE; } void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks) { - handleScrollWheel( clicks ); + handleScrollWheel( clicks ); } void LLViewerWindow::handleScrollHWheel(LLWindow *window, S32 clicks) { - handleScrollHWheel(clicks); + handleScrollHWheel(clicks); } void LLViewerWindow::handleWindowBlock(LLWindow *window) { - send_agent_pause(); + send_agent_pause(); } void LLViewerWindow::handleWindowUnblock(LLWindow *window) { - send_agent_resume(); + send_agent_resume(); } void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data) { - const S32 SLURL_MESSAGE_TYPE = 0; - switch (data_type) - { - case SLURL_MESSAGE_TYPE: - // received URL - std::string url = (const char*)data; - LLMediaCtrl* web = NULL; - const bool trusted_browser = false; - // don't treat slapps coming from external browsers as "clicks" as this would bypass throttling - if (LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_EXTERNAL, web, trusted_browser)) - { - // bring window to foreground, as it has just been "launched" from a URL - mWindow->bringToFront(); - } - break; - } + const S32 SLURL_MESSAGE_TYPE = 0; + switch (data_type) + { + case SLURL_MESSAGE_TYPE: + // received URL + std::string url = (const char*)data; + LLMediaCtrl* web = NULL; + const bool trusted_browser = false; + // don't treat slapps coming from external browsers as "clicks" as this would bypass throttling + if (LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_EXTERNAL, web, trusted_browser)) + { + // bring window to foreground, as it has just been "launched" from a URL + mWindow->bringToFront(); + } + break; + } } BOOL LLViewerWindow::handleTimerEvent(LLWindow *window) { //TODO: just call this every frame from gatherInput instead of using a convoluted 30fps timer callback - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - LLViewerJoystick::getInstance()->updateStatus(); - return TRUE; - } - return FALSE; + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + LLViewerJoystick::getInstance()->updateStatus(); + return TRUE; + } + return FALSE; } BOOL LLViewerWindow::handleDeviceChange(LLWindow *window) { - // give a chance to use a joystick after startup (hot-plugging) - if (!LLViewerJoystick::getInstance()->isJoystickInitialized() ) - { - LLViewerJoystick::getInstance()->init(true); - return TRUE; - } - return FALSE; + // give a chance to use a joystick after startup (hot-plugging) + if (!LLViewerJoystick::getInstance()->isJoystickInitialized() ) + { + LLViewerJoystick::getInstance()->init(true); + return TRUE; + } + return FALSE; } BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) @@ -1763,157 +1763,157 @@ BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 BOOL LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window) { - LLCoordScreen window_rect; - mWindow->getSize(&window_rect); - reshape(window_rect.mX, window_rect.mY); - return TRUE; + LLCoordScreen window_rect; + mWindow->getSize(&window_rect); + reshape(window_rect.mX, window_rect.mY); + return TRUE; } void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg) { - LLAppViewer::instance()->pingMainloopTimeout(msg); + LLAppViewer::instance()->pingMainloopTimeout(msg); } void LLViewerWindow::handleResumeWatchdog(LLWindow *window) { - LLAppViewer::instance()->resumeMainloopTimeout(); + LLAppViewer::instance()->resumeMainloopTimeout(); } void LLViewerWindow::handlePauseWatchdog(LLWindow *window) { - LLAppViewer::instance()->pauseMainloopTimeout(); + LLAppViewer::instance()->pauseMainloopTimeout(); } //virtual std::string LLViewerWindow::translateString(const char* tag) { - return LLTrans::getString( std::string(tag) ); + return LLTrans::getString( std::string(tag) ); } //virtual std::string LLViewerWindow::translateString(const char* tag, - const std::map& args) -{ - // LLTrans uses a special subclass of std::string for format maps, - // but we must use std::map<> in these callbacks, otherwise we create - // a dependency between LLWindow and LLFormatMapString. So copy the data. - LLStringUtil::format_map_t args_copy; - std::map::const_iterator it = args.begin(); - for ( ; it != args.end(); ++it) - { - args_copy[it->first] = it->second; - } - return LLTrans::getString( std::string(tag), args_copy); + const std::map& args) +{ + // LLTrans uses a special subclass of std::string for format maps, + // but we must use std::map<> in these callbacks, otherwise we create + // a dependency between LLWindow and LLFormatMapString. So copy the data. + LLStringUtil::format_map_t args_copy; + std::map::const_iterator it = args.begin(); + for ( ; it != args.end(); ++it) + { + args_copy[it->first] = it->second; + } + return LLTrans::getString( std::string(tag), args_copy); } // // Classes // LLViewerWindow::LLViewerWindow(const Params& p) -: mWindow(NULL), - mActive(true), - mUIVisible(true), - mWindowRectRaw(0, p.height, p.width, 0), - mWindowRectScaled(0, p.height, p.width, 0), - mWorldViewRectRaw(0, p.height, p.width, 0), - mLeftMouseDown(FALSE), - mMiddleMouseDown(FALSE), - mRightMouseDown(FALSE), - mMouseInWindow( FALSE ), +: mWindow(NULL), + mActive(true), + mUIVisible(true), + mWindowRectRaw(0, p.height, p.width, 0), + mWindowRectScaled(0, p.height, p.width, 0), + mWorldViewRectRaw(0, p.height, p.width, 0), + mLeftMouseDown(FALSE), + mMiddleMouseDown(FALSE), + mRightMouseDown(FALSE), + mMouseInWindow( FALSE ), mAllowMouseDragging(TRUE), mMouseDownTimer(), - mLastMask( MASK_NONE ), - mToolStored( NULL ), - mHideCursorPermanent( FALSE ), - mCursorHidden(FALSE), - mIgnoreActivate( FALSE ), - mResDirty(false), - mStatesDirty(false), - mCurrResolutionIndex(0), - mProgressView(NULL) -{ - // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to - // pass its value right now. Instead, pass it a nullary function that - // will, when we later need it, return the value of gKeyboard. - // boost::lambda::var() constructs such a functor on the fly. - mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard))); - mViewerWindowListener.reset(new LLViewerWindowListener(this)); - - mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything)); - mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible")); - mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert")); - mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal")); - - bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications"); - LLNotifications::instance().setIgnoreAllNotifications(ignore); - if (ignore) - { - LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL; - } - - - /* - LLWindowCallbacks* callbacks, - const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, - BOOL fullscreen, - BOOL clearBg, - BOOL disable_vsync, - BOOL ignore_pixel_depth, - U32 fsaa_samples) - */ - // create window + mLastMask( MASK_NONE ), + mToolStored( NULL ), + mHideCursorPermanent( FALSE ), + mCursorHidden(FALSE), + mIgnoreActivate( FALSE ), + mResDirty(false), + mStatesDirty(false), + mCurrResolutionIndex(0), + mProgressView(NULL) +{ + // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to + // pass its value right now. Instead, pass it a nullary function that + // will, when we later need it, return the value of gKeyboard. + // boost::lambda::var() constructs such a functor on the fly. + mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard))); + mViewerWindowListener.reset(new LLViewerWindowListener(this)); + + mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything)); + mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible")); + mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert")); + mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal")); + + bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications"); + LLNotifications::instance().setIgnoreAllNotifications(ignore); + if (ignore) + { + LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL; + } + + + /* + LLWindowCallbacks* callbacks, + const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, + BOOL fullscreen, + BOOL clearBg, + BOOL disable_vsync, + BOOL ignore_pixel_depth, + U32 fsaa_samples) + */ + // create window U32 max_core_count = gSavedSettings.getU32("EmulateCoreCount"); U32 max_vram = gSavedSettings.getU32("RenderMaxVRAMBudget"); F32 max_gl_version = gSavedSettings.getF32("RenderMaxOpenGLVersion"); - - mWindow = LLWindowManager::createWindow(this, - p.title, p.name, p.x, p.y, p.width, p.height, 0, - p.fullscreen, - gHeadlessClient, - gSavedSettings.getBOOL("RenderVSyncEnable"), - !gHeadlessClient, - p.ignore_pixel_depth, - 0, + + mWindow = LLWindowManager::createWindow(this, + p.title, p.name, p.x, p.y, p.width, p.height, 0, + p.fullscreen, + gHeadlessClient, + gSavedSettings.getBOOL("RenderVSyncEnable"), + !gHeadlessClient, + p.ignore_pixel_depth, + 0, max_core_count, max_vram, max_gl_version); //don't use window level anti-aliasing - if (NULL == mWindow) - { - LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate")); - - LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << LL_ENDL ; + if (NULL == mWindow) + { + LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate")); + + LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << LL_ENDL ; - ms_sleep(5000) ; //wait for 5 seconds. + ms_sleep(5000) ; //wait for 5 seconds. - LLSplashScreen::update(LLTrans::getString("ShuttingDown")); + LLSplashScreen::update(LLTrans::getString("ShuttingDown")); #if LL_LINUX - LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information." - << LL_ENDL; + LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information." + << LL_ENDL; #else - LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings" - << LL_ENDL; + LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings" + << LL_ENDL; #endif LLAppViewer::instance()->fastQuit(1); - } + } else if (!LLViewerShaderMgr::sInitialized) { //immediately initialize shaders LLViewerShaderMgr::sInitialized = TRUE; LLViewerShaderMgr::instance()->setShaders(); } - - if (!LLAppViewer::instance()->restoreErrorTrap()) - { + + if (!LLAppViewer::instance()->restoreErrorTrap()) + { // this always happens, so downgrading it to INFO - LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL; - } + LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL; + } - const bool do_not_enforce = false; - mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set - LLCoordScreen scr; + const bool do_not_enforce = false; + mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set + LLCoordScreen scr; mWindow->getSize(&scr); // Reset UI scale factor on first run if OS's display scaling is not 100% @@ -1926,90 +1926,90 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.setBOOL("ResetUIScaleOnFirstRun", FALSE); } - // Get the real window rect the window was created with (since there are various OS-dependent reasons why - // the size of a window or fullscreen context may have been adjusted slightly...) - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); - - mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); - mDisplayScale *= ui_scale_factor; - LLUI::setScaleFactor(mDisplayScale); - - { - LLCoordWindow size; - mWindow->getSize(&size); - mWindowRectRaw.set(0, size.mY, size.mX, 0); - mWindowRectScaled.set(0, ll_round((F32)size.mY / mDisplayScale.mV[VY]), ll_round((F32)size.mX / mDisplayScale.mV[VX]), 0); - } - - LLFontManager::initClass(); - // Init font system, load default fonts and generate basic glyphs - // currently it takes aprox. 0.5 sec and we would load these fonts anyway - // before login screen. - LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), - mDisplayScale.mV[VX], - mDisplayScale.mV[VY], - gDirUtilp->getAppRODataDir()); - - // - // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off - // stuff like AGP if we think that it'll crash the viewer. - // - LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL; - - // Initialize OpenGL Renderer - LLVertexBuffer::initClass(mWindow); - LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - if (!gGL.init(true)) + // Get the real window rect the window was created with (since there are various OS-dependent reasons why + // the size of a window or fullscreen context may have been adjusted slightly...) + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); + + mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); + mDisplayScale *= ui_scale_factor; + LLUI::setScaleFactor(mDisplayScale); + + { + LLCoordWindow size; + mWindow->getSize(&size); + mWindowRectRaw.set(0, size.mY, size.mX, 0); + mWindowRectScaled.set(0, ll_round((F32)size.mY / mDisplayScale.mV[VY]), ll_round((F32)size.mX / mDisplayScale.mV[VX]), 0); + } + + LLFontManager::initClass(); + // Init font system, load default fonts and generate basic glyphs + // currently it takes aprox. 0.5 sec and we would load these fonts anyway + // before login screen. + LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), + mDisplayScale.mV[VX], + mDisplayScale.mV[VY], + gDirUtilp->getAppRODataDir()); + + // + // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off + // stuff like AGP if we think that it'll crash the viewer. + // + LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL; + + // Initialize OpenGL Renderer + LLVertexBuffer::initClass(mWindow); + LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; + if (!gGL.init(true)) { LLError::LLUserWarningMsg::show(LLTrans::getString("MBVideoDrvErr")); LL_ERRS() << "gGL not initialized" << LL_ENDL; } - if (LLFeatureManager::getInstance()->isSafe() - || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) - || (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString()) - || (gSavedSettings.getBOOL("ProbeHardwareOnStartup"))) - { - LLFeatureManager::getInstance()->applyRecommendedSettings(); - gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); - } - - // If we crashed while initializng GL stuff last time, disable certain features - if (gSavedSettings.getBOOL("RenderInitError")) - { - mInitAlert = "DisplaySettingsNoShaders"; - LLFeatureManager::getInstance()->setGraphicsLevel(0, false); - gSavedSettings.setU32("RenderQualityPerformance", 0); - } - - // Init the image list. Must happen after GL is initialized and before the images that - // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images. + if (LLFeatureManager::getInstance()->isSafe() + || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) + || (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString()) + || (gSavedSettings.getBOOL("ProbeHardwareOnStartup"))) + { + LLFeatureManager::getInstance()->applyRecommendedSettings(); + gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); + } + + // If we crashed while initializng GL stuff last time, disable certain features + if (gSavedSettings.getBOOL("RenderInitError")) + { + mInitAlert = "DisplaySettingsNoShaders"; + LLFeatureManager::getInstance()->setGraphicsLevel(0, false); + gSavedSettings.setU32("RenderQualityPerformance", 0); + } + + // Init the image list. Must happen after GL is initialized and before the images that + // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images. LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreadedTextures"), gSavedSettings.getBOOL("RenderGLMultiThreadedMedia")); - gTextureList.init(); - LLViewerTextureManager::init() ; - gBumpImageList.init(); - + gTextureList.init(); + LLViewerTextureManager::init() ; + gBumpImageList.init(); + // Create container for all sub-views - LLView::Params rvp; - rvp.name("root"); - rvp.rect(mWindowRectScaled); - rvp.mouse_opaque(false); - rvp.follows.flags(FOLLOWS_NONE); - mRootView = LLUICtrlFactory::create(rvp); - LLUI::getInstance()->setRootView(mRootView); + LLView::Params rvp; + rvp.name("root"); + rvp.rect(mWindowRectScaled); + rvp.mouse_opaque(false); + rvp.follows.flags(FOLLOWS_NONE); + mRootView = LLUICtrlFactory::create(rvp); + LLUI::getInstance()->setRootView(mRootView); - // Make avatar head look forward at start - mCurrentMousePoint.mX = getWindowWidthScaled() / 2; - mCurrentMousePoint.mY = getWindowHeightScaled() / 2; + // Make avatar head look forward at start + mCurrentMousePoint.mX = getWindowWidthScaled() / 2; + mCurrentMousePoint.mY = getWindowHeightScaled() / 2; - gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle"); - mOverlayTitle = gSavedSettings.getString("OverlayTitle"); - // Can't have spaces in settings.ini strings, so use underscores instead and convert them. - LLStringUtil::replaceChar(mOverlayTitle, '_', ' '); + gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle"); + mOverlayTitle = gSavedSettings.getString("OverlayTitle"); + // Can't have spaces in settings.ini strings, so use underscores instead and convert them. + LLStringUtil::replaceChar(mOverlayTitle, '_', ' '); - mDebugText = new LLDebugText(this); + mDebugText = new LLDebugText(this); - mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); + mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); } std::string LLViewerWindow::getLastSnapshotDir() @@ -2019,8 +2019,8 @@ std::string LLViewerWindow::getLastSnapshotDir() void LLViewerWindow::initGLDefaults() { - // RN: Need this for translation and stretch manip. - gBox.prerender(); + // RN: Need this for translation and stretch manip. + gBox.prerender(); } struct MainPanel : public LLPanel @@ -2029,550 +2029,550 @@ struct MainPanel : public LLPanel void LLViewerWindow::initBase() { - S32 height = getWindowHeightScaled(); - S32 width = getWindowWidthScaled(); + S32 height = getWindowHeightScaled(); + S32 width = getWindowWidthScaled(); - LLRect full_window(0, height, width, 0); + LLRect full_window(0, height, width, 0); - //////////////////// - // - // Set the gamma - // + //////////////////// + // + // Set the gamma + // - F32 gamma = gSavedSettings.getF32("RenderGamma"); - if (gamma != 0.0f) - { - getWindow()->setGamma(gamma); - } + F32 gamma = gSavedSettings.getF32("RenderGamma"); + if (gamma != 0.0f) + { + getWindow()->setGamma(gamma); + } - // Create global views + // Create global views - // Login screen and main_view.xml need edit menus for preferences and browser - LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL; - initialize_edit_menu(); + // Login screen and main_view.xml need edit menus for preferences and browser + LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL; + initialize_edit_menu(); LLFontGL::loadCommonFonts(); - // Create the floater view at the start so that other views can add children to it. - // (But wait to add it as a child of the root view so that it will be in front of the - // other views.) - MainPanel* main_view = new MainPanel(); - if (!main_view->buildFromFile("main_view.xml")) - { - LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file main_view.xml, " - << "if this problem happens again, please validate your installation." << LL_ENDL; - } - main_view->setShape(full_window); - getRootView()->addChild(main_view); - - // placeholder widget that controls where "world" is rendered - mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); - mPopupView = main_view->getChild("popup_holder"); - mHintHolder = main_view->getChild("hint_holder")->getHandle(); - mLoginPanelHolder = main_view->getChild("login_panel_holder")->getHandle(); - - // Create the toolbar view - // Get a pointer to the toolbar view holder - LLPanel* panel_holder = main_view->getChild("toolbar_view_holder"); - // Load the toolbar view from file - gToolBarView = LLUICtrlFactory::getInstance()->createFromFile("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance()); - if (!gToolBarView) - { - LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, " - << "if this problem happens again, please validate your installation." << LL_ENDL; - } - gToolBarView->setShape(panel_holder->getLocalRect()); - // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI()) - gToolBarView->setVisible(FALSE); - - // Constrain floaters to inside the menu and status bar regions. - gFloaterView = main_view->getChild("Floater View"); - for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; ++i) - { - LLToolBar * toolbarp = gToolBarView->getToolbar((LLToolBarEnums::EToolBarLocation)i); - if (toolbarp) - { - toolbarp->getCenterLayoutPanel()->setReshapeCallback(boost::bind(&LLFloaterView::setToolbarRect, gFloaterView, _1, _2)); - } - } - gFloaterView->setFloaterSnapView(main_view->getChild("floater_snap_region")->getHandle()); - gSnapshotFloaterView = main_view->getChild("Snapshot Floater View"); - - // Console - llassert( !gConsole ); - LLConsole::Params cp; - cp.name("console"); - cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize")); - cp.rect(getChatConsoleRect()); - cp.persist_time(gSavedSettings.getF32("ChatPersistTime")); - cp.font_size_index(gSavedSettings.getS32("ChatFontSize")); - cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); - gConsole = LLUICtrlFactory::create(cp); - getRootView()->addChild(gConsole); - - // optionally forward warnings to chat console/chat floater - // for qa runs and dev builds + // Create the floater view at the start so that other views can add children to it. + // (But wait to add it as a child of the root view so that it will be in front of the + // other views.) + MainPanel* main_view = new MainPanel(); + if (!main_view->buildFromFile("main_view.xml")) + { + LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file main_view.xml, " + << "if this problem happens again, please validate your installation." << LL_ENDL; + } + main_view->setShape(full_window); + getRootView()->addChild(main_view); + + // placeholder widget that controls where "world" is rendered + mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); + mPopupView = main_view->getChild("popup_holder"); + mHintHolder = main_view->getChild("hint_holder")->getHandle(); + mLoginPanelHolder = main_view->getChild("login_panel_holder")->getHandle(); + + // Create the toolbar view + // Get a pointer to the toolbar view holder + LLPanel* panel_holder = main_view->getChild("toolbar_view_holder"); + // Load the toolbar view from file + gToolBarView = LLUICtrlFactory::getInstance()->createFromFile("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance()); + if (!gToolBarView) + { + LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, " + << "if this problem happens again, please validate your installation." << LL_ENDL; + } + gToolBarView->setShape(panel_holder->getLocalRect()); + // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI()) + gToolBarView->setVisible(FALSE); + + // Constrain floaters to inside the menu and status bar regions. + gFloaterView = main_view->getChild("Floater View"); + for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; ++i) + { + LLToolBar * toolbarp = gToolBarView->getToolbar((LLToolBarEnums::EToolBarLocation)i); + if (toolbarp) + { + toolbarp->getCenterLayoutPanel()->setReshapeCallback(boost::bind(&LLFloaterView::setToolbarRect, gFloaterView, _1, _2)); + } + } + gFloaterView->setFloaterSnapView(main_view->getChild("floater_snap_region")->getHandle()); + gSnapshotFloaterView = main_view->getChild("Snapshot Floater View"); + + // Console + llassert( !gConsole ); + LLConsole::Params cp; + cp.name("console"); + cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize")); + cp.rect(getChatConsoleRect()); + cp.persist_time(gSavedSettings.getF32("ChatPersistTime")); + cp.font_size_index(gSavedSettings.getS32("ChatFontSize")); + cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); + gConsole = LLUICtrlFactory::create(cp); + getRootView()->addChild(gConsole); + + // optionally forward warnings to chat console/chat floater + // for qa runs and dev builds #if !LL_RELEASE_FOR_DOWNLOAD - RecordToChatConsole::getInstance()->startRecorder(); + RecordToChatConsole::getInstance()->startRecorder(); #else - if(gSavedSettings.getBOOL("QAMode")) - { - RecordToChatConsole::getInstance()->startRecorder(); - } + if(gSavedSettings.getBOOL("QAMode")) + { + RecordToChatConsole::getInstance()->startRecorder(); + } #endif - gDebugView = getRootView()->getChild("DebugView"); - gDebugView->init(); - gToolTipView = getRootView()->getChild("tooltip view"); + gDebugView = getRootView()->getChild("DebugView"); + gDebugView->init(); + gToolTipView = getRootView()->getChild("tooltip view"); - // Initialize do not disturb response message when logged in - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse)); + // Initialize do not disturb response message when logged in + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse)); - // Add the progress bar view (startup view), which overrides everything - mProgressView = getRootView()->findChild("progress_view"); - setShowProgress(FALSE); - setProgressCancelButtonVisible(FALSE); + // Add the progress bar view (startup view), which overrides everything + mProgressView = getRootView()->findChild("progress_view"); + setShowProgress(FALSE); + setProgressCancelButtonVisible(FALSE); - gMenuHolder = getRootView()->getChild("Menu Holder"); - LLMenuGL::sMenuContainer = gMenuHolder; + gMenuHolder = getRootView()->getChild("Menu Holder"); + LLMenuGL::sMenuContainer = gMenuHolder; } void LLViewerWindow::initWorldUI() { - if (gNonInteractive) - { - gIMMgr = LLIMMgr::getInstance(); - LLNavigationBar::getInstance(); - gFloaterView->pushVisibleAll(FALSE); - return; - } - - S32 height = mRootView->getRect().getHeight(); - S32 width = mRootView->getRect().getWidth(); - LLRect full_window(0, height, width, 0); - - - gIMMgr = LLIMMgr::getInstance(); - - //getRootView()->sendChildToFront(gFloaterView); - //getRootView()->sendChildToFront(gSnapshotFloaterView); - - if (!gNonInteractive) - { - LLPanel* chiclet_container = getRootView()->getChild("chiclet_container"); - LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); - chiclet_bar->setShape(chiclet_container->getLocalRect()); - chiclet_bar->setFollowsAll(); - chiclet_container->addChild(chiclet_bar); - chiclet_container->setVisible(TRUE); - } - - LLRect morph_view_rect = full_window; - morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); - morph_view_rect.mTop = full_window.mTop - 32; - LLMorphView::Params mvp; - mvp.name("MorphView"); - mvp.rect(morph_view_rect); - mvp.visible(false); - gMorphView = LLUICtrlFactory::create(mvp); - getRootView()->addChild(gMorphView); - - LLWorldMapView::initClass(); - - // Force gFloaterWorldMap to initialize - LLFloaterReg::getInstance("world_map"); - - // Force gFloaterTools to initialize - LLFloaterReg::getInstance("build"); - - // Status bar - LLPanel* status_bar_container = getRootView()->getChild("status_bar_container"); - gStatusBar = new LLStatusBar(status_bar_container->getLocalRect()); - gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT); - gStatusBar->setShape(status_bar_container->getLocalRect()); - // sync bg color with menu bar - gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); + if (gNonInteractive) + { + gIMMgr = LLIMMgr::getInstance(); + LLNavigationBar::getInstance(); + gFloaterView->pushVisibleAll(FALSE); + return; + } + + S32 height = mRootView->getRect().getHeight(); + S32 width = mRootView->getRect().getWidth(); + LLRect full_window(0, height, width, 0); + + + gIMMgr = LLIMMgr::getInstance(); + + //getRootView()->sendChildToFront(gFloaterView); + //getRootView()->sendChildToFront(gSnapshotFloaterView); + + if (!gNonInteractive) + { + LLPanel* chiclet_container = getRootView()->getChild("chiclet_container"); + LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); + chiclet_bar->setShape(chiclet_container->getLocalRect()); + chiclet_bar->setFollowsAll(); + chiclet_container->addChild(chiclet_bar); + chiclet_container->setVisible(TRUE); + } + + LLRect morph_view_rect = full_window; + morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); + morph_view_rect.mTop = full_window.mTop - 32; + LLMorphView::Params mvp; + mvp.name("MorphView"); + mvp.rect(morph_view_rect); + mvp.visible(false); + gMorphView = LLUICtrlFactory::create(mvp); + getRootView()->addChild(gMorphView); + + LLWorldMapView::initClass(); + + // Force gFloaterWorldMap to initialize + LLFloaterReg::getInstance("world_map"); + + // Force gFloaterTools to initialize + LLFloaterReg::getInstance("build"); + + // Status bar + LLPanel* status_bar_container = getRootView()->getChild("status_bar_container"); + gStatusBar = new LLStatusBar(status_bar_container->getLocalRect()); + gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT); + gStatusBar->setShape(status_bar_container->getLocalRect()); + // sync bg color with menu bar + gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); // add InBack so that gStatusBar won't be drawn over menu status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/); status_bar_container->setVisible(TRUE); - // Navigation bar - LLView* nav_bar_container = getRootView()->getChild("nav_bar_container"); + // Navigation bar + LLView* nav_bar_container = getRootView()->getChild("nav_bar_container"); - LLNavigationBar* navbar = LLNavigationBar::getInstance(); - navbar->setShape(nav_bar_container->getLocalRect()); - navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get()); - nav_bar_container->addChild(navbar); - nav_bar_container->setVisible(TRUE); + LLNavigationBar* navbar = LLNavigationBar::getInstance(); + navbar->setShape(nav_bar_container->getLocalRect()); + navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get()); + nav_bar_container->addChild(navbar); + nav_bar_container->setVisible(TRUE); - if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) - { - navbar->setVisible(FALSE); - } + if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) + { + navbar->setVisible(FALSE); + } else { reshapeStatusBarContainer(); } - // Top Info bar - LLPanel* topinfo_bar_container = getRootView()->getChild("topinfo_bar_container"); - LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance(); - - topinfo_bar->setShape(topinfo_bar_container->getLocalRect()); - - topinfo_bar_container->addChild(topinfo_bar); - topinfo_bar_container->setVisible(TRUE); - - if (!gSavedSettings.getBOOL("ShowMiniLocationPanel")) - { - topinfo_bar->setVisible(FALSE); - } - - if ( gHUDView == NULL ) - { - LLRect hud_rect = full_window; - hud_rect.mBottom += 50; - if (gMenuBarView && gMenuBarView->isInVisibleChain()) - { - hud_rect.mTop -= gMenuBarView->getRect().getHeight(); - } - gHUDView = new LLHUDView(hud_rect); - getRootView()->addChild(gHUDView); - getRootView()->sendChildToBack(gHUDView); - } - - LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container"); - - LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); - panel_ssf_container->addChild(panel_stand_stop_flying); - - LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance(); - panel_ssf_container->addChild(panel_hide_beacon); - - panel_ssf_container->setVisible(TRUE); - - LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); - - // Load and make the toolbars visible - // Note: we need to load the toolbars only *after* the user is logged in and IW - if (gToolBarView) - { - gToolBarView->loadToolbars(); - gToolBarView->setVisible(TRUE); - } - - if (!gNonInteractive) - { - LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild("destination_guide_contents"); - if (destinations) - { - destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); - std::string url = gSavedSettings.getString("DestinationGuideURL"); - url = LLWeb::expandURLSubstitutions(url, LLSD()); - destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); - } - LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild("avatar_picker_contents"); - if (avatar_picker) - { - avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); - std::string url = gSavedSettings.getString("AvatarPickerURL"); - url = LLWeb::expandURLSubstitutions(url, LLSD()); - avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); - } - } + // Top Info bar + LLPanel* topinfo_bar_container = getRootView()->getChild("topinfo_bar_container"); + LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance(); + + topinfo_bar->setShape(topinfo_bar_container->getLocalRect()); + + topinfo_bar_container->addChild(topinfo_bar); + topinfo_bar_container->setVisible(TRUE); + + if (!gSavedSettings.getBOOL("ShowMiniLocationPanel")) + { + topinfo_bar->setVisible(FALSE); + } + + if ( gHUDView == NULL ) + { + LLRect hud_rect = full_window; + hud_rect.mBottom += 50; + if (gMenuBarView && gMenuBarView->isInVisibleChain()) + { + hud_rect.mTop -= gMenuBarView->getRect().getHeight(); + } + gHUDView = new LLHUDView(hud_rect); + getRootView()->addChild(gHUDView); + getRootView()->sendChildToBack(gHUDView); + } + + LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container"); + + LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); + panel_ssf_container->addChild(panel_stand_stop_flying); + + LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance(); + panel_ssf_container->addChild(panel_hide_beacon); + + panel_ssf_container->setVisible(TRUE); + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); + + // Load and make the toolbars visible + // Note: we need to load the toolbars only *after* the user is logged in and IW + if (gToolBarView) + { + gToolBarView->loadToolbars(); + gToolBarView->setVisible(TRUE); + } + + if (!gNonInteractive) + { + LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild("destination_guide_contents"); + if (destinations) + { + destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("DestinationGuideURL"); + url = LLWeb::expandURLSubstitutions(url, LLSD()); + destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + } + LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild("avatar_picker_contents"); + if (avatar_picker) + { + avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("AvatarPickerURL"); + url = LLWeb::expandURLSubstitutions(url, LLSD()); + avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + } + } } // Destroy the UI void LLViewerWindow::shutdownViews() { - // clean up warning logger - RecordToChatConsole::getInstance()->stopRecorder(); - LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ; - - gFocusMgr.unlockFocus(); - gFocusMgr.setMouseCapture(NULL); - gFocusMgr.setKeyboardFocus(NULL); - gFocusMgr.setTopCtrl(NULL); - if (mWindow) - { - mWindow->allowLanguageTextInput(NULL, FALSE); - } - - delete mDebugText; - mDebugText = NULL; - - LL_INFOS() << "DebugText deleted." << LL_ENDL ; - - // Cleanup global views - if (gMorphView) - { - gMorphView->setVisible(FALSE); - } - LL_INFOS() << "Global views cleaned." << LL_ENDL ; - - LLNotificationsUI::LLToast::cleanupToasts(); - LL_INFOS() << "Leftover toast cleaned up." << LL_ENDL; - - // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open - // will crump with LL_ERRS. - LLModalDialog::shutdownModals(); - LL_INFOS() << "LLModalDialog shut down." << LL_ENDL; - - // destroy the nav bar, not currently part of gViewerWindow - // *TODO: Make LLNavigationBar part of gViewerWindow - LLNavigationBar::deleteSingleton(); - LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ; - - // destroy menus after instantiating navbar above, as it needs - // access to gMenuHolder - cleanup_menus(); - LL_INFOS() << "menus destroyed." << LL_ENDL ; - - view_listener_t::cleanup(); - LL_INFOS() << "view listeners destroyed." << LL_ENDL ; - - // Clean up pointers that are going to be invalid. (todo: check sMenuContainer) - mProgressView = NULL; - mPopupView = NULL; - - // Delete all child views. - delete mRootView; - mRootView = NULL; - LL_INFOS() << "RootView deleted." << LL_ENDL ; - - LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); - - // Automatically deleted as children of mRootView. Fix the globals. - gStatusBar = NULL; - gIMMgr = NULL; - gToolTipView = NULL; - - gToolBarView = NULL; - gFloaterView = NULL; - gMorphView = NULL; - - gHUDView = NULL; + // clean up warning logger + RecordToChatConsole::getInstance()->stopRecorder(); + LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ; + + gFocusMgr.unlockFocus(); + gFocusMgr.setMouseCapture(NULL); + gFocusMgr.setKeyboardFocus(NULL); + gFocusMgr.setTopCtrl(NULL); + if (mWindow) + { + mWindow->allowLanguageTextInput(NULL, FALSE); + } + + delete mDebugText; + mDebugText = NULL; + + LL_INFOS() << "DebugText deleted." << LL_ENDL ; + + // Cleanup global views + if (gMorphView) + { + gMorphView->setVisible(FALSE); + } + LL_INFOS() << "Global views cleaned." << LL_ENDL ; + + LLNotificationsUI::LLToast::cleanupToasts(); + LL_INFOS() << "Leftover toast cleaned up." << LL_ENDL; + + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open + // will crump with LL_ERRS. + LLModalDialog::shutdownModals(); + LL_INFOS() << "LLModalDialog shut down." << LL_ENDL; + + // destroy the nav bar, not currently part of gViewerWindow + // *TODO: Make LLNavigationBar part of gViewerWindow + LLNavigationBar::deleteSingleton(); + LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ; + + // destroy menus after instantiating navbar above, as it needs + // access to gMenuHolder + cleanup_menus(); + LL_INFOS() << "menus destroyed." << LL_ENDL ; + + view_listener_t::cleanup(); + LL_INFOS() << "view listeners destroyed." << LL_ENDL ; + + // Clean up pointers that are going to be invalid. (todo: check sMenuContainer) + mProgressView = NULL; + mPopupView = NULL; + + // Delete all child views. + delete mRootView; + mRootView = NULL; + LL_INFOS() << "RootView deleted." << LL_ENDL ; + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); + + // Automatically deleted as children of mRootView. Fix the globals. + gStatusBar = NULL; + gIMMgr = NULL; + gToolTipView = NULL; + + gToolBarView = NULL; + gFloaterView = NULL; + gMorphView = NULL; + + gHUDView = NULL; } void LLViewerWindow::shutdownGL() { - //-------------------------------------------------------- - // Shutdown GL cleanly. Order is very important here. - //-------------------------------------------------------- - LLFontGL::destroyDefaultFonts(); - SUBSYSTEM_CLEANUP(LLFontManager); - stop_glerror(); + //-------------------------------------------------------- + // Shutdown GL cleanly. Order is very important here. + //-------------------------------------------------------- + LLFontGL::destroyDefaultFonts(); + SUBSYSTEM_CLEANUP(LLFontManager); + stop_glerror(); + + gSky.cleanup(); + stop_glerror(); - gSky.cleanup(); - stop_glerror(); + LL_INFOS() << "Cleaning up pipeline" << LL_ENDL; + gPipeline.cleanup(); + stop_glerror(); - LL_INFOS() << "Cleaning up pipeline" << LL_ENDL; - gPipeline.cleanup(); - stop_glerror(); + //MUST clean up pipeline before cleaning up wearables + LL_INFOS() << "Cleaning up wearables" << LL_ENDL; + LLWearableList::instance().cleanup() ; - //MUST clean up pipeline before cleaning up wearables - LL_INFOS() << "Cleaning up wearables" << LL_ENDL; - LLWearableList::instance().cleanup() ; + gTextureList.shutdown(); + stop_glerror(); - gTextureList.shutdown(); - stop_glerror(); + gBumpImageList.shutdown(); + stop_glerror(); - gBumpImageList.shutdown(); - stop_glerror(); + LLWorldMapView::cleanupTextures(); - LLWorldMapView::cleanupTextures(); + LLViewerTextureManager::cleanup() ; + SUBSYSTEM_CLEANUP(LLImageGL) ; - LLViewerTextureManager::cleanup() ; - SUBSYSTEM_CLEANUP(LLImageGL) ; - - LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ; + LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ; - LL_INFOS() << "Cleaning up select manager" << LL_ENDL; - LLSelectMgr::getInstance()->cleanup(); + LL_INFOS() << "Cleaning up select manager" << LL_ENDL; + LLSelectMgr::getInstance()->cleanup(); - LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL; - stopGL(FALSE); - stop_glerror(); + LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL; + stopGL(FALSE); + stop_glerror(); - gGL.shutdown(); + gGL.shutdown(); - SUBSYSTEM_CLEANUP(LLVertexBuffer); + SUBSYSTEM_CLEANUP(LLVertexBuffer); - LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ; + LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ; } // shutdownViews() and shutdownGL() need to be called first LLViewerWindow::~LLViewerWindow() { - LL_INFOS() << "Destroying Window" << LL_ENDL; - destroyWindow(); + LL_INFOS() << "Destroying Window" << LL_ENDL; + destroyWindow(); - delete mDebugText; - mDebugText = NULL; + delete mDebugText; + mDebugText = NULL; - if (LLViewerShaderMgr::sInitialized) - { - LLViewerShaderMgr::releaseInstance(); - LLViewerShaderMgr::sInitialized = FALSE; - } + if (LLViewerShaderMgr::sInitialized) + { + LLViewerShaderMgr::releaseInstance(); + LLViewerShaderMgr::sInitialized = FALSE; + } } void LLViewerWindow::setCursor( ECursorType c ) { - mWindow->setCursor( c ); + mWindow->setCursor( c ); } void LLViewerWindow::showCursor() { - mWindow->showCursor(); - - mCursorHidden = FALSE; + mWindow->showCursor(); + + mCursorHidden = FALSE; } void LLViewerWindow::hideCursor() { - // And hide the cursor - mWindow->hideCursor(); + // And hide the cursor + mWindow->hideCursor(); - mCursorHidden = TRUE; + mCursorHidden = TRUE; } void LLViewerWindow::sendShapeToSim() { - LLMessageSystem* msg = gMessageSystem; - if(!msg) return; - msg->newMessageFast(_PREHASH_AgentHeightWidth); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); - msg->nextBlockFast(_PREHASH_HeightWidthBlock); - msg->addU32Fast(_PREHASH_GenCounter, 0); - U16 height16 = (U16) mWorldViewRectRaw.getHeight(); - U16 width16 = (U16) mWorldViewRectRaw.getWidth(); - msg->addU16Fast(_PREHASH_Height, height16); - msg->addU16Fast(_PREHASH_Width, width16); - gAgent.sendReliableMessage(); + LLMessageSystem* msg = gMessageSystem; + if(!msg) return; + msg->newMessageFast(_PREHASH_AgentHeightWidth); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); + msg->nextBlockFast(_PREHASH_HeightWidthBlock); + msg->addU32Fast(_PREHASH_GenCounter, 0); + U16 height16 = (U16) mWorldViewRectRaw.getHeight(); + U16 width16 = (U16) mWorldViewRectRaw.getWidth(); + msg->addU16Fast(_PREHASH_Height, height16); + msg->addU16Fast(_PREHASH_Width, width16); + gAgent.sendReliableMessage(); } // Must be called after window is created to set up agent // camera variables and UI variables. void LLViewerWindow::reshape(S32 width, S32 height) { - // Destroying the window at quit time generates spurious - // reshape messages. We don't care about these, and we - // don't want to send messages because the message system - // may have been destructed. - if (!LLApp::isExiting()) - { - gWindowResized = TRUE; + // Destroying the window at quit time generates spurious + // reshape messages. We don't care about these, and we + // don't want to send messages because the message system + // may have been destructed. + if (!LLApp::isExiting()) + { + gWindowResized = TRUE; - // update our window rectangle - mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width; - mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height; + // update our window rectangle + mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width; + mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height; - //glViewport(0, 0, width, height ); + //glViewport(0, 0, width, height ); LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist - if (height > 0 && camera) - { + if (height > 0 && camera) + { camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); camera->setAspect( getWorldViewAspectRatio() ); - } + } - calcDisplayScale(); - - BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor(); - LLUI::setScaleFactor(mDisplayScale); + calcDisplayScale(); - // update our window rectangle - mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]); - mWindowRectScaled.mTop = mWindowRectScaled.mBottom + ll_round((F32)height / mDisplayScale.mV[VY]); + BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor(); + LLUI::setScaleFactor(mDisplayScale); - setup2DViewport(); + // update our window rectangle + mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]); + mWindowRectScaled.mTop = mWindowRectScaled.mBottom + ll_round((F32)height / mDisplayScale.mV[VY]); - // Inform lower views of the change - // round up when converting coordinates to make sure there are no gaps at edge of window - LLView::sForceReshape = display_scale_changed; - mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY])); + setup2DViewport(); + + // Inform lower views of the change + // round up when converting coordinates to make sure there are no gaps at edge of window + LLView::sForceReshape = display_scale_changed; + mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY])); if (display_scale_changed) { // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass() LLPanelLogin::reshapePanel(); } - LLView::sForceReshape = FALSE; + LLView::sForceReshape = FALSE; - // clear font width caches - if (display_scale_changed) - { - LLHUDObject::reshapeAll(); - } + // clear font width caches + if (display_scale_changed) + { + LLHUDObject::reshapeAll(); + } - sendShapeToSim(); + sendShapeToSim(); - // store new settings for the mode we are in, regardless - BOOL maximized = mWindow->getMaximized(); - gSavedSettings.setBOOL("WindowMaximized", maximized); + // store new settings for the mode we are in, regardless + BOOL maximized = mWindow->getMaximized(); + gSavedSettings.setBOOL("WindowMaximized", maximized); - if (!maximized) - { - U32 min_window_width=gSavedSettings.getU32("MinWindowWidth"); - U32 min_window_height=gSavedSettings.getU32("MinWindowHeight"); - // tell the OS specific window code about min window size - mWindow->setMinSize(min_window_width, min_window_height); + if (!maximized) + { + U32 min_window_width=gSavedSettings.getU32("MinWindowWidth"); + U32 min_window_height=gSavedSettings.getU32("MinWindowHeight"); + // tell the OS specific window code about min window size + mWindow->setMinSize(min_window_width, min_window_height); - LLCoordScreen window_rect; - if (!gNonInteractive && mWindow->getSize(&window_rect)) - { - // Only save size if not maximized - gSavedSettings.setU32("WindowWidth", window_rect.mX); - gSavedSettings.setU32("WindowHeight", window_rect.mY); - } - } + LLCoordScreen window_rect; + if (!gNonInteractive && mWindow->getSize(&window_rect)) + { + // Only save size if not maximized + gSavedSettings.setU32("WindowWidth", window_rect.mX); + gSavedSettings.setU32("WindowHeight", window_rect.mY); + } + } - sample(LLStatViewer::WINDOW_WIDTH, width); - sample(LLStatViewer::WINDOW_HEIGHT, height); + sample(LLStatViewer::WINDOW_WIDTH, width); + sample(LLStatViewer::WINDOW_HEIGHT, height); - LLLayoutStack::updateClass(); - } + LLLayoutStack::updateClass(); + } } // Hide normal UI when a logon fails void LLViewerWindow::setNormalControlsVisible( BOOL visible ) { - if(LLChicletBar::instanceExists()) - { - LLChicletBar::getInstance()->setVisible(visible); - LLChicletBar::getInstance()->setEnabled(visible); - } - - if ( gMenuBarView ) - { - gMenuBarView->setVisible( visible ); - gMenuBarView->setEnabled( visible ); - - // ...and set the menu color appropriately. - setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT, - LLGridManager::getInstance()->isInProductionGrid()); - } - - if ( gStatusBar ) - { - gStatusBar->setVisible( visible ); - gStatusBar->setEnabled( visible ); - } - - LLNavigationBar* navbarp = LLUI::getInstance()->getRootView()->findChild("navigation_bar"); - if (navbarp) - { - // when it's time to show navigation bar we need to ensure that the user wants to see it - // i.e. ShowNavbarNavigationPanel option is true - navbarp->setVisible( visible && gSavedSettings.getBOOL("ShowNavbarNavigationPanel") ); - } + if(LLChicletBar::instanceExists()) + { + LLChicletBar::getInstance()->setVisible(visible); + LLChicletBar::getInstance()->setEnabled(visible); + } + + if ( gMenuBarView ) + { + gMenuBarView->setVisible( visible ); + gMenuBarView->setEnabled( visible ); + + // ...and set the menu color appropriately. + setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT, + LLGridManager::getInstance()->isInProductionGrid()); + } + + if ( gStatusBar ) + { + gStatusBar->setVisible( visible ); + gStatusBar->setEnabled( visible ); + } + + LLNavigationBar* navbarp = LLUI::getInstance()->getRootView()->findChild("navigation_bar"); + if (navbarp) + { + // when it's time to show navigation bar we need to ensure that the user wants to see it + // i.e. ShowNavbarNavigationPanel option is true + navbarp->setVisible( visible && gSavedSettings.getBOOL("ShowNavbarNavigationPanel") ); + } } void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) @@ -2580,17 +2580,17 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) LLSD args; LLColor4 new_bg_color; - // god more important than project, proj more important than grid - if ( god_mode ) + // god more important than project, proj more important than grid + if ( god_mode ) { - if ( LLGridManager::getInstance()->isInProductionGrid() ) - { - new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" ); - } - else - { - new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" ); - } + if ( LLGridManager::getInstance()->isInProductionGrid() ) + { + new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" ); + } + else + { + new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" ); + } } else { @@ -2603,24 +2603,24 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) case LLVersionInfo::PROJECT_VIEWER: new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" ); break; - + case LLVersionInfo::BETA_VIEWER: new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" ); break; - + case LLVersionInfo::RELEASE_VIEWER: if(!LLGridManager::getInstance()->isInProductionGrid()) { new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } - else + else { new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); } break; } } - + if(gMenuBarView) { gMenuBarView->setBackgroundColor( new_bg_color ); @@ -2635,149 +2635,149 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) void LLViewerWindow::drawDebugText() { gUIProgram.bind(); - gGL.color4f(1,1,1,1); - gGL.pushMatrix(); - gGL.pushUIMatrix(); - { - // scale view by UI global scale factor and aspect ratio correction factor - gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); - mDebugText->draw(); - } - gGL.popUIMatrix(); - gGL.popMatrix(); + gGL.color4f(1,1,1,1); + gGL.pushMatrix(); + gGL.pushUIMatrix(); + { + // scale view by UI global scale factor and aspect ratio correction factor + gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); + mDebugText->draw(); + } + gGL.popUIMatrix(); + gGL.popMatrix(); - gGL.flush(); - gUIProgram.unbind(); + gGL.flush(); + gUIProgram.unbind(); } void LLViewerWindow::draw() { - + //#if LL_DEBUG - LLView::sIsDrawing = TRUE; + LLView::sIsDrawing = TRUE; //#endif - stop_glerror(); - - LLUI::setLineWidth(1.f); - - LLUI::setLineWidth(1.f); - // Reset any left-over transforms - gGL.matrixMode(LLRender::MM_MODELVIEW); - - gGL.loadIdentity(); - - //S32 screen_x, screen_y; - - if (!gSavedSettings.getBOOL("RenderUIBuffer")) - { - LLView::sDirtyRect = getWindowRectScaled(); - } - - // HACK for timecode debugging - if (gSavedSettings.getBOOL("DisplayTimecode")) - { - // draw timecode block - std::string text; - - gGL.loadIdentity(); - - microsecondsToTimecodeString(gFrameTime,text); - const LLFontGL* font = LLFontGL::getFontSansSerif(); - font->renderUTF8(text, 0, - ll_round((getWindowWidthScaled()/2)-100.f), - ll_round((getWindowHeightScaled()-60.f)), - LLColor4( 1.f, 1.f, 1.f, 1.f ), - LLFontGL::LEFT, LLFontGL::TOP); - } - - // Draw all nested UI views. - // No translation needed, this view is glued to 0,0 - - gUIProgram.bind(); - gGL.color4f(1, 1, 1, 1); + stop_glerror(); - gGL.pushMatrix(); - LLUI::pushMatrix(); - { - - // scale view by UI global scale factor and aspect ratio correction factor - gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); - - LLVector2 old_scale_factor = LLUI::getScaleFactor(); - // apply camera zoom transform (for high res screenshots) - F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); - S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); - if (zoom_factor > 1.f) - { - //decompose subregion number to x and y values - int pos_y = sub_region / llceil(zoom_factor); - int pos_x = sub_region - (pos_y*llceil(zoom_factor)); - // offset for this tile - gGL.translatef((F32)getWindowWidthScaled() * -(F32)pos_x, - (F32)getWindowHeightScaled() * -(F32)pos_y, - 0.f); - gGL.scalef(zoom_factor, zoom_factor, 1.f); - LLUI::getScaleFactor() *= zoom_factor; - } - - // Draw tool specific overlay on world - LLToolMgr::getInstance()->getCurrentTool()->draw(); - - if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() ) - { - drawMouselookInstructions(); - stop_glerror(); - } - - // Draw all nested UI views. - // No translation needed, this view is glued to 0,0 - mRootView->draw(); - - if (LLView::sDebugRects) - { - gToolTipView->drawStickyRect(); - } - - // Draw optional on-top-of-everyone view - LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - if (top_ctrl && top_ctrl->getVisible()) - { - S32 screen_x, screen_y; - top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - LLUI::pushMatrix(); - LLUI::translate( (F32) screen_x, (F32) screen_y); - top_ctrl->draw(); - LLUI::popMatrix(); - } - - - if( gShowOverlayTitle && !mOverlayTitle.empty() ) - { - // Used for special titles such as "Second Life - Special E3 2003 Beta" - const S32 DIST_FROM_TOP = 20; - LLFontGL::getFontSansSerifBig()->renderUTF8( - mOverlayTitle, 0, - ll_round( getWindowWidthScaled() * 0.5f), - getWindowHeightScaled() - DIST_FROM_TOP, - LLColor4(1, 1, 1, 0.4f), - LLFontGL::HCENTER, LLFontGL::TOP); - } - - LLUI::setScaleFactor(old_scale_factor); - } - LLUI::popMatrix(); - gGL.popMatrix(); - - gUIProgram.unbind(); - - LLView::sIsDrawing = FALSE; -} + LLUI::setLineWidth(1.f); -// Takes a single keyup event, usually when UI is visible -BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) -{ + LLUI::setLineWidth(1.f); + // Reset any left-over transforms + gGL.matrixMode(LLRender::MM_MODELVIEW); + + gGL.loadIdentity(); + + //S32 screen_x, screen_y; + + if (!gSavedSettings.getBOOL("RenderUIBuffer")) + { + LLView::sDirtyRect = getWindowRectScaled(); + } + + // HACK for timecode debugging + if (gSavedSettings.getBOOL("DisplayTimecode")) + { + // draw timecode block + std::string text; + + gGL.loadIdentity(); + + microsecondsToTimecodeString(gFrameTime,text); + const LLFontGL* font = LLFontGL::getFontSansSerif(); + font->renderUTF8(text, 0, + ll_round((getWindowWidthScaled()/2)-100.f), + ll_round((getWindowHeightScaled()-60.f)), + LLColor4( 1.f, 1.f, 1.f, 1.f ), + LLFontGL::LEFT, LLFontGL::TOP); + } + + // Draw all nested UI views. + // No translation needed, this view is glued to 0,0 + + gUIProgram.bind(); + gGL.color4f(1, 1, 1, 1); + + gGL.pushMatrix(); + LLUI::pushMatrix(); + { + + // scale view by UI global scale factor and aspect ratio correction factor + gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); + + LLVector2 old_scale_factor = LLUI::getScaleFactor(); + // apply camera zoom transform (for high res screenshots) + F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); + S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); + if (zoom_factor > 1.f) + { + //decompose subregion number to x and y values + int pos_y = sub_region / llceil(zoom_factor); + int pos_x = sub_region - (pos_y*llceil(zoom_factor)); + // offset for this tile + gGL.translatef((F32)getWindowWidthScaled() * -(F32)pos_x, + (F32)getWindowHeightScaled() * -(F32)pos_y, + 0.f); + gGL.scalef(zoom_factor, zoom_factor, 1.f); + LLUI::getScaleFactor() *= zoom_factor; + } + + // Draw tool specific overlay on world + LLToolMgr::getInstance()->getCurrentTool()->draw(); + + if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() ) + { + drawMouselookInstructions(); + stop_glerror(); + } + + // Draw all nested UI views. + // No translation needed, this view is glued to 0,0 + mRootView->draw(); + + if (LLView::sDebugRects) + { + gToolTipView->drawStickyRect(); + } + + // Draw optional on-top-of-everyone view + LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + if (top_ctrl && top_ctrl->getVisible()) + { + S32 screen_x, screen_y; + top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + LLUI::pushMatrix(); + LLUI::translate( (F32) screen_x, (F32) screen_y); + top_ctrl->draw(); + LLUI::popMatrix(); + } + + + if( gShowOverlayTitle && !mOverlayTitle.empty() ) + { + // Used for special titles such as "Second Life - Special E3 2003 Beta" + const S32 DIST_FROM_TOP = 20; + LLFontGL::getFontSansSerifBig()->renderUTF8( + mOverlayTitle, 0, + ll_round( getWindowWidthScaled() * 0.5f), + getWindowHeightScaled() - DIST_FROM_TOP, + LLColor4(1, 1, 1, 0.4f), + LLFontGL::HCENTER, LLFontGL::TOP); + } + + LLUI::setScaleFactor(old_scale_factor); + } + LLUI::popMatrix(); + gGL.popMatrix(); + + gUIProgram.unbind(); + + LLView::sIsDrawing = FALSE; +} + +// Takes a single keyup event, usually when UI is visible +BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) +{ if (LLSetKeyBindDialog::recordKey(key, mask, FALSE)) { LL_DEBUGS() << "KeyUp handled by LLSetKeyBindDialog" << LL_ENDL; @@ -2788,45 +2788,45 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if (keyboard_focus - && !(mask & (MASK_CONTROL | MASK_ALT)) - && !gFocusMgr.getKeystrokesOnly()) - { - // We have keyboard focus, and it's not an accelerator + && !(mask & (MASK_CONTROL | MASK_ALT)) + && !gFocusMgr.getKeystrokesOnly()) + { + // We have keyboard focus, and it's not an accelerator if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown()) { return keyboard_focus->handleKeyUp(key, mask, FALSE); } else if (key < 0x80) - { - // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first. - return (gFocusMgr.getKeyboardFocus() != NULL); - } - } - - if (keyboard_focus) - { - if (keyboard_focus->handleKeyUp(key, mask, FALSE)) - { - LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key, mask); - return TRUE; - } - else { - LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL; - } - } - - // don't pass keys on to world when something in ui has focus - return gFocusMgr.childHasKeyboardFocus(mRootView) - || LLMenuGL::getKeyboardMode() - || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive()); + { + // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first. + return (gFocusMgr.getKeyboardFocus() != NULL); + } + } + + if (keyboard_focus) + { + if (keyboard_focus->handleKeyUp(key, mask, FALSE)) + { + LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + else { + LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL; + } + } + + // don't pass keys on to world when something in ui has focus + return gFocusMgr.childHasKeyboardFocus(mRootView) + || LLMenuGL::getKeyboardMode() + || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive()); } // Takes a single keydown event, usually when UI is visible BOOL LLViewerWindow::handleKey(KEY key, MASK mask) { - // hide tooltips on keypress - LLToolTipMgr::instance().blockToolTips(); + // hide tooltips on keypress + LLToolTipMgr::instance().blockToolTips(); // Menus get handled on key down instead of key up // so keybindings have to be recorded before that @@ -2838,7 +2838,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); - + if (keyboard_focus && !gFocusMgr.getKeystrokesOnly()) { @@ -2911,279 +2911,279 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } } - // let menus handle navigation keys for navigation - if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE)) - ||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE)) - ||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE))) - { - LL_DEBUGS() << "LLviewerWindow::handleKey handle nav keys for nav" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - - // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus - // as long as focus isn't locked - if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked()) - { - // Check the current floater's menu first, if it has one. - if (gFocusMgr.keyboardFocusHasAccelerators() - && keyboard_focus - && keyboard_focus->handleKey(key,mask,FALSE)) - { - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - if (gAgent.isInitialized() - && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) - && gMenuBarView - && gMenuBarView->handleAcceleratorKey(key, mask)) - { - LLViewerEventRecorder::instance().logKeyEvent(key, mask); - return TRUE; - } - - if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) - { - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - } - - // give floaters first chance to handle TAB key - // so frontmost floater gets focus - // if nothing has focus, go to first or last UI element as appropriate + // let menus handle navigation keys for navigation + if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE)) + ||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE)) + ||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE))) + { + LL_DEBUGS() << "LLviewerWindow::handleKey handle nav keys for nav" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + + // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus + // as long as focus isn't locked + if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked()) + { + // Check the current floater's menu first, if it has one. + if (gFocusMgr.keyboardFocusHasAccelerators() + && keyboard_focus + && keyboard_focus->handleKey(key,mask,FALSE)) + { + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + if (gAgent.isInitialized() + && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) + && gMenuBarView + && gMenuBarView->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + + if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + } + + // give floaters first chance to handle TAB key + // so frontmost floater gets focus + // if nothing has focus, go to first or last UI element as appropriate if (key == KEY_TAB && (mask & MASK_CONTROL || keyboard_focus == NULL)) - { - LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL; - if (gMenuHolder) gMenuHolder->hideMenus(); - - // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode - gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0); - - // do CTRL-TAB and CTRL-SHIFT-TAB logic - if (mask & MASK_SHIFT) - { - mRootView->focusPrevRoot(); - } - else - { - mRootView->focusNextRoot(); - } - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - // hidden edit menu for cut/copy/paste - if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask)) - { - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - LLFloater* focused_floaterp = gFloaterView->getFocusedFloater(); - std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : ""); - - if( keyboard_focus ) - { - if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel")) - { - if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) - { - // let Control-Up and Control-Down through for chat line history, - if (!(key == KEY_UP && mask == MASK_CONTROL) - && !(key == KEY_DOWN && mask == MASK_CONTROL) - && !(key == KEY_UP && mask == MASK_ALT) - && !(key == KEY_DOWN && mask == MASK_ALT)) - { - switch(key) - { - case KEY_LEFT: - case KEY_RIGHT: - case KEY_UP: - case KEY_DOWN: - case KEY_PAGE_UP: - case KEY_PAGE_DOWN: - case KEY_HOME: - case KEY_END: - // when chatbar is empty or ArrowKeysAlwaysMove set, - // pass arrow keys on to avatar... - return FALSE; - default: - break; - } - } - } - } - - if (keyboard_focus->handleKey(key, mask, FALSE)) - { - - LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } else { - LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << LL_ENDL; - } - } - - if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) ) - { - LL_DEBUGS() << "LLviewerWindow::handleKey toolbar handling?" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - // Try for a new-format gesture - if (LLGestureMgr::instance().triggerGesture(key, mask)) - { - LL_DEBUGS() << "LLviewerWindow::handleKey new gesture feature" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - // See if this is a gesture trigger. If so, eat the key and - // don't pass it down to the menus. - if (gGestureList.trigger(key, mask)) - { - LL_DEBUGS() << "LLviewerWindow::handleKey check gesture trigger" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - - // If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, - // no view has keyboard focus, this is a printable character key (and no modifier key is - // pressed except shift), then give focus to nearby chat (STORM-560) - if ( LLStartUp::getStartupState() >= STATE_STARTED && - gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && - !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) ) - { - // Initialize nearby chat if it's missing - LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance("nearby_chat"); - if (!nearby_chat) - { - LLSD name("im_container"); - LLFloaterReg::toggleInstanceOrBringToFront(name); - } - - LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance("nearby_chat")->getChatBox(); - if (chat_editor) - { - // passing NULL here, character will be added later when it is handled by character handler. - nearby_chat->startChat(NULL); - return TRUE; - } - } - - // give menus a chance to handle unmodified accelerator keys - if (gAgent.isInitialized() - && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) - && gMenuBarView - && gMenuBarView->handleAcceleratorKey(key, mask)) - { - LLViewerEventRecorder::instance().logKeyEvent(key, mask); - return TRUE; - } - - if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) - { - return TRUE; - } - - // don't pass keys on to world when something in ui has focus - return gFocusMgr.childHasKeyboardFocus(mRootView) - || LLMenuGL::getKeyboardMode() - || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive()); + { + LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL; + if (gMenuHolder) gMenuHolder->hideMenus(); + + // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode + gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0); + + // do CTRL-TAB and CTRL-SHIFT-TAB logic + if (mask & MASK_SHIFT) + { + mRootView->focusPrevRoot(); + } + else + { + mRootView->focusNextRoot(); + } + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + // hidden edit menu for cut/copy/paste + if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + LLFloater* focused_floaterp = gFloaterView->getFocusedFloater(); + std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : ""); + + if( keyboard_focus ) + { + if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel")) + { + if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) + { + // let Control-Up and Control-Down through for chat line history, + if (!(key == KEY_UP && mask == MASK_CONTROL) + && !(key == KEY_DOWN && mask == MASK_CONTROL) + && !(key == KEY_UP && mask == MASK_ALT) + && !(key == KEY_DOWN && mask == MASK_ALT)) + { + switch(key) + { + case KEY_LEFT: + case KEY_RIGHT: + case KEY_UP: + case KEY_DOWN: + case KEY_PAGE_UP: + case KEY_PAGE_DOWN: + case KEY_HOME: + case KEY_END: + // when chatbar is empty or ArrowKeysAlwaysMove set, + // pass arrow keys on to avatar... + return FALSE; + default: + break; + } + } + } + } + + if (keyboard_focus->handleKey(key, mask, FALSE)) + { + + LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } else { + LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << LL_ENDL; + } + } + + if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) ) + { + LL_DEBUGS() << "LLviewerWindow::handleKey toolbar handling?" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + // Try for a new-format gesture + if (LLGestureMgr::instance().triggerGesture(key, mask)) + { + LL_DEBUGS() << "LLviewerWindow::handleKey new gesture feature" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + // See if this is a gesture trigger. If so, eat the key and + // don't pass it down to the menus. + if (gGestureList.trigger(key, mask)) + { + LL_DEBUGS() << "LLviewerWindow::handleKey check gesture trigger" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + + // If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, + // no view has keyboard focus, this is a printable character key (and no modifier key is + // pressed except shift), then give focus to nearby chat (STORM-560) + if ( LLStartUp::getStartupState() >= STATE_STARTED && + gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && + !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) ) + { + // Initialize nearby chat if it's missing + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance("nearby_chat"); + if (!nearby_chat) + { + LLSD name("im_container"); + LLFloaterReg::toggleInstanceOrBringToFront(name); + } + + LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance("nearby_chat")->getChatBox(); + if (chat_editor) + { + // passing NULL here, character will be added later when it is handled by character handler. + nearby_chat->startChat(NULL); + return TRUE; + } + } + + // give menus a chance to handle unmodified accelerator keys + if (gAgent.isInitialized() + && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) + && gMenuBarView + && gMenuBarView->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + + if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) + { + return TRUE; + } + + // don't pass keys on to world when something in ui has focus + return gFocusMgr.childHasKeyboardFocus(mRootView) + || LLMenuGL::getKeyboardMode() + || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive()); } BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) { - // HACK: We delay processing of return keys until they arrive as a Unicode char, - // so that if you're typing chat text at low frame rate, we don't send the chat - // until all keystrokes have been entered. JC - // HACK: Numeric keypad on Mac is Unicode 3 - // HACK: Control-M on Windows is Unicode 13 - if ((uni_char == 13 && mask != MASK_CONTROL) - || (uni_char == 3 && mask == MASK_NONE) ) - { - if (mask != MASK_ALT) - { - // remaps, handles ignored cases and returns back to viewer window. - return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); - } - } - - // let menus handle navigation (jump) keys - if (gMenuBarView && gMenuBarView->handleUnicodeChar(uni_char, TRUE)) - { - return TRUE; - } - - // Traverses up the hierarchy - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); - if( keyboard_focus ) - { - if (keyboard_focus->handleUnicodeChar(uni_char, FALSE)) - { - return TRUE; - } + // HACK: We delay processing of return keys until they arrive as a Unicode char, + // so that if you're typing chat text at low frame rate, we don't send the chat + // until all keystrokes have been entered. JC + // HACK: Numeric keypad on Mac is Unicode 3 + // HACK: Control-M on Windows is Unicode 13 + if ((uni_char == 13 && mask != MASK_CONTROL) + || (uni_char == 3 && mask == MASK_NONE) ) + { + if (mask != MASK_ALT) + { + // remaps, handles ignored cases and returns back to viewer window. + return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); + } + } + + // let menus handle navigation (jump) keys + if (gMenuBarView && gMenuBarView->handleUnicodeChar(uni_char, TRUE)) + { + return TRUE; + } + + // Traverses up the hierarchy + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + if( keyboard_focus ) + { + if (keyboard_focus->handleUnicodeChar(uni_char, FALSE)) + { + return TRUE; + } return TRUE; - } + } - return FALSE; + return FALSE; } void LLViewerWindow::handleScrollWheel(S32 clicks) { - LLUI::getInstance()->resetMouseIdleTimer(); - - LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); - if( mouse_captor ) - { - S32 local_x; - S32 local_y; - mouse_captor->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y ); - mouse_captor->handleScrollWheel(local_x, local_y, clicks); - if (LLView::sDebugMouseHandling) - { - LL_INFOS() << "Scroll Wheel handled by captor " << mouse_captor->getName() << LL_ENDL; - } - return; - } - - LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - if (top_ctrl) - { - S32 local_x; - S32 local_y; - top_ctrl->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y ); - if (top_ctrl->handleScrollWheel(local_x, local_y, clicks)) return; - } - - if (mRootView->handleScrollWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks) ) - { - if (LLView::sDebugMouseHandling) - { - LL_INFOS() << "Scroll Wheel" << LLView::sMouseHandlerMessage << LL_ENDL; - } - return; - } - else if (LLView::sDebugMouseHandling) - { - LL_INFOS() << "Scroll Wheel not handled by view" << LL_ENDL; - } - - // Zoom the camera in and out behavior - - if(top_ctrl == 0 - && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) - && gAgentCamera.isInitialized()) - gAgentCamera.handleScrollWheel(clicks); - - return; + LLUI::getInstance()->resetMouseIdleTimer(); + + LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); + if( mouse_captor ) + { + S32 local_x; + S32 local_y; + mouse_captor->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y ); + mouse_captor->handleScrollWheel(local_x, local_y, clicks); + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Wheel handled by captor " << mouse_captor->getName() << LL_ENDL; + } + return; + } + + LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + if (top_ctrl) + { + S32 local_x; + S32 local_y; + top_ctrl->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y ); + if (top_ctrl->handleScrollWheel(local_x, local_y, clicks)) return; + } + + if (mRootView->handleScrollWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks) ) + { + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Wheel" << LLView::sMouseHandlerMessage << LL_ENDL; + } + return; + } + else if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Wheel not handled by view" << LL_ENDL; + } + + // Zoom the camera in and out behavior + + if(top_ctrl == 0 + && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) + && gAgentCamera.isInitialized()) + gAgentCamera.handleScrollWheel(clicks); + + return; } void LLViewerWindow::handleScrollHWheel(S32 clicks) @@ -3192,7 +3192,7 @@ void LLViewerWindow::handleScrollHWheel(S32 clicks) { return; } - + LLUI::getInstance()->resetMouseIdleTimer(); LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); @@ -3236,42 +3236,42 @@ void LLViewerWindow::handleScrollHWheel(S32 clicks) void LLViewerWindow::addPopup(LLView* popup) { - if (mPopupView) - { - mPopupView->addPopup(popup); - } + if (mPopupView) + { + mPopupView->addPopup(popup); + } } void LLViewerWindow::removePopup(LLView* popup) { - if (mPopupView) - { - mPopupView->removePopup(popup); - } + if (mPopupView) + { + mPopupView->removePopup(popup); + } } void LLViewerWindow::clearPopups() { - if (mPopupView) - { - mPopupView->clearPopups(); - } + if (mPopupView) + { + mPopupView->clearPopups(); + } } void LLViewerWindow::moveCursorToCenter() { - if (! gSavedSettings.getBOOL("DisableMouseWarp")) - { - S32 x = getWorldViewWidthScaled() / 2; - S32 y = getWorldViewHeightScaled() / 2; - - LLUI::getInstance()->setMousePositionScreen(x, y); - - //on a forced move, all deltas get zeroed out to prevent jumping - mCurrentMousePoint.set(x,y); - mLastMousePoint.set(x,y); - mCurrentMouseDelta.set(0,0); - } + if (! gSavedSettings.getBOOL("DisableMouseWarp")) + { + S32 x = getWorldViewWidthScaled() / 2; + S32 y = getWorldViewHeightScaled() / 2; + + LLUI::getInstance()->setMousePositionScreen(x, y); + + //on a forced move, all deltas get zeroed out to prevent jumping + mCurrentMousePoint.set(x,y); + mLastMousePoint.set(x,y); + mCurrentMouseDelta.set(0,0); + } } @@ -3282,32 +3282,32 @@ void LLViewerWindow::moveCursorToCenter() void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params) { - if (viewp) - { - if (!params.styled_message.empty()) - { - params.styled_message.add().text("\n---------\n"); - } - LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView(); - // NOTE: we skip "root" since it is assumed - for (LLView::root_to_view_iterator_t tooltip_it = ++viewp->beginRootToView(); - tooltip_it != end_tooltip_it; - ++tooltip_it) - { - LLView* viewp = *tooltip_it; - - params.styled_message.add().text(viewp->getName()); - - LLPanel* panelp = dynamic_cast(viewp); - if (panelp && !panelp->getXMLFilename().empty()) - { - params.styled_message.add() - .text("(" + panelp->getXMLFilename() + ")") - .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f)); - } - params.styled_message.add().text("/"); - } - } + if (viewp) + { + if (!params.styled_message.empty()) + { + params.styled_message.add().text("\n---------\n"); + } + LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView(); + // NOTE: we skip "root" since it is assumed + for (LLView::root_to_view_iterator_t tooltip_it = ++viewp->beginRootToView(); + tooltip_it != end_tooltip_it; + ++tooltip_it) + { + LLView* viewp = *tooltip_it; + + params.styled_message.add().text(viewp->getName()); + + LLPanel* panelp = dynamic_cast(viewp); + if (panelp && !panelp->getXMLFilename().empty()) + { + params.styled_message.add() + .text("(" + panelp->getXMLFilename() + ")") + .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f)); + } + params.styled_message.add().text("/"); + } + } } static LLTrace::BlockTimerStatHandle ftm("Update UI"); @@ -3316,922 +3316,922 @@ static LLTrace::BlockTimerStatHandle ftm("Update UI"); // event processing. void LLViewerWindow::updateUI() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm); - static std::string last_handle_msg; + static std::string last_handle_msg; - if (gLoggedInTime.getStarted()) - { - if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout")) - { - LLFirstUse::notUsingDestinationGuide(); - } - if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout")) - { - LLFirstUse::notUsingSidePanel(); - } - } + if (gLoggedInTime.getStarted()) + { + if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout")) + { + LLFirstUse::notUsingDestinationGuide(); + } + if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout")) + { + LLFirstUse::notUsingSidePanel(); + } + } - LLConsole::updateClass(); + LLConsole::updateClass(); - // animate layout stacks so we have up to date rect for world view - LLLayoutStack::updateClass(); + // animate layout stacks so we have up to date rect for world view + LLLayoutStack::updateClass(); - // use full window for world view when not rendering UI - bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); - updateWorldViewRect(world_view_uses_full_window); + // use full window for world view when not rendering UI + bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); + updateWorldViewRect(world_view_uses_full_window); - LLView::sMouseHandlerMessage.clear(); + LLView::sMouseHandlerMessage.clear(); - S32 x = mCurrentMousePoint.mX; - S32 y = mCurrentMousePoint.mY; + S32 x = mCurrentMousePoint.mX; + S32 y = mCurrentMousePoint.mY; - MASK mask = gKeyboard->currentMask(TRUE); + MASK mask = gKeyboard->currentMask(TRUE); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) - { - gDebugRaycastFaceHit = gDebugRaycastGLTFNodeHit = gDebugRaycastGLTFPrimitiveHit = -1; - gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, FALSE, - &gDebugRaycastFaceHit, + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) + { + gDebugRaycastFaceHit = gDebugRaycastGLTFNodeHit = gDebugRaycastGLTFPrimitiveHit = -1; + gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, FALSE, + &gDebugRaycastFaceHit, &gDebugRaycastGLTFNodeHit, &gDebugRaycastGLTFPrimitiveHit, - &gDebugRaycastIntersection, - &gDebugRaycastTexCoord, - &gDebugRaycastNormal, - &gDebugRaycastTangent, - &gDebugRaycastStart, - &gDebugRaycastEnd); - - gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL); - } - - updateMouseDelta(); - updateKeyboardFocus(); - - BOOL handled = FALSE; - - LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); - LLView* captor_view = dynamic_cast(mouse_captor); - - //FIXME: only include captor and captor's ancestors if mouse is truly over them --RN - - //build set of views containing mouse cursor by traversing UI hierarchy and testing - //screen rect against mouse cursor - view_handle_set_t mouse_hover_set; - - // constraint mouse enter events to children of mouse captor - LLView* root_view = captor_view; - - // if mouse captor doesn't exist or isn't a LLView - // then allow mouse enter events on entire UI hierarchy - if (!root_view) - { - root_view = mRootView; - } - - static LLCachedControl dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false); - if (dump_menu_holder) - { - static bool init = false; - static LLFrameTimer child_count_timer; - static std::vector child_vec; - if (!init) - { - child_count_timer.resetWithExpiry(5.f); - init = true; - } - if (child_count_timer.hasExpired()) - { - LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL; - std::vector local_child_vec; - LLView::child_list_t child_list = *gMenuHolder->getChildList(); - for (auto child : child_list) - { - local_child_vec.emplace_back(child->getName()); - } - if (!local_child_vec.empty() && local_child_vec != child_vec) - { - std::vector out_vec; - std::sort(local_child_vec.begin(), local_child_vec.end()); - std::sort(child_vec.begin(), child_vec.end()); - std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin())); - if (!out_vec.empty()) - { - LL_INFOS() << "gMenuHolder removal diff size: '"<getParent(); - while(captor_parent_view) - { - mouse_hover_set.insert(captor_parent_view->getHandle()); - captor_parent_view = captor_parent_view->getParent(); - } - } - - // aggregate visible views that contain mouse cursor in display order - LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups(); - - for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it) - { - LLView* popup = popup_it->get(); - if (popup && popup->calcScreenBoundingRect().pointInRect(x, y)) - { - // iterator over contents of top_ctrl, and throw into mouse_hover_set - for (LLView::tree_iterator_t it = popup->beginTreeDFS(); - it != popup->endTreeDFS(); - ++it) - { - LLView* viewp = *it; - if (viewp->getVisible() - && viewp->calcScreenBoundingRect().pointInRect(x, y)) - { - // we have a view that contains the mouse, add it to the set - mouse_hover_set.insert(viewp->getHandle()); - } - else - { - // skip this view and all of its children - it.skipDescendants(); - } - } - } - } - - // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events - if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y)) - { - // iterator over contents of top_ctrl, and throw into mouse_hover_set - for (LLView::tree_iterator_t it = top_ctrl->beginTreeDFS(); - it != top_ctrl->endTreeDFS(); - ++it) - { - LLView* viewp = *it; - if (viewp->getVisible() - && viewp->calcScreenBoundingRect().pointInRect(x, y)) - { - // we have a view that contains the mouse, add it to the set - mouse_hover_set.insert(viewp->getHandle()); - } - else - { - // skip this view and all of its children - it.skipDescendants(); - } - } - } - else - { - // walk UI tree in depth-first order - for (LLView::tree_iterator_t it = root_view->beginTreeDFS(); - it != root_view->endTreeDFS(); - ++it) - { - LLView* viewp = *it; - // calculating the screen rect involves traversing the parent, so this is less than optimal - if (viewp->getVisible() - && viewp->calcScreenBoundingRect().pointInRect(x, y)) - { - - // if this view is mouse opaque, nothing behind it should be in mouse_hover_set - if (viewp->getMouseOpaque()) - { - // constrain further iteration to children of this widget - it = viewp->beginTreeDFS(); - } - - // we have a view that contains the mouse, add it to the set - mouse_hover_set.insert(viewp->getHandle()); - } - else - { - // skip this view and all of its children - it.skipDescendants(); - } - } - } - } - - typedef std::vector > view_handle_list_t; - - // call onMouseEnter() on all views which contain the mouse cursor but did not before - view_handle_list_t mouse_enter_views; - std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(), - mMouseHoverViews.begin(), mMouseHoverViews.end(), - std::back_inserter(mouse_enter_views)); - for (view_handle_list_t::iterator it = mouse_enter_views.begin(); - it != mouse_enter_views.end(); - ++it) - { - LLView* viewp = it->get(); - if (viewp) - { - LLRect view_screen_rect = viewp->calcScreenRect(); - viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask); - } - } - - // call onMouseLeave() on all views which no longer contain the mouse cursor - view_handle_list_t mouse_leave_views; - std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(), - mouse_hover_set.begin(), mouse_hover_set.end(), - std::back_inserter(mouse_leave_views)); - for (view_handle_list_t::iterator it = mouse_leave_views.begin(); - it != mouse_leave_views.end(); - ++it) - { - LLView* viewp = it->get(); - if (viewp) - { - LLRect view_screen_rect = viewp->calcScreenRect(); - viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask); - } - } - - // store resulting hover set for next frame - swap(mMouseHoverViews, mouse_hover_set); - - // only handle hover events when UI is enabled - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - - if( mouse_captor ) - { - // Pass hover events to object capturing mouse events. - S32 local_x; - S32 local_y; - mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); - handled = mouse_captor->handleHover(local_x, local_y, mask); - if (LLView::sDebugMouseHandling) - { - LL_INFOS() << "Hover handled by captor " << mouse_captor->getName() << LL_ENDL; - } - - if( !handled ) - { - LL_DEBUGS("UserInput") << "hover not handled by mouse captor" << LL_ENDL; - } - } - else - { - if (top_ctrl) - { - S32 local_x, local_y; - top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); - handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask); - } - - if ( !handled ) - { - // x and y are from last time mouse was in window - // mMouseInWindow tracks *actual* mouse location - if (mMouseInWindow && mRootView->handleHover(x, y, mask) ) - { - if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg) - { - last_handle_msg = LLView::sMouseHandlerMessage; - LL_INFOS() << "Hover" << LLView::sMouseHandlerMessage << LL_ENDL; - } - handled = TRUE; - } - else if (LLView::sDebugMouseHandling) - { - if (last_handle_msg != LLStringUtil::null) - { - last_handle_msg.clear(); - LL_INFOS() << "Hover not handled by view" << LL_ENDL; - } - } - } - - if (!handled) - { - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - - if(mMouseInWindow && tool) - { - handled = tool->handleHover(x, y, mask); - } - } - } - - // Show a new tool tip (or update one that is already shown) - BOOL tool_tip_handled = FALSE; - std::string tool_tip_msg; - if( handled - && !mWindow->isCursorHidden()) - { - LLRect screen_sticky_rect = mRootView->getLocalRect(); - S32 local_x, local_y; - - static LLCachedControl debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0); - if (debug_show_xui_names) - { - LLToolTip::Params params; - - LLView* tooltip_view = mRootView; - LLView::tree_iterator_t end_it = mRootView->endTreeDFS(); - for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it) - { - LLView* viewp = *it; - LLRect screen_rect; - viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect); - if (!(viewp->getVisible() - && screen_rect.pointInRect(x, y))) - { - it.skipDescendants(); - } - // only report xui names for LLUICtrls, - // and blacklist the various containers we don't care about - else if (dynamic_cast(viewp) - && viewp != gMenuHolder - && viewp != gFloaterView - && viewp != gConsole) - { - if (dynamic_cast(viewp)) - { - // constrain search to descendants of this (frontmost) floater - // by resetting iterator - it = viewp->beginTreeDFS(); - } - - // if we are in a new part of the tree (not a descendent of current tooltip_view) - // then push the results for tooltip_view and start with a new potential view - // NOTE: this emulates visiting only the leaf nodes that meet our criteria - if (!viewp->hasAncestor(tooltip_view)) - { - append_xui_tooltip(tooltip_view, params); - screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); - } - tooltip_view = viewp; - } - } - - append_xui_tooltip(tooltip_view, params); - params.styled_message.add().text("\n"); - - screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); - - params.sticky_rect = screen_sticky_rect; - params.max_width = 400; - - LLToolTipMgr::instance().show(params); - } - // if there is a mouse captor, nothing else gets a tooltip - else if (mouse_captor) - { - mouse_captor->screenPointToLocal(x, y, &local_x, &local_y); - tool_tip_handled = mouse_captor->handleToolTip(local_x, local_y, mask); - } - else - { - // next is top_ctrl - if (!tool_tip_handled && top_ctrl) - { - top_ctrl->screenPointToLocal(x, y, &local_x, &local_y); - tool_tip_handled = top_ctrl->handleToolTip(local_x, local_y, mask ); - } - - if (!tool_tip_handled) - { - local_x = x; local_y = y; - tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask ); - } - - LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool(); - if (!tool_tip_handled && current_tool) - { - current_tool->screenPointToLocal(x, y, &local_x, &local_y); - tool_tip_handled = current_tool->handleToolTip(local_x, local_y, mask ); - } - } - } - } - else - { // just have tools handle hover when UI is turned off - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - - if(mMouseInWindow && tool) - { - handled = tool->handleHover(x, y, mask); - } - } - - updateLayout(); - - mLastMousePoint = mCurrentMousePoint; - - // cleanup unused selections when no modal dialogs are open - if (LLModalDialog::activeCount() == 0) - { - LLViewerParcelMgr::getInstance()->deselectUnused(); - } - - if (LLModalDialog::activeCount() == 0) - { - LLSelectMgr::getInstance()->deselectUnused(); - } -} - - -void LLViewerWindow::updateLayout() -{ - LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); - if (gFloaterTools != NULL - && tool != NULL - && tool != gToolNull - && tool != LLToolCompInspect::getInstance() - && tool != LLToolDragAndDrop::getInstance() - && !gSavedSettings.getBOOL("FreezeTime")) - { - // Suppress the toolbox view if our source tool was the pie tool, - // and we've overridden to something else. - bool suppress_toolbox = - (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) && - (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()); - - LLMouseHandler *captor = gFocusMgr.getMouseCapture(); - // With the null, inspect, or drag and drop tool, don't muck - // with visibility. - - if (gFloaterTools->isMinimized() - || (tool != LLToolPie::getInstance() // not default tool - && tool != LLToolCompGun::getInstance() // not coming out of mouselook - && !suppress_toolbox // not override in third person - && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools() - && (!captor || dynamic_cast(captor) != NULL))) // not dragging - { - // Force floater tools to be visible (unless minimized) - if (!gFloaterTools->getVisible()) - { - gFloaterTools->openFloater(); - } - // Update the location of the blue box tool popup - LLCoordGL select_center_screen; - MASK mask = gKeyboard->currentMask(TRUE); - gFloaterTools->updatePopup( select_center_screen, mask ); - } - else - { - gFloaterTools->setVisible(FALSE); - } - //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible()); - } - - // Always update console - if(gConsole) - { - LLRect console_rect = getChatConsoleRect(); - gConsole->reshape(console_rect.getWidth(), console_rect.getHeight()); - gConsole->setRect(console_rect); - } -} + &gDebugRaycastIntersection, + &gDebugRaycastTexCoord, + &gDebugRaycastNormal, + &gDebugRaycastTangent, + &gDebugRaycastStart, + &gDebugRaycastEnd); + + gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL); + } -void LLViewerWindow::updateMouseDelta() -{ -#if LL_WINDOWS - LLCoordCommon delta; - mWindow->getCursorDelta(&delta); - S32 dx = delta.mX; - S32 dy = delta.mY; -#else - S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]); - S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); -#endif + updateMouseDelta(); + updateKeyboardFocus(); - //RN: fix for asynchronous notification of mouse leaving window not working - LLCoordWindow mouse_pos; - mWindow->getCursorPosition(&mouse_pos); - if (mouse_pos.mX < 0 || - mouse_pos.mY < 0 || - mouse_pos.mX > mWindowRectRaw.getWidth() || - mouse_pos.mY > mWindowRectRaw.getHeight()) - { - mMouseInWindow = FALSE; - } - else - { - mMouseInWindow = TRUE; - } - - LLVector2 mouse_vel; - - if (gSavedSettings.getBOOL("MouseSmooth")) - { - static F32 fdx = 0.f; - static F32 fdy = 0.f; - - F32 amount = 16.f; - fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f); - fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f); - - mCurrentMouseDelta.set(ll_round(fdx), ll_round(fdy)); - mouse_vel.setVec(fdx,fdy); - } - else - { - mCurrentMouseDelta.set(dx, dy); - mouse_vel.setVec((F32) dx, (F32) dy); - } - - sample(sMouseVelocityStat, mouse_vel.magVec()); -} + BOOL handled = FALSE; -void LLViewerWindow::updateKeyboardFocus() -{ - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - gFocusMgr.setKeyboardFocus(NULL); - } - - // clean up current focus - LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); - if (cur_focus) - { - if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain()) - { - // don't release focus, just reassign so that if being given - // to a sibling won't call onFocusLost on all the ancestors - // gFocusMgr.releaseFocusIfNeeded(cur_focus); - - LLUICtrl* parent = cur_focus->getParentUICtrl(); - const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot(); - bool new_focus_found = false; - while(parent) - { - if (parent->isCtrl() - && (parent->hasTabStop() || parent == focus_root) - && !parent->getIsChrome() - && parent->isInVisibleChain() - && parent->isInEnabledChain()) - { - if (!parent->focusFirstItem()) - { - parent->setFocus(TRUE); - } - new_focus_found = true; - break; - } - parent = parent->getParentUICtrl(); - } - - // if we didn't find a better place to put focus, just release it - // hasFocus() will return true if and only if we didn't touch focus since we - // are only moving focus higher in the hierarchy - if (!new_focus_found) - { - cur_focus->setFocus(FALSE); - } - } - else if (cur_focus->isFocusRoot()) - { - // focus roots keep trying to delegate focus to their first valid descendant - // this assumes that focus roots are not valid focus holders on their own - cur_focus->focusFirstItem(); - } - } - - // last ditch force of edit menu to selection manager - if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) - { - LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); - } - - if (gFloaterView->getCycleMode()) - { - // sync all floaters with their focus state - gFloaterView->highlightFocusedFloater(); - gSnapshotFloaterView->highlightFocusedFloater(); - MASK mask = gKeyboard->currentMask(TRUE); - if ((mask & MASK_CONTROL) == 0) - { - // control key no longer held down, finish cycle mode - gFloaterView->setCycleMode(FALSE); - - gFloaterView->syncFloaterTabOrder(); - } - else - { - // user holding down CTRL, don't update tab order of floaters - } - } - else - { - // update focused floater - gFloaterView->highlightFocusedFloater(); - gSnapshotFloaterView->highlightFocusedFloater(); - // make sure floater visible order is in sync with tab order - gFloaterView->syncFloaterTabOrder(); - } -} + LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); + LLView* captor_view = dynamic_cast(mouse_captor); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_WORLD_VIEW("Update World View"); -void LLViewerWindow::updateWorldViewRect(bool use_full_window) -{ - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WORLD_VIEW); + //FIXME: only include captor and captor's ancestors if mouse is truly over them --RN - // start off using whole window to render world - LLRect new_world_rect = mWindowRectRaw; + //build set of views containing mouse cursor by traversing UI hierarchy and testing + //screen rect against mouse cursor + view_handle_set_t mouse_hover_set; - if (use_full_window == false && mWorldViewPlaceholder.get()) - { - new_world_rect = mWorldViewPlaceholder.get()->calcScreenRect(); - // clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers - new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1); - new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1); + // constraint mouse enter events to children of mouse captor + LLView* root_view = captor_view; - new_world_rect.mLeft = ll_round((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]); - new_world_rect.mRight = ll_round((F32)new_world_rect.mRight * mDisplayScale.mV[VX]); - new_world_rect.mBottom = ll_round((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]); - new_world_rect.mTop = ll_round((F32)new_world_rect.mTop * mDisplayScale.mV[VY]); - } + // if mouse captor doesn't exist or isn't a LLView + // then allow mouse enter events on entire UI hierarchy + if (!root_view) + { + root_view = mRootView; + } - if (mWorldViewRectRaw != new_world_rect) - { - mWorldViewRectRaw = new_world_rect; - gResizeScreenTexture = TRUE; - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + static LLCachedControl dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false); + if (dump_menu_holder) + { + static bool init = false; + static LLFrameTimer child_count_timer; + static std::vector child_vec; + if (!init) + { + child_count_timer.resetWithExpiry(5.f); + init = true; + } + if (child_count_timer.hasExpired()) + { + LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL; + std::vector local_child_vec; + LLView::child_list_t child_list = *gMenuHolder->getChildList(); + for (auto child : child_list) + { + local_child_vec.emplace_back(child->getName()); + } + if (!local_child_vec.empty() && local_child_vec != child_vec) + { + std::vector out_vec; + std::sort(local_child_vec.begin(), local_child_vec.end()); + std::sort(child_vec.begin(), child_vec.end()); + std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin())); + if (!out_vec.empty()) + { + LL_INFOS() << "gMenuHolder removal diff size: '"<getParent(); + while(captor_parent_view) + { + mouse_hover_set.insert(captor_parent_view->getHandle()); + captor_parent_view = captor_parent_view->getParent(); + } + } + + // aggregate visible views that contain mouse cursor in display order + LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups(); + + for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it) + { + LLView* popup = popup_it->get(); + if (popup && popup->calcScreenBoundingRect().pointInRect(x, y)) + { + // iterator over contents of top_ctrl, and throw into mouse_hover_set + for (LLView::tree_iterator_t it = popup->beginTreeDFS(); + it != popup->endTreeDFS(); + ++it) + { + LLView* viewp = *it; + if (viewp->getVisible() + && viewp->calcScreenBoundingRect().pointInRect(x, y)) + { + // we have a view that contains the mouse, add it to the set + mouse_hover_set.insert(viewp->getHandle()); + } + else + { + // skip this view and all of its children + it.skipDescendants(); + } + } + } + } + + // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events + if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y)) + { + // iterator over contents of top_ctrl, and throw into mouse_hover_set + for (LLView::tree_iterator_t it = top_ctrl->beginTreeDFS(); + it != top_ctrl->endTreeDFS(); + ++it) + { + LLView* viewp = *it; + if (viewp->getVisible() + && viewp->calcScreenBoundingRect().pointInRect(x, y)) + { + // we have a view that contains the mouse, add it to the set + mouse_hover_set.insert(viewp->getHandle()); + } + else + { + // skip this view and all of its children + it.skipDescendants(); + } + } + } + else + { + // walk UI tree in depth-first order + for (LLView::tree_iterator_t it = root_view->beginTreeDFS(); + it != root_view->endTreeDFS(); + ++it) + { + LLView* viewp = *it; + // calculating the screen rect involves traversing the parent, so this is less than optimal + if (viewp->getVisible() + && viewp->calcScreenBoundingRect().pointInRect(x, y)) + { + + // if this view is mouse opaque, nothing behind it should be in mouse_hover_set + if (viewp->getMouseOpaque()) + { + // constrain further iteration to children of this widget + it = viewp->beginTreeDFS(); + } + + // we have a view that contains the mouse, add it to the set + mouse_hover_set.insert(viewp->getHandle()); + } + else + { + // skip this view and all of its children + it.skipDescendants(); + } + } + } + } + + typedef std::vector > view_handle_list_t; + + // call onMouseEnter() on all views which contain the mouse cursor but did not before + view_handle_list_t mouse_enter_views; + std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(), + mMouseHoverViews.begin(), mMouseHoverViews.end(), + std::back_inserter(mouse_enter_views)); + for (view_handle_list_t::iterator it = mouse_enter_views.begin(); + it != mouse_enter_views.end(); + ++it) + { + LLView* viewp = it->get(); + if (viewp) + { + LLRect view_screen_rect = viewp->calcScreenRect(); + viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask); + } + } + + // call onMouseLeave() on all views which no longer contain the mouse cursor + view_handle_list_t mouse_leave_views; + std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(), + mouse_hover_set.begin(), mouse_hover_set.end(), + std::back_inserter(mouse_leave_views)); + for (view_handle_list_t::iterator it = mouse_leave_views.begin(); + it != mouse_leave_views.end(); + ++it) + { + LLView* viewp = it->get(); + if (viewp) + { + LLRect view_screen_rect = viewp->calcScreenRect(); + viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask); + } + } + + // store resulting hover set for next frame + swap(mMouseHoverViews, mouse_hover_set); + + // only handle hover events when UI is enabled + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + + if( mouse_captor ) + { + // Pass hover events to object capturing mouse events. + S32 local_x; + S32 local_y; + mouse_captor->screenPointToLocal( x, y, &local_x, &local_y ); + handled = mouse_captor->handleHover(local_x, local_y, mask); + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Hover handled by captor " << mouse_captor->getName() << LL_ENDL; + } + + if( !handled ) + { + LL_DEBUGS("UserInput") << "hover not handled by mouse captor" << LL_ENDL; + } + } + else + { + if (top_ctrl) + { + S32 local_x, local_y; + top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); + handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask); + } + + if ( !handled ) + { + // x and y are from last time mouse was in window + // mMouseInWindow tracks *actual* mouse location + if (mMouseInWindow && mRootView->handleHover(x, y, mask) ) + { + if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg) + { + last_handle_msg = LLView::sMouseHandlerMessage; + LL_INFOS() << "Hover" << LLView::sMouseHandlerMessage << LL_ENDL; + } + handled = TRUE; + } + else if (LLView::sDebugMouseHandling) + { + if (last_handle_msg != LLStringUtil::null) + { + last_handle_msg.clear(); + LL_INFOS() << "Hover not handled by view" << LL_ENDL; + } + } + } + + if (!handled) + { + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + + if(mMouseInWindow && tool) + { + handled = tool->handleHover(x, y, mask); + } + } + } + + // Show a new tool tip (or update one that is already shown) + BOOL tool_tip_handled = FALSE; + std::string tool_tip_msg; + if( handled + && !mWindow->isCursorHidden()) + { + LLRect screen_sticky_rect = mRootView->getLocalRect(); + S32 local_x, local_y; + + static LLCachedControl debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0); + if (debug_show_xui_names) + { + LLToolTip::Params params; + + LLView* tooltip_view = mRootView; + LLView::tree_iterator_t end_it = mRootView->endTreeDFS(); + for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it) + { + LLView* viewp = *it; + LLRect screen_rect; + viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect); + if (!(viewp->getVisible() + && screen_rect.pointInRect(x, y))) + { + it.skipDescendants(); + } + // only report xui names for LLUICtrls, + // and blacklist the various containers we don't care about + else if (dynamic_cast(viewp) + && viewp != gMenuHolder + && viewp != gFloaterView + && viewp != gConsole) + { + if (dynamic_cast(viewp)) + { + // constrain search to descendants of this (frontmost) floater + // by resetting iterator + it = viewp->beginTreeDFS(); + } + + // if we are in a new part of the tree (not a descendent of current tooltip_view) + // then push the results for tooltip_view and start with a new potential view + // NOTE: this emulates visiting only the leaf nodes that meet our criteria + if (!viewp->hasAncestor(tooltip_view)) + { + append_xui_tooltip(tooltip_view, params); + screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); + } + tooltip_view = viewp; + } + } + + append_xui_tooltip(tooltip_view, params); + params.styled_message.add().text("\n"); + + screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect()); + + params.sticky_rect = screen_sticky_rect; + params.max_width = 400; + + LLToolTipMgr::instance().show(params); + } + // if there is a mouse captor, nothing else gets a tooltip + else if (mouse_captor) + { + mouse_captor->screenPointToLocal(x, y, &local_x, &local_y); + tool_tip_handled = mouse_captor->handleToolTip(local_x, local_y, mask); + } + else + { + // next is top_ctrl + if (!tool_tip_handled && top_ctrl) + { + top_ctrl->screenPointToLocal(x, y, &local_x, &local_y); + tool_tip_handled = top_ctrl->handleToolTip(local_x, local_y, mask ); + } + + if (!tool_tip_handled) + { + local_x = x; local_y = y; + tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask ); + } + + LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool(); + if (!tool_tip_handled && current_tool) + { + current_tool->screenPointToLocal(x, y, &local_x, &local_y); + tool_tip_handled = current_tool->handleToolTip(local_x, local_y, mask ); + } + } + } + } + else + { // just have tools handle hover when UI is turned off + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + + if(mMouseInWindow && tool) + { + handled = tool->handleHover(x, y, mask); + } + } + + updateLayout(); + + mLastMousePoint = mCurrentMousePoint; + + // cleanup unused selections when no modal dialogs are open + if (LLModalDialog::activeCount() == 0) + { + LLViewerParcelMgr::getInstance()->deselectUnused(); + } + + if (LLModalDialog::activeCount() == 0) + { + LLSelectMgr::getInstance()->deselectUnused(); + } +} + + +void LLViewerWindow::updateLayout() +{ + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); + if (gFloaterTools != NULL + && tool != NULL + && tool != gToolNull + && tool != LLToolCompInspect::getInstance() + && tool != LLToolDragAndDrop::getInstance() + && !gSavedSettings.getBOOL("FreezeTime")) + { + // Suppress the toolbox view if our source tool was the pie tool, + // and we've overridden to something else. + bool suppress_toolbox = + (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) && + (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()); + + LLMouseHandler *captor = gFocusMgr.getMouseCapture(); + // With the null, inspect, or drag and drop tool, don't muck + // with visibility. + + if (gFloaterTools->isMinimized() + || (tool != LLToolPie::getInstance() // not default tool + && tool != LLToolCompGun::getInstance() // not coming out of mouselook + && !suppress_toolbox // not override in third person + && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools() + && (!captor || dynamic_cast(captor) != NULL))) // not dragging + { + // Force floater tools to be visible (unless minimized) + if (!gFloaterTools->getVisible()) + { + gFloaterTools->openFloater(); + } + // Update the location of the blue box tool popup + LLCoordGL select_center_screen; + MASK mask = gKeyboard->currentMask(TRUE); + gFloaterTools->updatePopup( select_center_screen, mask ); + } + else + { + gFloaterTools->setVisible(FALSE); + } + //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible()); + } + + // Always update console + if(gConsole) + { + LLRect console_rect = getChatConsoleRect(); + gConsole->reshape(console_rect.getWidth(), console_rect.getHeight()); + gConsole->setRect(console_rect); + } +} + +void LLViewerWindow::updateMouseDelta() +{ +#if LL_WINDOWS + LLCoordCommon delta; + mWindow->getCursorDelta(&delta); + S32 dx = delta.mX; + S32 dy = delta.mY; +#else + S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]); + S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); +#endif + + //RN: fix for asynchronous notification of mouse leaving window not working + LLCoordWindow mouse_pos; + mWindow->getCursorPosition(&mouse_pos); + if (mouse_pos.mX < 0 || + mouse_pos.mY < 0 || + mouse_pos.mX > mWindowRectRaw.getWidth() || + mouse_pos.mY > mWindowRectRaw.getHeight()) + { + mMouseInWindow = FALSE; + } + else + { + mMouseInWindow = TRUE; + } + + LLVector2 mouse_vel; + + if (gSavedSettings.getBOOL("MouseSmooth")) + { + static F32 fdx = 0.f; + static F32 fdy = 0.f; + + F32 amount = 16.f; + fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f); + fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f); - // sending a signal with a new WorldView rect - mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled); - } + mCurrentMouseDelta.set(ll_round(fdx), ll_round(fdy)); + mouse_vel.setVec(fdx,fdy); + } + else + { + mCurrentMouseDelta.set(dx, dy); + mouse_vel.setVec((F32) dx, (F32) dy); + } + + sample(sMouseVelocityStat, mouse_vel.magVec()); +} + +void LLViewerWindow::updateKeyboardFocus() +{ + if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + gFocusMgr.setKeyboardFocus(NULL); + } + + // clean up current focus + LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); + if (cur_focus) + { + if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain()) + { + // don't release focus, just reassign so that if being given + // to a sibling won't call onFocusLost on all the ancestors + // gFocusMgr.releaseFocusIfNeeded(cur_focus); + + LLUICtrl* parent = cur_focus->getParentUICtrl(); + const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot(); + bool new_focus_found = false; + while(parent) + { + if (parent->isCtrl() + && (parent->hasTabStop() || parent == focus_root) + && !parent->getIsChrome() + && parent->isInVisibleChain() + && parent->isInEnabledChain()) + { + if (!parent->focusFirstItem()) + { + parent->setFocus(TRUE); + } + new_focus_found = true; + break; + } + parent = parent->getParentUICtrl(); + } + + // if we didn't find a better place to put focus, just release it + // hasFocus() will return true if and only if we didn't touch focus since we + // are only moving focus higher in the hierarchy + if (!new_focus_found) + { + cur_focus->setFocus(FALSE); + } + } + else if (cur_focus->isFocusRoot()) + { + // focus roots keep trying to delegate focus to their first valid descendant + // this assumes that focus roots are not valid focus holders on their own + cur_focus->focusFirstItem(); + } + } + + // last ditch force of edit menu to selection manager + if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) + { + LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); + } + + if (gFloaterView->getCycleMode()) + { + // sync all floaters with their focus state + gFloaterView->highlightFocusedFloater(); + gSnapshotFloaterView->highlightFocusedFloater(); + MASK mask = gKeyboard->currentMask(TRUE); + if ((mask & MASK_CONTROL) == 0) + { + // control key no longer held down, finish cycle mode + gFloaterView->setCycleMode(FALSE); + + gFloaterView->syncFloaterTabOrder(); + } + else + { + // user holding down CTRL, don't update tab order of floaters + } + } + else + { + // update focused floater + gFloaterView->highlightFocusedFloater(); + gSnapshotFloaterView->highlightFocusedFloater(); + // make sure floater visible order is in sync with tab order + gFloaterView->syncFloaterTabOrder(); + } +} + +static LLTrace::BlockTimerStatHandle FTM_UPDATE_WORLD_VIEW("Update World View"); +void LLViewerWindow::updateWorldViewRect(bool use_full_window) +{ + LL_RECORD_BLOCK_TIME(FTM_UPDATE_WORLD_VIEW); + + // start off using whole window to render world + LLRect new_world_rect = mWindowRectRaw; + + if (use_full_window == false && mWorldViewPlaceholder.get()) + { + new_world_rect = mWorldViewPlaceholder.get()->calcScreenRect(); + // clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers + new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1); + new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1); + + new_world_rect.mLeft = ll_round((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]); + new_world_rect.mRight = ll_round((F32)new_world_rect.mRight * mDisplayScale.mV[VX]); + new_world_rect.mBottom = ll_round((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]); + new_world_rect.mTop = ll_round((F32)new_world_rect.mTop * mDisplayScale.mV[VY]); + } + + if (mWorldViewRectRaw != new_world_rect) + { + mWorldViewRectRaw = new_world_rect; + gResizeScreenTexture = TRUE; + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + + LLRect old_world_rect_scaled = mWorldViewRectScaled; + mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); + + // sending a signal with a new WorldView rect + mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled); + } } void LLViewerWindow::saveLastMouse(const LLCoordGL &point) { - // Store last mouse location. - // If mouse leaves window, pretend last point was on edge of window - - if (point.mX < 0) - { - mCurrentMousePoint.mX = 0; - } - else if (point.mX > getWindowWidthScaled()) - { - mCurrentMousePoint.mX = getWindowWidthScaled(); - } - else - { - mCurrentMousePoint.mX = point.mX; - } - - if (point.mY < 0) - { - mCurrentMousePoint.mY = 0; - } - else if (point.mY > getWindowHeightScaled() ) - { - mCurrentMousePoint.mY = getWindowHeightScaled(); - } - else - { - mCurrentMousePoint.mY = point.mY; - } + // Store last mouse location. + // If mouse leaves window, pretend last point was on edge of window + + if (point.mX < 0) + { + mCurrentMousePoint.mX = 0; + } + else if (point.mX > getWindowWidthScaled()) + { + mCurrentMousePoint.mX = getWindowWidthScaled(); + } + else + { + mCurrentMousePoint.mX = point.mX; + } + + if (point.mY < 0) + { + mCurrentMousePoint.mY = 0; + } + else if (point.mY > getWindowHeightScaled() ) + { + mCurrentMousePoint.mY = getWindowHeightScaled(); + } + else + { + mCurrentMousePoint.mY = point.mY; + } } // Draws the selection outlines for the currently selected objects // Must be called after displayObjects is called, which sets the mGLName parameter // NOTE: This function gets called 3 times: -// render_ui_3d: FALSE, FALSE, TRUE -// render_hud_elements: FALSE, FALSE, FALSE +// render_ui_3d: FALSE, FALSE, TRUE +// render_hud_elements: FALSE, FALSE, FALSE void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud ) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - if (!for_hud && !for_gl_pick) - { - // Call this once and only once - LLSelectMgr::getInstance()->updateSilhouettes(); - } - - // Draw fence around land selections - if (for_gl_pick) - { - if (pick_parcel_walls) - { - LLViewerParcelMgr::getInstance()->renderParcelCollision(); - } - } - else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) || - (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD)) - { - LLSelectMgr::getInstance()->renderSilhouettes(for_hud); - - stop_glerror(); - - // setup HUD render - if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) - { - LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); - - // set up transform to encompass bounding box of HUD - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame - gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f); - } - - // Render light for editing - if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit()) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLEnable gls_blend(GL_BLEND); - LLGLEnable gls_cull(GL_CULL_FACE); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - if (selection->getSelectType() == SELECT_TYPE_HUD) - { - F32 zoom = gAgentCamera.mHUDCurZoom; - gGL.scalef(zoom, zoom, zoom); - } - - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - LLDrawable* drawable = object->mDrawable; - if (drawable && drawable->isLight()) - { - LLVOVolume* vovolume = drawable->getVOVolume(); - gGL.pushMatrix(); - - LLVector3 center = drawable->getPositionAgent(); - gGL.translatef(center[0], center[1], center[2]); - F32 scale = vovolume->getLightRadius(); - gGL.scalef(scale, scale, scale); - - LLColor4 color(vovolume->getLightSRGBColor(), .5f); - gGL.color4fv(color.mV); - - //F32 pixel_area = 100000.f; - // Render Outside - gSphere.render(); - - // Render Inside - glCullFace(GL_FRONT); - gSphere.render(); - glCullFace(GL_BACK); - - gGL.popMatrix(); - } - return true; - } - } func; - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); - - gGL.popMatrix(); - } - - // NOTE: The average position for the axis arrows of the selected objects should - // not be recalculated at this time. If they are, then group rotations will break. - - // Draw arrows at average center of all selected objects - LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); - if (tool) - { - if(tool->isAlwaysRendered()) - { - tool->render(); - } - else - { - if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() ) - { - bool all_selected_objects_move; - bool all_selected_objects_modify; - // Note: This might be costly to do on each frame and when a lot of objects are selected - // we might be better off with some kind of memory for selection and/or states, consider - // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to - // make whole viewer benefit. - LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify); - - BOOL draw_handles = TRUE; - - if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) - { - draw_handles = FALSE; - } - - if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) - { - draw_handles = FALSE; - } - - if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() ) - { - draw_handles = FALSE; - } - - if( draw_handles ) - { - tool->render(); - } - } - } - if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount()) - { - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - stop_glerror(); - } - } - } + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + if (!for_hud && !for_gl_pick) + { + // Call this once and only once + LLSelectMgr::getInstance()->updateSilhouettes(); + } + + // Draw fence around land selections + if (for_gl_pick) + { + if (pick_parcel_walls) + { + LLViewerParcelMgr::getInstance()->renderParcelCollision(); + } + } + else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) || + (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD)) + { + LLSelectMgr::getInstance()->renderSilhouettes(for_hud); + + stop_glerror(); + + // setup HUD render + if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) + { + LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); + + // set up transform to encompass bounding box of HUD + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); + gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame + gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f); + } + + // Render light for editing + if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit()) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLEnable gls_blend(GL_BLEND); + LLGLEnable gls_cull(GL_CULL_FACE); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + if (selection->getSelectType() == SELECT_TYPE_HUD) + { + F32 zoom = gAgentCamera.mHUDCurZoom; + gGL.scalef(zoom, zoom, zoom); + } + + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + LLDrawable* drawable = object->mDrawable; + if (drawable && drawable->isLight()) + { + LLVOVolume* vovolume = drawable->getVOVolume(); + gGL.pushMatrix(); + + LLVector3 center = drawable->getPositionAgent(); + gGL.translatef(center[0], center[1], center[2]); + F32 scale = vovolume->getLightRadius(); + gGL.scalef(scale, scale, scale); + + LLColor4 color(vovolume->getLightSRGBColor(), .5f); + gGL.color4fv(color.mV); + + //F32 pixel_area = 100000.f; + // Render Outside + gSphere.render(); + + // Render Inside + glCullFace(GL_FRONT); + gSphere.render(); + glCullFace(GL_BACK); + + gGL.popMatrix(); + } + return true; + } + } func; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); + + gGL.popMatrix(); + } + + // NOTE: The average position for the axis arrows of the selected objects should + // not be recalculated at this time. If they are, then group rotations will break. + + // Draw arrows at average center of all selected objects + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); + if (tool) + { + if(tool->isAlwaysRendered()) + { + tool->render(); + } + else + { + if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() ) + { + bool all_selected_objects_move; + bool all_selected_objects_modify; + // Note: This might be costly to do on each frame and when a lot of objects are selected + // we might be better off with some kind of memory for selection and/or states, consider + // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to + // make whole viewer benefit. + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify); + + BOOL draw_handles = TRUE; + + if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) + { + draw_handles = FALSE; + } + + if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) + { + draw_handles = FALSE; + } + + if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() ) + { + draw_handles = FALSE; + } + + if( draw_handles ) + { + tool->render(); + } + } + } + if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount()) + { + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + stop_glerror(); + } + } + } } // Return a point near the clicked object representative of the place the object was clicked. LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLViewerObject* clicked_object) const { - // create a normalized vector pointing from the camera center into the - // world at the location of the mouse click - LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot ); + // create a normalized vector pointing from the camera center into the + // world at the location of the mouse click + LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot ); - LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); + LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); - // make mouse vector as long as object vector, so it touchs a point near - // where the user clicked on the object - mouse_direction_global *= (F32) relative_object.magVec(); + // make mouse vector as long as object vector, so it touchs a point near + // where the user clicked on the object + mouse_direction_global *= (F32) relative_object.magVec(); - LLVector3d new_pos; - new_pos.setVec(mouse_direction_global); - // transform mouse vector back to world coords - new_pos += gAgentCamera.getCameraPositionGlobal(); + LLVector3d new_pos; + new_pos.setVec(mouse_direction_global); + // transform mouse vector back to world coords + new_pos += gAgentCamera.getCameraPositionGlobal(); - return new_pos; + return new_pos; } BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const { - BOOL intersect = FALSE; + BOOL intersect = FALSE; -// U8 shape = objectp->mPrimitiveCode & LL_PCODE_BASE_MASK; - if (!intersect) - { - point_global = clickPointInWorldGlobal(x, y, objectp); - LL_INFOS() << "approx intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL; - } - else - { - LL_INFOS() << "good intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL; - } +// U8 shape = objectp->mPrimitiveCode & LL_PCODE_BASE_MASK; + if (!intersect) + { + point_global = clickPointInWorldGlobal(x, y, objectp); + LL_INFOS() << "approx intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL; + } + else + { + LL_INFOS() << "good intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL; + } - return intersect; + return intersect; } void LLViewerWindow::pickAsync( S32 x, - S32 y_from_bot, - MASK mask, - void (*callback)(const LLPickInfo& info), - BOOL pick_transparent, - BOOL pick_rigged, - BOOL pick_unselectable, + S32 y_from_bot, + MASK mask, + void (*callback)(const LLPickInfo& info), + BOOL pick_transparent, + BOOL pick_rigged, + BOOL pick_unselectable, BOOL pick_reflection_probes) { - // "Show Debug Alpha" means no object actually transparent + // "Show Debug Alpha" means no object actually transparent BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); if (LLDrawPoolAlpha::sShowDebugAlpha || (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects"))) @@ -4239,587 +4239,587 @@ void LLViewerWindow::pickAsync( S32 x, pick_transparent = TRUE; } - LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, pick_reflection_probes, pick_unselectable, TRUE, callback); - schedulePick(pick_info); + LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, pick_reflection_probes, pick_unselectable, TRUE, callback); + schedulePick(pick_info); } void LLViewerWindow::schedulePick(LLPickInfo& pick_info) { - if (mPicks.size() >= 1024 || mWindow->getMinimized()) - { //something went wrong, picks are being scheduled but not processed - - if (pick_info.mPickCallback) - { - pick_info.mPickCallback(pick_info); - } - - return; - } - mPicks.push_back(pick_info); - - // delay further event processing until we receive results of pick - // only do this for async picks so that handleMouseUp won't be called - // until the pick triggered in handleMouseDown has been processed, for example - mWindow->delayInputProcessing(); + if (mPicks.size() >= 1024 || mWindow->getMinimized()) + { //something went wrong, picks are being scheduled but not processed + + if (pick_info.mPickCallback) + { + pick_info.mPickCallback(pick_info); + } + + return; + } + mPicks.push_back(pick_info); + + // delay further event processing until we receive results of pick + // only do this for async picks so that handleMouseUp won't be called + // until the pick triggered in handleMouseDown has been processed, for example + mWindow->delayInputProcessing(); } void LLViewerWindow::performPick() { - if (!mPicks.empty()) - { - std::vector::iterator pick_it; - for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it) - { - pick_it->fetchResults(); - } + if (!mPicks.empty()) + { + std::vector::iterator pick_it; + for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it) + { + pick_it->fetchResults(); + } - mLastPick = mPicks.back(); - mPicks.clear(); - } + mLastPick = mPicks.back(); + mPicks.clear(); + } } void LLViewerWindow::returnEmptyPicks() { - std::vector::iterator pick_it; - for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it) - { - mLastPick = *pick_it; - // just trigger callback with empty results - if (pick_it->mPickCallback) - { - pick_it->mPickCallback(*pick_it); - } - } - mPicks.clear(); + std::vector::iterator pick_it; + for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it) + { + mLastPick = *pick_it; + // just trigger callback with empty results + if (pick_it->mPickCallback) + { + pick_it->mPickCallback(*pick_it); + } + } + mPicks.clear(); } // Performs the GL object/land pick. LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable, BOOL pick_reflection_probe) { - BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); - if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha) - { - // build mode allows interaction with all transparent objects - // "Show Debug Alpha" means no object actually transparent - pick_transparent = TRUE; - } - - // shortcut queueing in mPicks and just update mLastPick in place - MASK key_mask = gKeyboard->currentMask(TRUE); - mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, TRUE, FALSE, NULL); - mLastPick.fetchResults(); + BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); + if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha) + { + // build mode allows interaction with all transparent objects + // "Show Debug Alpha" means no object actually transparent + pick_transparent = TRUE; + } + + // shortcut queueing in mPicks and just update mLastPick in place + MASK key_mask = gKeyboard->currentMask(TRUE); + mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, TRUE, FALSE, NULL); + mLastPick.fetchResults(); - return mLastPick; + return mLastPick; } LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, - LLVector4a* intersection) + LLVector4a* intersection) { - S32 x = mouse_x; - S32 y = mouse_y; + S32 x = mouse_x; + S32 y = mouse_y; - if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position - { - x = getCurrentMouseX(); - y = getCurrentMouseY(); - } + if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position + { + x = getCurrentMouseX(); + y = getCurrentMouseY(); + } - // world coordinates of mouse - // VECTORIZE THIS - LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); - LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); - LLVector3 mouse_world_start = mouse_point_global; - LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; + // world coordinates of mouse + // VECTORIZE THIS + LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); + LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); + LLVector3 mouse_world_start = mouse_point_global; + LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; - LLVector4a start, end; - start.load3(mouse_world_start.mV); - end.load3(mouse_world_end.mV); - - return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection); + LLVector4a start, end; + start.load3(mouse_world_start.mV); + end.load3(mouse_world_end.mV); + + return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection); } LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, - LLViewerObject *this_object, - S32 this_face, - BOOL pick_transparent, - BOOL pick_rigged, + LLViewerObject *this_object, + S32 this_face, + BOOL pick_transparent, + BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe, - S32* face_hit, + S32* face_hit, S32* gltf_node_hit, S32* gltf_primitive_hit, - LLVector4a *intersection, - LLVector2 *uv, - LLVector4a *normal, - LLVector4a *tangent, - LLVector4a* start, - LLVector4a* end) -{ - S32 x = mouse_x; - S32 y = mouse_y; - - if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position - { - x = getCurrentMouseX(); - y = getCurrentMouseY(); - } - - // HUD coordinates of mouse - LLVector3 mouse_point_hud = mousePointHUD(x, y); - LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0); - LLVector3 mouse_hud_end = mouse_point_hud + LLVector3(depth, 0, 0); - - // world coordinates of mouse - LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); - LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); - - //get near clip plane - LLVector3 n = LLViewerCamera::getInstance()->getAtAxis(); - LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear(); - - //project mouse point onto plane - LLVector3 pos; - line_plane(mouse_point_global, mouse_direction_global, p, n, pos); - mouse_point_global = pos; - - LLVector3 mouse_world_start = mouse_point_global; - LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; - - if (!LLViewerJoystick::getInstance()->getOverrideCamera()) - { //always set raycast intersection to mouse_world_end unless - //flycam is on (for DoF effect) - gDebugRaycastIntersection.load3(mouse_world_end.mV); - } - - LLVector4a mw_start; - mw_start.load3(mouse_world_start.mV); - LLVector4a mw_end; - mw_end.load3(mouse_world_end.mV); - - LLVector4a mh_start; - mh_start.load3(mouse_hud_start.mV); - LLVector4a mh_end; - mh_end.load3(mouse_hud_end.mV); - - if (start) - { - *start = mw_start; - } - - if (end) - { - *end = mw_end; - } - - LLViewerObject* found = NULL; - - if (this_object) // check only this object - { - if (this_object->isHUDAttachment()) // is a HUD object? - { - if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable, - face_hit, intersection, uv, normal, tangent)) - { - found = this_object; - } - } - else // is a world object - { + LLVector4a *intersection, + LLVector2 *uv, + LLVector4a *normal, + LLVector4a *tangent, + LLVector4a* start, + LLVector4a* end) +{ + S32 x = mouse_x; + S32 y = mouse_y; + + if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position + { + x = getCurrentMouseX(); + y = getCurrentMouseY(); + } + + // HUD coordinates of mouse + LLVector3 mouse_point_hud = mousePointHUD(x, y); + LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0); + LLVector3 mouse_hud_end = mouse_point_hud + LLVector3(depth, 0, 0); + + // world coordinates of mouse + LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); + LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); + + //get near clip plane + LLVector3 n = LLViewerCamera::getInstance()->getAtAxis(); + LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear(); + + //project mouse point onto plane + LLVector3 pos; + line_plane(mouse_point_global, mouse_direction_global, p, n, pos); + mouse_point_global = pos; + + LLVector3 mouse_world_start = mouse_point_global; + LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; + + if (!LLViewerJoystick::getInstance()->getOverrideCamera()) + { //always set raycast intersection to mouse_world_end unless + //flycam is on (for DoF effect) + gDebugRaycastIntersection.load3(mouse_world_end.mV); + } + + LLVector4a mw_start; + mw_start.load3(mouse_world_start.mV); + LLVector4a mw_end; + mw_end.load3(mouse_world_end.mV); + + LLVector4a mh_start; + mh_start.load3(mouse_hud_start.mV); + LLVector4a mh_end; + mh_end.load3(mouse_hud_end.mV); + + if (start) + { + *start = mw_start; + } + + if (end) + { + *end = mw_end; + } + + LLViewerObject* found = NULL; + + if (this_object) // check only this object + { + if (this_object->isHUDAttachment()) // is a HUD object? + { + if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable, + face_hit, intersection, uv, normal, tangent)) + { + found = this_object; + } + } + else // is a world object + { if ((pick_reflection_probe || !this_object->isReflectionProbe()) && this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged, pick_unselectable, - face_hit, intersection, uv, normal, tangent)) - { - found = this_object; - } - } - } - else // check ALL objects - { - found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, - face_hit, intersection, uv, normal, tangent); - - if (!found) // if not found in HUD, look in world: - { - found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, - face_hit, gltf_node_hit, gltf_primitive_hit, intersection, uv, normal, tangent); - if (found && !pick_transparent) - { - gDebugRaycastIntersection = *intersection; - } - } - } - - return found; + face_hit, intersection, uv, normal, tangent)) + { + found = this_object; + } + } + } + else // check ALL objects + { + found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, + face_hit, intersection, uv, normal, tangent); + + if (!found) // if not found in HUD, look in world: + { + found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, + face_hit, gltf_node_hit, gltf_primitive_hit, intersection, uv, normal, tangent); + if (found && !pick_transparent) + { + gDebugRaycastIntersection = *intersection; + } + } + } + + return found; } // Returns unit vector relative to camera // indicating direction of point on screen x,y LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const { - // find vertical field of view - F32 fov = LLViewerCamera::getInstance()->getView(); + // find vertical field of view + F32 fov = LLViewerCamera::getInstance()->getView(); - // find world view center in scaled ui coordinates - F32 center_x = getWorldViewRectScaled().getCenterX(); - F32 center_y = getWorldViewRectScaled().getCenterY(); + // find world view center in scaled ui coordinates + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); - // calculate pixel distance to screen - F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f)); + // calculate pixel distance to screen + F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f)); - // calculate click point relative to middle of screen - F32 click_x = x - center_x; - F32 click_y = y - center_y; + // calculate click point relative to middle of screen + F32 click_x = x - center_x; + F32 click_y = y - center_y; - // compute mouse vector - LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis() - - click_x * LLViewerCamera::getInstance()->getLeftAxis() - + click_y * LLViewerCamera::getInstance()->getUpAxis(); + // compute mouse vector + LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis() + - click_x * LLViewerCamera::getInstance()->getLeftAxis() + + click_y * LLViewerCamera::getInstance()->getUpAxis(); - mouse_vector.normVec(); + mouse_vector.normVec(); - return mouse_vector; + return mouse_vector; } LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const { - // find screen resolution - S32 height = getWorldViewHeightScaled(); + // find screen resolution + S32 height = getWorldViewHeightScaled(); - // find world view center - F32 center_x = getWorldViewRectScaled().getCenterX(); - F32 center_y = getWorldViewRectScaled().getCenterY(); + // find world view center + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); - // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5 - F32 hud_x = -((F32)x - center_x) / height; - F32 hud_y = ((F32)y - center_y) / height; + // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5 + F32 hud_x = -((F32)x - center_x) / height; + F32 hud_y = ((F32)y - center_y) / height; - return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom); + return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom); } // Returns unit vector relative to camera in camera space // indicating direction of point on screen x,y LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const { - // find vertical field of view - F32 fov_height = LLViewerCamera::getInstance()->getView(); - F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect(); + // find vertical field of view + F32 fov_height = LLViewerCamera::getInstance()->getView(); + F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect(); - // find screen resolution - S32 height = getWorldViewHeightScaled(); - S32 width = getWorldViewWidthScaled(); + // find screen resolution + S32 height = getWorldViewHeightScaled(); + S32 width = getWorldViewWidthScaled(); - // find world view center - F32 center_x = getWorldViewRectScaled().getCenterX(); - F32 center_y = getWorldViewRectScaled().getCenterY(); + // find world view center + F32 center_x = getWorldViewRectScaled().getCenterX(); + F32 center_y = getWorldViewRectScaled().getCenterY(); - // calculate click point relative to middle of screen - F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f; - F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height; + // calculate click point relative to middle of screen + F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f; + F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height; - // compute mouse vector - LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f); - LLQuaternion mouse_rotate; - mouse_rotate.setQuat(click_y, click_x, 0.f); + // compute mouse vector + LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f); + LLQuaternion mouse_rotate; + mouse_rotate.setQuat(click_y, click_x, 0.f); - mouse_vector = mouse_vector * mouse_rotate; - // project to z = -1 plane; - mouse_vector = mouse_vector * (-1.f / mouse_vector.mV[VZ]); + mouse_vector = mouse_vector * mouse_rotate; + // project to z = -1 plane; + mouse_vector = mouse_vector * (-1.f / mouse_vector.mV[VZ]); - return mouse_vector; + return mouse_vector; } -BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, - const LLVector3d &plane_point_global, - const LLVector3 &plane_normal_global) +BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, + const LLVector3d &plane_point_global, + const LLVector3 &plane_normal_global) { - LLVector3d mouse_direction_global_d; + LLVector3d mouse_direction_global_d; + + mouse_direction_global_d.setVec(mouseDirectionGlobal(x,y)); + LLVector3d plane_normal_global_d; + plane_normal_global_d.setVec(plane_normal_global); + F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d); + LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal(); + F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel) + / plane_mouse_dot; + if (llabs(plane_mouse_dot) < 0.00001) + { + // if mouse is parallel to plane, return closest point on line through plane origin + // that is parallel to camera plane by scaling mouse direction vector + // by distance to plane origin, modulated by deviation of mouse direction from plane origin + LLVector3d plane_origin_dir = plane_origin_camera_rel; + plane_origin_dir.normVec(); - mouse_direction_global_d.setVec(mouseDirectionGlobal(x,y)); - LLVector3d plane_normal_global_d; - plane_normal_global_d.setVec(plane_normal_global); - F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d); - LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal(); - F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel) - / plane_mouse_dot; - if (llabs(plane_mouse_dot) < 0.00001) - { - // if mouse is parallel to plane, return closest point on line through plane origin - // that is parallel to camera plane by scaling mouse direction vector - // by distance to plane origin, modulated by deviation of mouse direction from plane origin - LLVector3d plane_origin_dir = plane_origin_camera_rel; - plane_origin_dir.normVec(); - - mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d); - } + mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d); + } - point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d; + point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d; - return mouse_look_at_scale > 0.0; + return mouse_look_at_scale > 0.0; } // Returns global position BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_position_global, BOOL ignore_distance) { - LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); - F32 mouse_dir_scale; - BOOL hit_land = FALSE; - LLViewerRegion *regionp; - F32 land_z; - const F32 FIRST_PASS_STEP = 1.0f; // meters - const F32 SECOND_PASS_STEP = 0.1f; // meters - const F32 draw_distance = ignore_distance ? MAX_FAR_CLIP : gAgentCamera.mDrawDistance; - LLVector3d camera_pos_global; - - camera_pos_global = gAgentCamera.getCameraPositionGlobal(); - LLVector3d probe_point_global; - LLVector3 probe_point_region; - - // walk forwards to find the point - for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < draw_distance; mouse_dir_scale += FIRST_PASS_STEP) - { - LLVector3d mouse_direction_global_d; - mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); - probe_point_global = camera_pos_global + mouse_direction_global_d; - - regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); - - if (!regionp) - { - // ...we're outside the world somehow - continue; - } - - S32 i = (S32) (probe_point_region.mV[VX]/regionp->getLand().getMetersPerGrid()); - S32 j = (S32) (probe_point_region.mV[VY]/regionp->getLand().getMetersPerGrid()); - S32 grids_per_edge = (S32) regionp->getLand().mGridsPerEdge; - if ((i >= grids_per_edge) || (j >= grids_per_edge)) - { - //LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL; - continue; - } - - land_z = regionp->getLand().resolveHeightRegion(probe_point_region); - - //LL_INFOS() << "mousePointOnLand initial z " << land_z << LL_ENDL; - - if (probe_point_region.mV[VZ] < land_z) - { - // ...just went under land - - // cout << "under land at " << probe_point << " scale " << mouse_vec_scale << endl; - - hit_land = TRUE; - break; - } - } - - - if (hit_land) - { - // Don't go more than one step beyond where we stopped above. - // This can't just be "mouse_vec_scale" because floating point error - // will stop the loop before the last increment.... X - 1.0 + 0.1 + 0.1 + ... + 0.1 != X - F32 stop_mouse_dir_scale = mouse_dir_scale + FIRST_PASS_STEP; - - // take a step backwards, then walk forwards again to refine position - for ( mouse_dir_scale -= FIRST_PASS_STEP; mouse_dir_scale <= stop_mouse_dir_scale; mouse_dir_scale += SECOND_PASS_STEP) - { - LLVector3d mouse_direction_global_d; - mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); - probe_point_global = camera_pos_global + mouse_direction_global_d; - - regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); - - if (!regionp) - { - // ...we're outside the world somehow - continue; - } - - /* - i = (S32) (local_probe_point.mV[VX]/regionp->getLand().getMetersPerGrid()); - j = (S32) (local_probe_point.mV[VY]/regionp->getLand().getMetersPerGrid()); - if ((i >= regionp->getLand().mGridsPerEdge) || (j >= regionp->getLand().mGridsPerEdge)) - { - // LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL; - continue; - } - land_z = regionp->getLand().mSurfaceZ[ i + j * (regionp->getLand().mGridsPerEdge) ]; - */ - - land_z = regionp->getLand().resolveHeightRegion(probe_point_region); - - //LL_INFOS() << "mousePointOnLand refine z " << land_z << LL_ENDL; - - if (probe_point_region.mV[VZ] < land_z) - { - // ...just went under land again - - *land_position_global = probe_point_global; - return TRUE; - } - } - } - - return FALSE; + LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); + F32 mouse_dir_scale; + BOOL hit_land = FALSE; + LLViewerRegion *regionp; + F32 land_z; + const F32 FIRST_PASS_STEP = 1.0f; // meters + const F32 SECOND_PASS_STEP = 0.1f; // meters + const F32 draw_distance = ignore_distance ? MAX_FAR_CLIP : gAgentCamera.mDrawDistance; + LLVector3d camera_pos_global; + + camera_pos_global = gAgentCamera.getCameraPositionGlobal(); + LLVector3d probe_point_global; + LLVector3 probe_point_region; + + // walk forwards to find the point + for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < draw_distance; mouse_dir_scale += FIRST_PASS_STEP) + { + LLVector3d mouse_direction_global_d; + mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); + probe_point_global = camera_pos_global + mouse_direction_global_d; + + regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); + + if (!regionp) + { + // ...we're outside the world somehow + continue; + } + + S32 i = (S32) (probe_point_region.mV[VX]/regionp->getLand().getMetersPerGrid()); + S32 j = (S32) (probe_point_region.mV[VY]/regionp->getLand().getMetersPerGrid()); + S32 grids_per_edge = (S32) regionp->getLand().mGridsPerEdge; + if ((i >= grids_per_edge) || (j >= grids_per_edge)) + { + //LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL; + continue; + } + + land_z = regionp->getLand().resolveHeightRegion(probe_point_region); + + //LL_INFOS() << "mousePointOnLand initial z " << land_z << LL_ENDL; + + if (probe_point_region.mV[VZ] < land_z) + { + // ...just went under land + + // cout << "under land at " << probe_point << " scale " << mouse_vec_scale << endl; + + hit_land = TRUE; + break; + } + } + + + if (hit_land) + { + // Don't go more than one step beyond where we stopped above. + // This can't just be "mouse_vec_scale" because floating point error + // will stop the loop before the last increment.... X - 1.0 + 0.1 + 0.1 + ... + 0.1 != X + F32 stop_mouse_dir_scale = mouse_dir_scale + FIRST_PASS_STEP; + + // take a step backwards, then walk forwards again to refine position + for ( mouse_dir_scale -= FIRST_PASS_STEP; mouse_dir_scale <= stop_mouse_dir_scale; mouse_dir_scale += SECOND_PASS_STEP) + { + LLVector3d mouse_direction_global_d; + mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); + probe_point_global = camera_pos_global + mouse_direction_global_d; + + regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); + + if (!regionp) + { + // ...we're outside the world somehow + continue; + } + + /* + i = (S32) (local_probe_point.mV[VX]/regionp->getLand().getMetersPerGrid()); + j = (S32) (local_probe_point.mV[VY]/regionp->getLand().getMetersPerGrid()); + if ((i >= regionp->getLand().mGridsPerEdge) || (j >= regionp->getLand().mGridsPerEdge)) + { + // LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL; + continue; + } + land_z = regionp->getLand().mSurfaceZ[ i + j * (regionp->getLand().mGridsPerEdge) ]; + */ + + land_z = regionp->getLand().resolveHeightRegion(probe_point_region); + + //LL_INFOS() << "mousePointOnLand refine z " << land_z << LL_ENDL; + + if (probe_point_region.mV[VZ] < land_z) + { + // ...just went under land again + + *land_position_global = probe_point_global; + return TRUE; + } + } + } + + return FALSE; } // Saves an image to the harddrive as "SnapshotX" where X >= 1. void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb) { - if (!image) - { - LL_WARNS() << "No image to save" << LL_ENDL; - return; - } - std::string extension("." + image->getExtension()); - LLImageFormatted* formatted_image = image; - // Get a base file location if needed. - if (force_picker || !isSnapshotLocSet()) - { - std::string proposed_name(sSnapshotBaseName); - - // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in. - LLFilePicker::ESaveFilter pick_type; - - if (extension == ".j2c") - pick_type = LLFilePicker::FFSAVE_J2C; - else if (extension == ".bmp") - pick_type = LLFilePicker::FFSAVE_BMP; - else if (extension == ".jpg") - pick_type = LLFilePicker::FFSAVE_JPEG; - else if (extension == ".png") - pick_type = LLFilePicker::FFSAVE_PNG; - else if (extension == ".tga") - pick_type = LLFilePicker::FFSAVE_TGA; - else - pick_type = LLFilePicker::FFSAVE_ALL; - - LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name, - boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)); - } - else - { - saveImageLocal(formatted_image, success_cb, failure_cb); - } + if (!image) + { + LL_WARNS() << "No image to save" << LL_ENDL; + return; + } + std::string extension("." + image->getExtension()); + LLImageFormatted* formatted_image = image; + // Get a base file location if needed. + if (force_picker || !isSnapshotLocSet()) + { + std::string proposed_name(sSnapshotBaseName); + + // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in. + LLFilePicker::ESaveFilter pick_type; + + if (extension == ".j2c") + pick_type = LLFilePicker::FFSAVE_J2C; + else if (extension == ".bmp") + pick_type = LLFilePicker::FFSAVE_BMP; + else if (extension == ".jpg") + pick_type = LLFilePicker::FFSAVE_JPEG; + else if (extension == ".png") + pick_type = LLFilePicker::FFSAVE_PNG; + else if (extension == ".tga") + pick_type = LLFilePicker::FFSAVE_TGA; + else + pick_type = LLFilePicker::FFSAVE_ALL; + + LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name, + boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)); + } + else + { + saveImageLocal(formatted_image, success_cb, failure_cb); + } } void LLViewerWindow::onDirectorySelected(const std::vector& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb) { - // Copy the directory + file name - std::string filepath = filenames[0]; + // Copy the directory + file name + std::string filepath = filenames[0]; - gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true)); - gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath)); - saveImageLocal(image, success_cb, failure_cb); + gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true)); + gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath)); + saveImageLocal(image, success_cb, failure_cb); } void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb) { - failure_cb(); + failure_cb(); } void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb) { - std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir(); - if (lastSnapshotDir.empty()) - { - failure_cb(); - return; - } + std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir(); + if (lastSnapshotDir.empty()) + { + failure_cb(); + return; + } // Check if there is enough free space to save snapshot #ifdef LL_WINDOWS - boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir)); + boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir)); #else - boost::filesystem::path b_path(lastSnapshotDir); + boost::filesystem::path b_path(lastSnapshotDir); #endif - if (!boost::filesystem::is_directory(b_path)) - { - LLSD args; - args["PATH"] = lastSnapshotDir; - LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args); - resetSnapshotLoc(); - failure_cb(); - return; - } - boost::filesystem::space_info b_space = boost::filesystem::space(b_path); - if (b_space.free < image->getDataSize()) - { - LLSD args; - args["PATH"] = lastSnapshotDir; - - std::string needM_bytes_string; - LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10); - args["NEED_MEMORY"] = needM_bytes_string; - - std::string freeM_bytes_string; - LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10); - args["FREE_MEMORY"] = freeM_bytes_string; - - LLNotificationsUtil::add("SnapshotToComputerFailed", args); - - failure_cb(); - } - - // Look for an unused file name - BOOL is_snapshot_name_loc_set = isSnapshotLocSet(); - std::string filepath; - S32 i = 1; - S32 err = 0; - std::string extension("." + image->getExtension()); - do - { - filepath = sSnapshotDir; - filepath += gDirUtilp->getDirDelimiter(); - filepath += sSnapshotBaseName; - - if (is_snapshot_name_loc_set) - { - filepath += llformat("_%.3d",i); - } - - filepath += extension; - - llstat stat_info; - err = LLFile::stat( filepath, &stat_info ); - i++; - } - while( -1 != err // Search until the file is not found (i.e., stat() gives an error). - && is_snapshot_name_loc_set); // Or stop if we are rewriting. - - LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL; - if (image->save(filepath)) - { - playSnapshotAnimAndSound(); - success_cb(); - } - else - { - failure_cb(); - } + if (!boost::filesystem::is_directory(b_path)) + { + LLSD args; + args["PATH"] = lastSnapshotDir; + LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args); + resetSnapshotLoc(); + failure_cb(); + return; + } + boost::filesystem::space_info b_space = boost::filesystem::space(b_path); + if (b_space.free < image->getDataSize()) + { + LLSD args; + args["PATH"] = lastSnapshotDir; + + std::string needM_bytes_string; + LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10); + args["NEED_MEMORY"] = needM_bytes_string; + + std::string freeM_bytes_string; + LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10); + args["FREE_MEMORY"] = freeM_bytes_string; + + LLNotificationsUtil::add("SnapshotToComputerFailed", args); + + failure_cb(); + } + + // Look for an unused file name + BOOL is_snapshot_name_loc_set = isSnapshotLocSet(); + std::string filepath; + S32 i = 1; + S32 err = 0; + std::string extension("." + image->getExtension()); + do + { + filepath = sSnapshotDir; + filepath += gDirUtilp->getDirDelimiter(); + filepath += sSnapshotBaseName; + + if (is_snapshot_name_loc_set) + { + filepath += llformat("_%.3d",i); + } + + filepath += extension; + + llstat stat_info; + err = LLFile::stat( filepath, &stat_info ); + i++; + } + while( -1 != err // Search until the file is not found (i.e., stat() gives an error). + && is_snapshot_name_loc_set); // Or stop if we are rewriting. + + LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL; + if (image->save(filepath)) + { + playSnapshotAnimAndSound(); + success_cb(); + } + else + { + failure_cb(); + } } void LLViewerWindow::resetSnapshotLoc() { - gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); + gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); } // static void LLViewerWindow::movieSize(S32 new_width, S32 new_height) { - LLCoordWindow size; - LLCoordWindow new_size(new_width, new_height); - gViewerWindow->getWindow()->getSize(&size); - if ( size != new_size ) - { - gViewerWindow->getWindow()->setSize(new_size); - } + LLCoordWindow size; + LLCoordWindow new_size(new_width, new_height); + gViewerWindow->getWindow()->getSize(&size); + if ( size != new_size ) + { + gViewerWindow->getWindow()->setSize(new_size); + } } BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format) @@ -4867,347 +4867,347 @@ BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, void LLViewerWindow::playSnapshotAnimAndSound() { - if (gSavedSettings.getBOOL("QuietSnapshotsToDisk")) - { - return; - } - gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START); - send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f); + if (gSavedSettings.getBOOL("QuietSnapshotsToDisk")) + { + return; + } + gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START); + send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f); +} + +BOOL LLViewerWindow::isSnapshotLocSet() const +{ + std::string snapshot_dir = sSnapshotDir; + return !snapshot_dir.empty(); +} + +void LLViewerWindow::resetSnapshotLoc() const +{ + gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); +} + +BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type) +{ + return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type); } -BOOL LLViewerWindow::isSnapshotLocSet() const -{ - std::string snapshot_dir = sSnapshotDir; - return !snapshot_dir.empty(); -} +// Saves the image from the screen to a raw image +// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy +// the results over to the final raw image. +BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, + BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size) +{ + if (!raw) + { + return FALSE; + } + //check if there is enough memory for the snapshot image + if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K + { + if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) + { + LL_WARNS() << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << LL_ENDL ; + return FALSE ; //there is no enough memory for taking this snapshot. + } + } + + // PRE SNAPSHOT + gSnapshotNoPost = no_post; + gDisplaySwapBuffers = FALSE; + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT); + setCursor(UI_CURSOR_WAIT); + + // Hide all the UI widgets first and draw a frame + BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; + + if ( prev_draw_ui != show_ui) + { + LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + + BOOL hide_hud = !show_hud && LLPipeline::sShowHUDAttachments; + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = FALSE; + } + + // if not showing ui, use full window to render world view + updateWorldViewRect(!show_ui); + + // Copy screen to a buffer + // crop sides or top and bottom, if taking a snapshot of different aspect ratio + // from window + LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); + + S32 snapshot_width = window_rect.getWidth(); + S32 snapshot_height = window_rect.getHeight(); + // SNAPSHOT + S32 window_width = snapshot_width; + S32 window_height = snapshot_height; + + // Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested + if (show_ui) + { + // If the user wants the UI, limit the output size to the available screen size + image_width = llmin(image_width, window_width); + image_height = llmin(image_height, window_height); + } + + S32 original_width = 0; + S32 original_height = 0; + bool reset_deferred = false; + + LLRenderTarget scratch_space; + + F32 scale_factor = 1.0f ; + if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) + { + if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && + (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) + { + U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA; + if (scratch_space.allocate(image_width, image_height, color_fmt, true)) + { + original_width = gPipeline.mRT->deferredScreen.getWidth(); + original_height = gPipeline.mRT->deferredScreen.getHeight(); + + if (gPipeline.allocateScreenBuffer(image_width, image_height)) + { + window_width = image_width; + window_height = image_height; + snapshot_width = image_width; + snapshot_height = image_height; + reset_deferred = true; + mWorldViewRectRaw.set(0, image_height, image_width, 0); + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + scratch_space.bindTarget(); + } + else + { + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + } + } + } + + if (!reset_deferred) + { + // if image cropping or need to enlarge the scene, compute a scale_factor + F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; + snapshot_width = (S32)(ratio * image_width) ; + snapshot_height = (S32)(ratio * image_height) ; + scale_factor = llmax(1.0f, 1.0f / ratio) ; + } + } + + if (show_ui && scale_factor > 1.f) + { + // Note: we should never get there... + LL_WARNS() << "over scaling UI not supported." << LL_ENDL; + } + + S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); + S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); + + S32 image_buffer_x = llfloor(snapshot_width * scale_factor) ; + S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ; + + if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow + { + scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; + image_buffer_x = llfloor(snapshot_width * scale_factor) ; + image_buffer_y = llfloor(snapshot_height * scale_factor) ; + } + if ((image_buffer_x > 0) && (image_buffer_y > 0)) + { + raw->resize(image_buffer_x, image_buffer_y, 3); + } + else + { + return FALSE ; + } + if (raw->isBufferInvalid()) + { + return FALSE ; + } + + BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher + if (high_res && show_ui) + { + // Note: we should never get there... + LL_WARNS() << "High res UI snapshot not supported. " << LL_ENDL; + /*send_agent_pause(); + //rescale fonts + initFonts(scale_factor); + LLHUDObject::reshapeAll();*/ + } + + S32 output_buffer_offset_y = 0; + + F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear()); + F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear()); + + // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen. + // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y + for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y) + { + S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; + // handle fractional columns + U32 read_height = llmax(0, (window_height - subimage_y_offset) - + llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight()))); + + S32 output_buffer_offset_x = 0; + for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x) + { + gDisplaySwapBuffers = FALSE; + gDepthDirty = TRUE; + + S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); + // handle fractional rows + U32 read_width = llmax(0, (window_width - subimage_x_offset) - + llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth()))); + + // Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases) + if (read_width && read_height) + { + const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); + display(do_rebuild, scale_factor, subfield, TRUE); + + if (!LLPipeline::sRenderDeferred) + { + // Required for showing the GUI in snapshots and performing bloom composite overlay + // Call even if show_ui is FALSE + render_ui(scale_factor, subfield); + swap(); + } + + for (U32 out_y = 0; out_y < read_height ; out_y++) + { + S32 output_buffer_offset = ( + (out_y * (raw->getWidth())) // ...plus iterated y... + + (window_width * subimage_x) // ...plus subimage start in x... + + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... + - output_buffer_offset_x // ...minus buffer padding x... + - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y... + ) * raw->getComponents(); + + // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) + if (out_y % 100 == 0) + { + LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); + } + // disable use of glReadPixels when doing nVidia nSight graphics debugging + if (!LLRender::sNsightDebugSupport) + { + if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR) + { + glReadPixels( + subimage_x_offset, out_y + subimage_y_offset, + read_width, 1, + GL_RGB, GL_UNSIGNED_BYTE, + raw->getData() + output_buffer_offset + ); + } + else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH + { + LLPointer depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values + glReadPixels( + subimage_x_offset, out_y + subimage_y_offset, + read_width, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, + depth_line_buffer->getData()// current output pixel is beginning of buffer... + ); + + for (S32 i = 0; i < (S32)read_width; i++) + { + F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); + + F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); + U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); + // write converted scanline out to result image + for (S32 j = 0; j < raw->getComponents(); j++) + { + *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; + } + } + } + } + } + } + output_buffer_offset_x += subimage_x_offset; + stop_glerror(); + } + output_buffer_offset_y += subimage_y_offset; + } + + gDisplaySwapBuffers = FALSE; + gSnapshotNoPost = FALSE; + gDepthDirty = TRUE; + + // POST SNAPSHOT + if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = TRUE; + } + + /*if (high_res) + { + initFonts(1.f); + LLHUDObject::reshapeAll(); + }*/ + + // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) + // Note: this formula depends on the number of components being 3. Not obvious, but it's correct. + image_width += (image_width * 3) % 4; + + BOOL ret = TRUE ; + // Resize image + if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) + { + ret = raw->scale( image_width, image_height ); + } + else if(image_width != image_buffer_x || image_height != image_buffer_y) + { + ret = raw->scale( image_width, image_height, FALSE ); + } + -void LLViewerWindow::resetSnapshotLoc() const -{ - gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); -} + setCursor(UI_CURSOR_ARROW); -BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type) -{ - return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type); -} + if (do_rebuild) + { + // If we had to do a rebuild, that means that the lists of drawables to be rendered + // was empty before we started. + // Need to reset these, otherwise we call state sort on it again when render gets called the next time + // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of + // objects on them. + gPipeline.resetDrawOrders(); + } -// Saves the image from the screen to a raw image -// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy -// the results over to the final raw image. -BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, - BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size) -{ - if (!raw) - { - return FALSE; - } - //check if there is enough memory for the snapshot image - if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K - { - if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) - { - LL_WARNS() << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << LL_ENDL ; - return FALSE ; //there is no enough memory for taking this snapshot. - } - } - - // PRE SNAPSHOT - gSnapshotNoPost = no_post; - gDisplaySwapBuffers = FALSE; - - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT); - setCursor(UI_CURSOR_WAIT); + if (reset_deferred) + { + mWorldViewRectRaw = window_rect; + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + scratch_space.flush(); + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); - // Hide all the UI widgets first and draw a frame - BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; + } - if ( prev_draw_ui != show_ui) - { - LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); - } + if (high_res) + { + send_agent_resume(); + } - BOOL hide_hud = !show_hud && LLPipeline::sShowHUDAttachments; - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = FALSE; - } - - // if not showing ui, use full window to render world view - updateWorldViewRect(!show_ui); - - // Copy screen to a buffer - // crop sides or top and bottom, if taking a snapshot of different aspect ratio - // from window - LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); - - S32 snapshot_width = window_rect.getWidth(); - S32 snapshot_height = window_rect.getHeight(); - // SNAPSHOT - S32 window_width = snapshot_width; - S32 window_height = snapshot_height; - - // Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested - if (show_ui) - { - // If the user wants the UI, limit the output size to the available screen size - image_width = llmin(image_width, window_width); - image_height = llmin(image_height, window_height); - } - - S32 original_width = 0; - S32 original_height = 0; - bool reset_deferred = false; - - LLRenderTarget scratch_space; - - F32 scale_factor = 1.0f ; - if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) - { - if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && - (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) - { - U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA; - if (scratch_space.allocate(image_width, image_height, color_fmt, true)) - { - original_width = gPipeline.mRT->deferredScreen.getWidth(); - original_height = gPipeline.mRT->deferredScreen.getHeight(); - - if (gPipeline.allocateScreenBuffer(image_width, image_height)) - { - window_width = image_width; - window_height = image_height; - snapshot_width = image_width; - snapshot_height = image_height; - reset_deferred = true; - mWorldViewRectRaw.set(0, image_height, image_width, 0); - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); - scratch_space.bindTarget(); - } - else - { - scratch_space.release(); - gPipeline.allocateScreenBuffer(original_width, original_height); - } - } - } - - if (!reset_deferred) - { - // if image cropping or need to enlarge the scene, compute a scale_factor - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; - } - } - - if (show_ui && scale_factor > 1.f) - { - // Note: we should never get there... - LL_WARNS() << "over scaling UI not supported." << LL_ENDL; - } - - S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); - S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); - - S32 image_buffer_x = llfloor(snapshot_width * scale_factor) ; - S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ; - - if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow - { - scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; - image_buffer_x = llfloor(snapshot_width * scale_factor) ; - image_buffer_y = llfloor(snapshot_height * scale_factor) ; - } - if ((image_buffer_x > 0) && (image_buffer_y > 0)) - { - raw->resize(image_buffer_x, image_buffer_y, 3); - } - else - { - return FALSE ; - } - if (raw->isBufferInvalid()) - { - return FALSE ; - } - - BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher - if (high_res && show_ui) - { - // Note: we should never get there... - LL_WARNS() << "High res UI snapshot not supported. " << LL_ENDL; - /*send_agent_pause(); - //rescale fonts - initFonts(scale_factor); - LLHUDObject::reshapeAll();*/ - } - - S32 output_buffer_offset_y = 0; - - F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear()); - F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear()); - - // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen. - // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y - for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y) - { - S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; - // handle fractional columns - U32 read_height = llmax(0, (window_height - subimage_y_offset) - - llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight()))); - - S32 output_buffer_offset_x = 0; - for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x) - { - gDisplaySwapBuffers = FALSE; - gDepthDirty = TRUE; - - S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); - // handle fractional rows - U32 read_width = llmax(0, (window_width - subimage_x_offset) - - llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth()))); - - // Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases) - if (read_width && read_height) - { - const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - display(do_rebuild, scale_factor, subfield, TRUE); - - if (!LLPipeline::sRenderDeferred) - { - // Required for showing the GUI in snapshots and performing bloom composite overlay - // Call even if show_ui is FALSE - render_ui(scale_factor, subfield); - swap(); - } - - for (U32 out_y = 0; out_y < read_height ; out_y++) - { - S32 output_buffer_offset = ( - (out_y * (raw->getWidth())) // ...plus iterated y... - + (window_width * subimage_x) // ...plus subimage start in x... - + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... - - output_buffer_offset_x // ...minus buffer padding x... - - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y... - ) * raw->getComponents(); - - // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) - if (out_y % 100 == 0) - { - LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); - } - // disable use of glReadPixels when doing nVidia nSight graphics debugging - if (!LLRender::sNsightDebugSupport) - { - if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR) - { - glReadPixels( - subimage_x_offset, out_y + subimage_y_offset, - read_width, 1, - GL_RGB, GL_UNSIGNED_BYTE, - raw->getData() + output_buffer_offset - ); - } - else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH - { - LLPointer depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values - glReadPixels( - subimage_x_offset, out_y + subimage_y_offset, - read_width, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, - depth_line_buffer->getData()// current output pixel is beginning of buffer... - ); - - for (S32 i = 0; i < (S32)read_width; i++) - { - F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); - - F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); - U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); - // write converted scanline out to result image - for (S32 j = 0; j < raw->getComponents(); j++) - { - *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; - } - } - } - } - } - } - output_buffer_offset_x += subimage_x_offset; - stop_glerror(); - } - output_buffer_offset_y += subimage_y_offset; - } - - gDisplaySwapBuffers = FALSE; - gSnapshotNoPost = FALSE; - gDepthDirty = TRUE; - - // POST SNAPSHOT - if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); - } - - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = TRUE; - } - - /*if (high_res) - { - initFonts(1.f); - LLHUDObject::reshapeAll(); - }*/ - - // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) - // Note: this formula depends on the number of components being 3. Not obvious, but it's correct. - image_width += (image_width * 3) % 4; - - BOOL ret = TRUE ; - // Resize image - if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) - { - ret = raw->scale( image_width, image_height ); - } - else if(image_width != image_buffer_x || image_height != image_buffer_y) - { - ret = raw->scale( image_width, image_height, FALSE ); - } - - - setCursor(UI_CURSOR_ARROW); - - if (do_rebuild) - { - // If we had to do a rebuild, that means that the lists of drawables to be rendered - // was empty before we started. - // Need to reset these, otherwise we call state sort on it again when render gets called the next time - // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of - // objects on them. - gPipeline.resetDrawOrders(); - } - - if (reset_deferred) - { - mWorldViewRectRaw = window_rect; - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); - scratch_space.flush(); - scratch_space.release(); - gPipeline.allocateScreenBuffer(original_width, original_height); - - } - - if (high_res) - { - send_agent_resume(); - } - - return ret; + return ret; } BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes) @@ -5225,10 +5225,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ } BOOL hide_hud = LLPipeline::sShowHUDAttachments; - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = FALSE; - } + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = FALSE; + } LLRect window_rect = getWorldViewRectRaw(); @@ -5253,8 +5253,8 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ } // we render the scene more than once since this helps - // greatly with the objects not being drawn in the - // snapshot when they are drawn in the scene. This is + // greatly with the objects not being drawn in the + // snapshot when they are drawn in the scene. This is // evident when you set this value via the debug setting // called 360CaptureNumRenderPasses to 1. The theory is // that the missing objects are caused by the sUseOcclusion @@ -5299,10 +5299,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ } } - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = TRUE; - } + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = TRUE; + } setCursor(UI_CURSOR_ARROW); @@ -5324,7 +5324,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea LL_PROFILE_GPU_ZONE("cubeSnapshot"); llassert(LLPipeline::sRenderDeferred); llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress - + U32 res = gPipeline.mRT->deferredScreen.getWidth(); //llassert(res <= gPipeline.mRT->deferredScreen.getWidth()); @@ -5336,7 +5336,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea // set new parameters specific to the 360 requirements LLPipeline::sUseOcclusion = 0; LLViewerCamera* camera = LLViewerCamera::getInstance(); - + LLViewerCamera saved_camera = LLViewerCamera::instance(); glh::matrix4f saved_proj = get_current_projection(); glh::matrix4f saved_mod = get_current_modelview(); @@ -5348,16 +5348,16 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea camera->setOrigin(origin); camera->setNear(near_clip); - LLPlane previousClipPlane; + LLPlane previousClipPlane; - if (useCustomClipPlane) - { + if (useCustomClipPlane) + { previousClipPlane = camera->getUserClipPlane(); camera->setUserClipPlane(clipPlane); - } + } glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT); - + U32 dynamic_render_types[] = { LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, @@ -5366,7 +5366,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32); bool prev_dynamic_render_type[dynamic_render_type_count]; - + if (!dynamic_render) { for (int i = 0; i < dynamic_render_type_count; ++i) @@ -5384,12 +5384,12 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea { LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } - + BOOL hide_hud = LLPipeline::sShowHUDAttachments; - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = FALSE; - } + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = FALSE; + } LLRect window_rect = getWorldViewRectRaw(); mWorldViewRectRaw.set(0, res, res, 0); @@ -5455,19 +5455,19 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea } } - if (hide_hud) - { - LLPipeline::sShowHUDAttachments = TRUE; - } + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = TRUE; + } gPipeline.resetDrawOrders(); mWorldViewRectRaw = window_rect; - if (useCustomClipPlane) - { + if (useCustomClipPlane) + { camera->setUserClipPlane(previousClipPlane); - } - + } + // restore original view/camera/avatar settings settings *camera = saved_camera; set_current_modelview(saved_mod); @@ -5481,138 +5481,138 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea void LLViewerWindow::destroyWindow() { - if (mWindow) - { - LLWindowManager::destroyWindow(mWindow); - } - mWindow = NULL; + if (mWindow) + { + LLWindowManager::destroyWindow(mWindow); + } + mWindow = NULL; } void LLViewerWindow::drawMouselookInstructions() { - // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) - const std::string instructions = LLTrans::getString("LeaveMouselook"); - const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD)); - - //to be on top of Bottom bar when it is opened - const S32 INSTRUCTIONS_PAD = 50; + // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) + const std::string instructions = LLTrans::getString("LeaveMouselook"); + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD)); - font->renderUTF8( - instructions, 0, - getWorldViewRectScaled().getCenterX(), - getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD, - LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ), - LLFontGL::HCENTER, LLFontGL::TOP, - LLFontGL::NORMAL,LLFontGL::DROP_SHADOW); + //to be on top of Bottom bar when it is opened + const S32 INSTRUCTIONS_PAD = 50; + + font->renderUTF8( + instructions, 0, + getWorldViewRectScaled().getCenterX(), + getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD, + LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ), + LLFontGL::HCENTER, LLFontGL::TOP, + LLFontGL::NORMAL,LLFontGL::DROP_SHADOW); } void* LLViewerWindow::getPlatformWindow() const { - return mWindow->getPlatformWindow(); + return mWindow->getPlatformWindow(); } -void* LLViewerWindow::getMediaWindow() const +void* LLViewerWindow::getMediaWindow() const { - return mWindow->getMediaWindow(); + return mWindow->getMediaWindow(); } -void LLViewerWindow::focusClient() const +void LLViewerWindow::focusClient() const { - return mWindow->focusClient(); + return mWindow->focusClient(); } -LLRootView* LLViewerWindow::getRootView() const +LLRootView* LLViewerWindow::getRootView() const { - return mRootView; + return mRootView; } LLRect LLViewerWindow::getWorldViewRectScaled() const { - return mWorldViewRectScaled; + return mWorldViewRectScaled; } S32 LLViewerWindow::getWorldViewHeightScaled() const { - return mWorldViewRectScaled.getHeight(); + return mWorldViewRectScaled.getHeight(); } S32 LLViewerWindow::getWorldViewWidthScaled() const { - return mWorldViewRectScaled.getWidth(); + return mWorldViewRectScaled.getWidth(); } S32 LLViewerWindow::getWorldViewHeightRaw() const { - return mWorldViewRectRaw.getHeight(); + return mWorldViewRectRaw.getHeight(); } S32 LLViewerWindow::getWorldViewWidthRaw() const { - return mWorldViewRectRaw.getWidth(); + return mWorldViewRectRaw.getWidth(); } -S32 LLViewerWindow::getWindowHeightScaled() const -{ - return mWindowRectScaled.getHeight(); +S32 LLViewerWindow::getWindowHeightScaled() const +{ + return mWindowRectScaled.getHeight(); } -S32 LLViewerWindow::getWindowWidthScaled() const -{ - return mWindowRectScaled.getWidth(); +S32 LLViewerWindow::getWindowWidthScaled() const +{ + return mWindowRectScaled.getWidth(); } -S32 LLViewerWindow::getWindowHeightRaw() const -{ - return mWindowRectRaw.getHeight(); +S32 LLViewerWindow::getWindowHeightRaw() const +{ + return mWindowRectRaw.getHeight(); } -S32 LLViewerWindow::getWindowWidthRaw() const -{ - return mWindowRectRaw.getWidth(); +S32 LLViewerWindow::getWindowWidthRaw() const +{ + return mWindowRectRaw.getWidth(); } void LLViewerWindow::setup2DRender() { - // setup ortho camera - gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight()); - setup2DViewport(); + // setup ortho camera + gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight()); + setup2DViewport(); } void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset) { - gGLViewport[0] = mWindowRectRaw.mLeft + x_offset; - gGLViewport[1] = mWindowRectRaw.mBottom + y_offset; - gGLViewport[2] = mWindowRectRaw.getWidth(); - gGLViewport[3] = mWindowRectRaw.getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + gGLViewport[0] = mWindowRectRaw.mLeft + x_offset; + gGLViewport[1] = mWindowRectRaw.mBottom + y_offset; + gGLViewport[2] = mWindowRectRaw.getWidth(); + gGLViewport[3] = mWindowRectRaw.getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } void LLViewerWindow::setup3DRender() { - // setup perspective camera - LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f); - setup3DViewport(); + // setup perspective camera + LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f); + setup3DViewport(); } void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI - gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset; - gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset; - gGLViewport[2] = mWorldViewRectRaw.getWidth(); - gGLViewport[3] = mWorldViewRectRaw.getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset; + gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset; + gGLViewport[2] = mWorldViewRectRaw.getWidth(); + gGLViewport[3] = mWorldViewRectRaw.getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } void LLViewerWindow::revealIntroPanel() { - if (mProgressView) - { - mProgressView->revealIntroPanel(); - } + if (mProgressView) + { + mProgressView->revealIntroPanel(); + } } void LLViewerWindow::initTextures(S32 location_id) @@ -5625,417 +5625,417 @@ void LLViewerWindow::initTextures(S32 location_id) void LLViewerWindow::setShowProgress(const BOOL show) { - if (mProgressView) - { - mProgressView->setVisible(show); - } + if (mProgressView) + { + mProgressView->setVisible(show); + } } void LLViewerWindow::setStartupComplete() { - if (mProgressView) - { - mProgressView->setStartupComplete(); - } + if (mProgressView) + { + mProgressView->setStartupComplete(); + } } BOOL LLViewerWindow::getShowProgress() const { - return (mProgressView && mProgressView->getVisible()); + return (mProgressView && mProgressView->getVisible()); } void LLViewerWindow::setProgressString(const std::string& string) { - if (mProgressView) - { - mProgressView->setText(string); - } + if (mProgressView) + { + mProgressView->setText(string); + } } void LLViewerWindow::setProgressMessage(const std::string& msg) { - if(mProgressView) - { - mProgressView->setMessage(msg); - } + if(mProgressView) + { + mProgressView->setMessage(msg); + } } void LLViewerWindow::setProgressPercent(const F32 percent) { - if (mProgressView) - { - mProgressView->setPercent(percent); - } + if (mProgressView) + { + mProgressView->setPercent(percent); + } } void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string& label ) { - if (mProgressView) - { - mProgressView->setCancelButtonVisible( b, label ); - } + if (mProgressView) + { + mProgressView->setCancelButtonVisible( b, label ); + } } LLProgressView *LLViewerWindow::getProgressView() const { - return mProgressView; + return mProgressView; } void LLViewerWindow::dumpState() { - LL_INFOS() << "LLViewerWindow Active " << S32(mActive) << LL_ENDL; - LL_INFOS() << "mWindow visible " << S32(mWindow->getVisible()) - << " minimized " << S32(mWindow->getMinimized()) - << LL_ENDL; + LL_INFOS() << "LLViewerWindow Active " << S32(mActive) << LL_ENDL; + LL_INFOS() << "mWindow visible " << S32(mWindow->getVisible()) + << " minimized " << S32(mWindow->getMinimized()) + << LL_ENDL; } void LLViewerWindow::stopGL(BOOL save_state) { - //Note: --bao - //if not necessary, do not change the order of the function calls in this function. - //if change something, make sure it will not break anything. - //especially be careful to put anything behind gTextureList.destroyGL(save_state); - if (!gGLManager.mIsDisabled) - { - LL_INFOS() << "Shutting down GL..." << LL_ENDL; - - // Pause texture decode threads (will get unpaused during main loop) - LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getTextureFetch()->pause(); - - gSky.destroyGL(); - stop_glerror(); - - LLManipTranslate::destroyGL() ; - stop_glerror(); - - gBumpImageList.destroyGL(); - stop_glerror(); - - LLFontGL::destroyAllGL(); - stop_glerror(); - - LLVOAvatar::destroyGL(); - stop_glerror(); - - LLVOPartGroup::destroyGL(); - - LLViewerDynamicTexture::destroyGL(); - stop_glerror(); - - if (gPipeline.isInit()) - { - gPipeline.destroyGL(); - } - - gBox.cleanupGL(); - - if(gPostProcess) - { - gPostProcess->invalidate(); - } - - gTextureList.destroyGL(save_state); - stop_glerror(); - - gGLManager.mIsDisabled = TRUE; - stop_glerror(); - - //unload shader's - while (LLGLSLShader::sInstances.size()) - { - LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); - shader->unload(); - } - } + //Note: --bao + //if not necessary, do not change the order of the function calls in this function. + //if change something, make sure it will not break anything. + //especially be careful to put anything behind gTextureList.destroyGL(save_state); + if (!gGLManager.mIsDisabled) + { + LL_INFOS() << "Shutting down GL..." << LL_ENDL; + + // Pause texture decode threads (will get unpaused during main loop) + LLAppViewer::getTextureCache()->pause(); + LLAppViewer::getTextureFetch()->pause(); + + gSky.destroyGL(); + stop_glerror(); + + LLManipTranslate::destroyGL() ; + stop_glerror(); + + gBumpImageList.destroyGL(); + stop_glerror(); + + LLFontGL::destroyAllGL(); + stop_glerror(); + + LLVOAvatar::destroyGL(); + stop_glerror(); + + LLVOPartGroup::destroyGL(); + + LLViewerDynamicTexture::destroyGL(); + stop_glerror(); + + if (gPipeline.isInit()) + { + gPipeline.destroyGL(); + } + + gBox.cleanupGL(); + + if(gPostProcess) + { + gPostProcess->invalidate(); + } + + gTextureList.destroyGL(save_state); + stop_glerror(); + + gGLManager.mIsDisabled = TRUE; + stop_glerror(); + + //unload shader's + while (LLGLSLShader::sInstances.size()) + { + LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); + shader->unload(); + } + } } void LLViewerWindow::restoreGL(const std::string& progress_message) { - //Note: --bao - //if not necessary, do not change the order of the function calls in this function. - //if change something, make sure it will not break anything. - //especially, be careful to put something before gTextureList.restoreGL(); - if (gGLManager.mIsDisabled) - { - LL_INFOS() << "Restoring GL..." << LL_ENDL; - gGLManager.mIsDisabled = FALSE; - - initGLDefaults(); - LLGLState::restoreGL(); - - gTextureList.restoreGL(); - - // for future support of non-square pixels, and fonts that are properly stretched - //LLFontGL::destroyDefaultFonts(); - initFonts(); - - gSky.restoreGL(); - gPipeline.restoreGL(); - LLManipTranslate::restoreGL(); - - gBumpImageList.restoreGL(); - LLViewerDynamicTexture::restoreGL(); - LLVOAvatar::restoreGL(); - LLVOPartGroup::restoreGL(); - - gResizeScreenTexture = TRUE; - gWindowResized = TRUE; - - if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) - { - LLVisualParamHint::requestHintUpdates(); - } - - if (!progress_message.empty()) - { - gRestoreGLTimer.reset(); - gRestoreGL = TRUE; - setShowProgress(TRUE); - setProgressString(progress_message); - } - LL_INFOS() << "...Restoring GL done" << LL_ENDL; - if(!LLAppViewer::instance()->restoreErrorTrap()) - { - LL_WARNS() << " Someone took over my signal/exception handler (post restoreGL)!" << LL_ENDL; - } - - } + //Note: --bao + //if not necessary, do not change the order of the function calls in this function. + //if change something, make sure it will not break anything. + //especially, be careful to put something before gTextureList.restoreGL(); + if (gGLManager.mIsDisabled) + { + LL_INFOS() << "Restoring GL..." << LL_ENDL; + gGLManager.mIsDisabled = FALSE; + + initGLDefaults(); + LLGLState::restoreGL(); + + gTextureList.restoreGL(); + + // for future support of non-square pixels, and fonts that are properly stretched + //LLFontGL::destroyDefaultFonts(); + initFonts(); + + gSky.restoreGL(); + gPipeline.restoreGL(); + LLManipTranslate::restoreGL(); + + gBumpImageList.restoreGL(); + LLViewerDynamicTexture::restoreGL(); + LLVOAvatar::restoreGL(); + LLVOPartGroup::restoreGL(); + + gResizeScreenTexture = TRUE; + gWindowResized = TRUE; + + if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) + { + LLVisualParamHint::requestHintUpdates(); + } + + if (!progress_message.empty()) + { + gRestoreGLTimer.reset(); + gRestoreGL = TRUE; + setShowProgress(TRUE); + setProgressString(progress_message); + } + LL_INFOS() << "...Restoring GL done" << LL_ENDL; + if(!LLAppViewer::instance()->restoreErrorTrap()) + { + LL_WARNS() << " Someone took over my signal/exception handler (post restoreGL)!" << LL_ENDL; + } + + } } void LLViewerWindow::initFonts(F32 zoom_factor) { - LLFontGL::destroyAllGL(); - // Initialize with possibly different zoom factor + LLFontGL::destroyAllGL(); + // Initialize with possibly different zoom factor - LLFontManager::initClass(); + LLFontManager::initClass(); - LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), - mDisplayScale.mV[VX] * zoom_factor, - mDisplayScale.mV[VY] * zoom_factor, - gDirUtilp->getAppRODataDir()); + LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), + mDisplayScale.mV[VX] * zoom_factor, + mDisplayScale.mV[VY] * zoom_factor, + gDirUtilp->getAppRODataDir()); } void LLViewerWindow::requestResolutionUpdate() { - mResDirty = true; + mResDirty = true; } static LLTrace::BlockTimerStatHandle FTM_WINDOW_CHECK_SETTINGS("Window Settings"); void LLViewerWindow::checkSettings() { - LL_RECORD_BLOCK_TIME(FTM_WINDOW_CHECK_SETTINGS); - if (mStatesDirty) - { - gGL.refreshState(); - LLViewerShaderMgr::instance()->setShaders(); - mStatesDirty = false; - } - - // We want to update the resolution AFTER the states getting refreshed not before. - if (mResDirty) - { - reshape(getWindowWidthRaw(), getWindowHeightRaw()); - mResDirty = false; - } + LL_RECORD_BLOCK_TIME(FTM_WINDOW_CHECK_SETTINGS); + if (mStatesDirty) + { + gGL.refreshState(); + LLViewerShaderMgr::instance()->setShaders(); + mStatesDirty = false; + } + + // We want to update the resolution AFTER the states getting refreshed not before. + if (mResDirty) + { + reshape(getWindowWidthRaw(), getWindowHeightRaw()); + mResDirty = false; + } } void LLViewerWindow::restartDisplay(BOOL show_progress_bar) { - LL_INFOS() << "Restaring GL" << LL_ENDL; - stopGL(); - if (show_progress_bar) - { - restoreGL(LLTrans::getString("ProgressChangingResolution")); - } - else - { - restoreGL(); - } + LL_INFOS() << "Restaring GL" << LL_ENDL; + stopGL(); + if (show_progress_bar) + { + restoreGL(LLTrans::getString("ProgressChangingResolution")); + } + else + { + restoreGL(); + } } BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar) { - //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); + //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); - //gResizeScreenTexture = TRUE; + //gResizeScreenTexture = TRUE; - //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); - //U32 old_fsaa = mWindow->getFSAASamples(); + //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); + //U32 old_fsaa = mWindow->getFSAASamples(); - // if not maximized, use the request size - if (!mWindow->getMaximized()) - { - mWindow->setSize(size); - } + // if not maximized, use the request size + if (!mWindow->getMaximized()) + { + mWindow->setSize(size); + } - //if (fsaa == old_fsaa) - { - return TRUE; - } + //if (fsaa == old_fsaa) + { + return TRUE; + } /* - // Close floaters that don't handle settings change - LLFloaterReg::hideInstance("snapshot"); - - BOOL result_first_try = FALSE; - BOOL result_second_try = FALSE; - - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); - send_agent_pause(); - LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL; - stopGL(); - mIgnoreActivate = TRUE; - LLCoordScreen old_size; - LLCoordScreen old_pos; - mWindow->getSize(&old_size); - - //mWindow->setFSAASamples(fsaa); - - result_first_try = mWindow->switchContext(false, size, disable_vsync); - if (!result_first_try) - { - // try to switch back - //mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(false, old_size, disable_vsync); - - if (!result_second_try) - { - // we are stuck...try once again with a minimal resolution? - send_agent_resume(); - mIgnoreActivate = FALSE; - return FALSE; - } - } - send_agent_resume(); - - LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL; - if (show_progress_bar) - { - restoreGL(LLTrans::getString("ProgressChangingResolution")); - } - else - { - restoreGL(); - } - - if (!result_first_try) - { - LLSD args; - args["RESX"] = llformat("%d",size.mX); - args["RESY"] = llformat("%d",size.mY); - LLNotificationsUtil::add("ResolutionSwitchFail", args); - size = old_size; // for reshape below - } - - BOOL success = result_first_try || result_second_try; - - if (success) - { - // maximize window if was maximized, else reposition - if (was_maximized) - { - mWindow->maximize(); - } - else - { - S32 windowX = gSavedSettings.getS32("WindowX"); - S32 windowY = gSavedSettings.getS32("WindowY"); - - mWindow->setPosition(LLCoordScreen ( windowX, windowY ) ); - } - } - - mIgnoreActivate = FALSE; - gFocusMgr.setKeyboardFocus(keyboard_focus); - - return success; - - */ -} - -F32 LLViewerWindow::getWorldViewAspectRatio() const -{ - F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight(); - return world_aspect; + // Close floaters that don't handle settings change + LLFloaterReg::hideInstance("snapshot"); + + BOOL result_first_try = FALSE; + BOOL result_second_try = FALSE; + + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + send_agent_pause(); + LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL; + stopGL(); + mIgnoreActivate = TRUE; + LLCoordScreen old_size; + LLCoordScreen old_pos; + mWindow->getSize(&old_size); + + //mWindow->setFSAASamples(fsaa); + + result_first_try = mWindow->switchContext(false, size, disable_vsync); + if (!result_first_try) + { + // try to switch back + //mWindow->setFSAASamples(old_fsaa); + result_second_try = mWindow->switchContext(false, old_size, disable_vsync); + + if (!result_second_try) + { + // we are stuck...try once again with a minimal resolution? + send_agent_resume(); + mIgnoreActivate = FALSE; + return FALSE; + } + } + send_agent_resume(); + + LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL; + if (show_progress_bar) + { + restoreGL(LLTrans::getString("ProgressChangingResolution")); + } + else + { + restoreGL(); + } + + if (!result_first_try) + { + LLSD args; + args["RESX"] = llformat("%d",size.mX); + args["RESY"] = llformat("%d",size.mY); + LLNotificationsUtil::add("ResolutionSwitchFail", args); + size = old_size; // for reshape below + } + + BOOL success = result_first_try || result_second_try; + + if (success) + { + // maximize window if was maximized, else reposition + if (was_maximized) + { + mWindow->maximize(); + } + else + { + S32 windowX = gSavedSettings.getS32("WindowX"); + S32 windowY = gSavedSettings.getS32("WindowY"); + + mWindow->setPosition(LLCoordScreen ( windowX, windowY ) ); + } + } + + mIgnoreActivate = FALSE; + gFocusMgr.setKeyboardFocus(keyboard_focus); + + return success; + + */ +} + +F32 LLViewerWindow::getWorldViewAspectRatio() const +{ + F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight(); + return world_aspect; } void LLViewerWindow::calcDisplayScale() { - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); - LLVector2 display_scale; - display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); - display_scale *= ui_scale_factor; + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); + LLVector2 display_scale; + display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); + display_scale *= ui_scale_factor; - // limit minimum display scale - if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE) - { - display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]); - } - - if (display_scale != mDisplayScale) - { - LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL; + // limit minimum display scale + if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE) + { + display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]); + } + + if (display_scale != mDisplayScale) + { + LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL; - mDisplayScale = display_scale; - // Init default fonts - initFonts(); - } + mDisplayScale = display_scale; + // Init default fonts + initFonts(); + } } //static -LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale) +LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale) { - LLRect res = rect; - res.mLeft = ll_round((F32)res.mLeft / display_scale.mV[VX]); - res.mRight = ll_round((F32)res.mRight / display_scale.mV[VX]); - res.mBottom = ll_round((F32)res.mBottom / display_scale.mV[VY]); - res.mTop = ll_round((F32)res.mTop / display_scale.mV[VY]); + LLRect res = rect; + res.mLeft = ll_round((F32)res.mLeft / display_scale.mV[VX]); + res.mRight = ll_round((F32)res.mRight / display_scale.mV[VX]); + res.mBottom = ll_round((F32)res.mBottom / display_scale.mV[VY]); + res.mTop = ll_round((F32)res.mTop / display_scale.mV[VY]); - return res; + return res; } S32 LLViewerWindow::getChatConsoleBottomPad() { - S32 offset = 0; + S32 offset = 0; - if(gToolBarView) - offset += gToolBarView->getBottomToolbar()->getRect().getHeight(); + if(gToolBarView) + offset += gToolBarView->getBottomToolbar()->getRect().getHeight(); - return offset; + return offset; } LLRect LLViewerWindow::getChatConsoleRect() { - LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0); - LLRect console_rect = full_window; + LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0); + LLRect console_rect = full_window; - const S32 CONSOLE_PADDING_TOP = 24; - const S32 CONSOLE_PADDING_LEFT = 24; - const S32 CONSOLE_PADDING_RIGHT = 10; + const S32 CONSOLE_PADDING_TOP = 24; + const S32 CONSOLE_PADDING_LEFT = 24; + const S32 CONSOLE_PADDING_RIGHT = 10; - console_rect.mTop -= CONSOLE_PADDING_TOP; - console_rect.mBottom += getChatConsoleBottomPad(); + console_rect.mTop -= CONSOLE_PADDING_TOP; + console_rect.mBottom += getChatConsoleBottomPad(); - console_rect.mLeft += CONSOLE_PADDING_LEFT; + console_rect.mLeft += CONSOLE_PADDING_LEFT; - static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth"); + static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth"); - if (CHAT_FULL_WIDTH) - { - console_rect.mRight -= CONSOLE_PADDING_RIGHT; - } - else - { - // Make console rect somewhat narrow so having inventory open is - // less of a problem. - console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3; - } + if (CHAT_FULL_WIDTH) + { + console_rect.mRight -= CONSOLE_PADDING_RIGHT; + } + else + { + // Make console rect somewhat narrow so having inventory open is + // less of a problem. + console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3; + } - return console_rect; + return console_rect; } void LLViewerWindow::reshapeStatusBarContainer() @@ -6063,31 +6063,31 @@ void LLViewerWindow::reshapeStatusBarContainer() void LLViewerWindow::setUIVisibility(bool visible) { - mUIVisible = visible; + mUIVisible = visible; - if (!visible) - { - gAgentCamera.changeCameraToThirdPerson(FALSE); - gFloaterView->hideAllFloaters(); - } - else - { - gFloaterView->showHiddenFloaters(); - } + if (!visible) + { + gAgentCamera.changeCameraToThirdPerson(FALSE); + gFloaterView->hideAllFloaters(); + } + else + { + gFloaterView->showHiddenFloaters(); + } - if (gToolBarView) - { - gToolBarView->setToolBarsVisible(visible); - } + if (gToolBarView) + { + gToolBarView->setToolBarsVisible(visible); + } - LLNavigationBar::getInstance()->setVisible(visible ? gSavedSettings.getBOOL("ShowNavbarNavigationPanel") : FALSE); - LLPanelTopInfoBar::getInstance()->setVisible(visible? gSavedSettings.getBOOL("ShowMiniLocationPanel") : FALSE); - mRootView->getChildView("status_bar_container")->setVisible(visible); + LLNavigationBar::getInstance()->setVisible(visible ? gSavedSettings.getBOOL("ShowNavbarNavigationPanel") : FALSE); + LLPanelTopInfoBar::getInstance()->setVisible(visible? gSavedSettings.getBOOL("ShowMiniLocationPanel") : FALSE); + mRootView->getChildView("status_bar_container")->setVisible(visible); } bool LLViewerWindow::getUIVisibility() { - return mUIVisible; + return mUIVisible; } //////////////////////////////////////////////////////////////////////////// @@ -6095,22 +6095,22 @@ bool LLViewerWindow::getUIVisibility() // LLPickInfo // LLPickInfo::LLPickInfo() - : mKeyMask(MASK_NONE), - mPickCallback(NULL), - mPickType(PICK_INVALID), - mWantSurfaceInfo(FALSE), - mObjectFace(-1), - mUVCoords(-1.f, -1.f), - mSTCoords(-1.f, -1.f), - mXYCoords(-1, -1), - mIntersection(), - mNormal(), - mTangent(), - mBinormal(), - mHUDIcon(NULL), - mPickTransparent(FALSE), - mPickRigged(FALSE), - mPickParticle(FALSE) + : mKeyMask(MASK_NONE), + mPickCallback(NULL), + mPickType(PICK_INVALID), + mWantSurfaceInfo(FALSE), + mObjectFace(-1), + mUVCoords(-1.f, -1.f), + mSTCoords(-1.f, -1.f), + mXYCoords(-1, -1), + mIntersection(), + mNormal(), + mTangent(), + mBinormal(), + mHUDIcon(NULL), + mPickTransparent(FALSE), + mPickRigged(FALSE), + mPickParticle(FALSE) { } @@ -6140,236 +6140,236 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, mPickRigged(pick_rigged), mPickParticle(pick_particle), mPickReflectionProbe(pick_reflection_probe), - mPickUnselectable(pick_unselectable) + mPickUnselectable(pick_unselectable) { } void LLPickInfo::fetchResults() { - S32 face_hit = -1; + S32 face_hit = -1; + + LLVector4a intersection, normal; + LLVector4a tangent; - LLVector4a intersection, normal; - LLVector4a tangent; + LLVector2 uv; - LLVector2 uv; + LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); - LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); - - LLVector4a origin; - origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); - F32 icon_dist = 0.f; - LLVector4a start; - LLVector4a end; - LLVector4a particle_end; + LLVector4a origin; + origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); + F32 icon_dist = 0.f; + LLVector4a start; + LLVector4a end; + LLVector4a particle_end; - if (hit_icon) - { - LLVector4a delta; - delta.setSub(intersection, origin); - icon_dist = delta.getLength3().getF32(); - } + if (hit_icon) + { + LLVector4a delta; + delta.setSub(intersection, origin); + icon_dist = delta.getLength3().getF32(); + } - LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f, - nullptr, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, &face_hit, &mGLTFNodeIndex, &mGLTFPrimitiveIndex, + LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f, + nullptr, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, &face_hit, &mGLTFNodeIndex, &mGLTFPrimitiveIndex, &intersection, &uv, &normal, &tangent, &start, &end); - - mPickPt = mMousePt; - - U32 te_offset = face_hit > -1 ? face_hit : 0; - - if (mPickParticle) - { //get the end point of line segement to use for particle raycast - if (hit_object) - { - particle_end = intersection; - } - else - { - particle_end = end; - } - } - - LLViewerObject* objectp = hit_object; - - - LLVector4a delta; - delta.setSub(origin, intersection); - - if (hit_icon && - (!objectp || - icon_dist < delta.getLength3().getF32())) - { - // was this name referring to a hud icon? - mHUDIcon = hit_icon; - mPickType = PICK_ICON; - mPosGlobal = mHUDIcon->getPositionGlobal(); - - } - else if (objectp) - { - if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH ) - { - // Hit land - mPickType = PICK_LAND; - mObjectID.setNull(); // land has no id - - // put global position into land_pos - LLVector3d land_pos; - if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos, mPickUnselectable)) - { - // The selected point is beyond the draw distance or is otherwise - // not selectable. Return before calling mPickCallback(). - return; - } - - // Fudge the land focus a little bit above ground. - mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f; - } - else - { - if(isFlora(objectp)) - { - mPickType = PICK_FLORA; - } - else - { - mPickType = PICK_OBJECT; - } - - LLVector3 v_intersection(intersection.getF32ptr()); - - mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY); - mObjectID = objectp->mID; - mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; - - - - mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection); - - if (mWantSurfaceInfo) - { - getSurfaceInfo(); - } - } - } - - if (mPickParticle) - { //search for closest particle to click origin out to intersection point - S32 part_face = -1; - - LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face); - if (group) - { - mParticleOwnerID = group->getPartOwner(part_face); - mParticleSourceID = group->getPartSource(part_face); - } - } - - if (mPickCallback) - { - mPickCallback(*this); - } + + mPickPt = mMousePt; + + U32 te_offset = face_hit > -1 ? face_hit : 0; + + if (mPickParticle) + { //get the end point of line segement to use for particle raycast + if (hit_object) + { + particle_end = intersection; + } + else + { + particle_end = end; + } + } + + LLViewerObject* objectp = hit_object; + + + LLVector4a delta; + delta.setSub(origin, intersection); + + if (hit_icon && + (!objectp || + icon_dist < delta.getLength3().getF32())) + { + // was this name referring to a hud icon? + mHUDIcon = hit_icon; + mPickType = PICK_ICON; + mPosGlobal = mHUDIcon->getPositionGlobal(); + + } + else if (objectp) + { + if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH ) + { + // Hit land + mPickType = PICK_LAND; + mObjectID.setNull(); // land has no id + + // put global position into land_pos + LLVector3d land_pos; + if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos, mPickUnselectable)) + { + // The selected point is beyond the draw distance or is otherwise + // not selectable. Return before calling mPickCallback(). + return; + } + + // Fudge the land focus a little bit above ground. + mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f; + } + else + { + if(isFlora(objectp)) + { + mPickType = PICK_FLORA; + } + else + { + mPickType = PICK_OBJECT; + } + + LLVector3 v_intersection(intersection.getF32ptr()); + + mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY); + mObjectID = objectp->mID; + mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; + + + + mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection); + + if (mWantSurfaceInfo) + { + getSurfaceInfo(); + } + } + } + + if (mPickParticle) + { //search for closest particle to click origin out to intersection point + S32 part_face = -1; + + LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face); + if (group) + { + mParticleOwnerID = group->getPartOwner(part_face); + mParticleSourceID = group->getPartSource(part_face); + } + } + + if (mPickCallback) + { + mPickCallback(*this); + } } LLPointer LLPickInfo::getObject() const { - return gObjectList.findObject( mObjectID ); + return gObjectList.findObject( mObjectID ); } void LLPickInfo::updateXYCoords() { - if (mObjectFace > -1) - { - const LLTextureEntry* tep = getObject()->getTE(mObjectFace); - LLPointer imagep = LLViewerTextureManager::getFetchedTexture(tep->getID()); - if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) - { - mXYCoords.mX = ll_round(mUVCoords.mV[VX] * (F32)imagep->getWidth()); - mXYCoords.mY = ll_round((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight()); - } - } + if (mObjectFace > -1) + { + const LLTextureEntry* tep = getObject()->getTE(mObjectFace); + LLPointer imagep = LLViewerTextureManager::getFetchedTexture(tep->getID()); + if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) + { + mXYCoords.mX = ll_round(mUVCoords.mV[VX] * (F32)imagep->getWidth()); + mXYCoords.mY = ll_round((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight()); + } + } } void LLPickInfo::getSurfaceInfo() { - // set values to uninitialized - this is what we return if no intersection is found - mObjectFace = -1; - mUVCoords = LLVector2(-1, -1); - mSTCoords = LLVector2(-1, -1); - mXYCoords = LLCoordScreen(-1, -1); - mIntersection = LLVector3(0,0,0); - mNormal = LLVector3(0,0,0); - mBinormal = LLVector3(0,0,0); - mTangent = LLVector4(0,0,0,0); - - LLVector4a tangent; - LLVector4a intersection; - LLVector4a normal; - - tangent.clear(); - normal.clear(); - intersection.clear(); - - LLViewerObject* objectp = getObject(); - - if (objectp) - { - if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f, - objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, - &mObjectFace, + // set values to uninitialized - this is what we return if no intersection is found + mObjectFace = -1; + mUVCoords = LLVector2(-1, -1); + mSTCoords = LLVector2(-1, -1); + mXYCoords = LLCoordScreen(-1, -1); + mIntersection = LLVector3(0,0,0); + mNormal = LLVector3(0,0,0); + mBinormal = LLVector3(0,0,0); + mTangent = LLVector4(0,0,0,0); + + LLVector4a tangent; + LLVector4a intersection; + LLVector4a normal; + + tangent.clear(); + normal.clear(); + intersection.clear(); + + LLViewerObject* objectp = getObject(); + + if (objectp) + { + if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f, + objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, + &mObjectFace, &mGLTFNodeIndex, &mGLTFPrimitiveIndex, - &intersection, - &mSTCoords, - &normal, - &tangent)) - { - // if we succeeded with the intersect above, compute the texture coordinates: - - if (objectp->mDrawable.notNull() && mObjectFace > -1) - { - LLFace* facep = objectp->mDrawable->getFace(mObjectFace); - if (facep) - { - mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); - } - } - - mIntersection.set(intersection.getF32ptr()); - mNormal.set(normal.getF32ptr()); - mTangent.set(tangent.getF32ptr()); - - //extrapoloate binormal from normal and tangent - - LLVector4a binormal; - binormal.setCross3(normal, tangent); - binormal.mul(tangent.getF32ptr()[3]); - - mBinormal.set(binormal.getF32ptr()); - - mBinormal.normalize(); - mNormal.normalize(); - mTangent.normalize(); - - // and XY coords: - updateXYCoords(); - - } - } -} - -//static + &intersection, + &mSTCoords, + &normal, + &tangent)) + { + // if we succeeded with the intersect above, compute the texture coordinates: + + if (objectp->mDrawable.notNull() && mObjectFace > -1) + { + LLFace* facep = objectp->mDrawable->getFace(mObjectFace); + if (facep) + { + mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); + } + } + + mIntersection.set(intersection.getF32ptr()); + mNormal.set(normal.getF32ptr()); + mTangent.set(tangent.getF32ptr()); + + //extrapoloate binormal from normal and tangent + + LLVector4a binormal; + binormal.setCross3(normal, tangent); + binormal.mul(tangent.getF32ptr()[3]); + + mBinormal.set(binormal.getF32ptr()); + + mBinormal.normalize(); + mNormal.normalize(); + mTangent.normalize(); + + // and XY coords: + updateXYCoords(); + + } + } +} + +//static bool LLPickInfo::isFlora(LLViewerObject* object) { - if (!object) return false; + if (!object) return false; - LLPCode pcode = object->getPCode(); + LLPCode pcode = object->getPCode(); - if( (LL_PCODE_LEGACY_GRASS == pcode) - || (LL_PCODE_LEGACY_TREE == pcode) - || (LL_PCODE_TREE_NEW == pcode)) - { - return true; - } - return false; + if( (LL_PCODE_LEGACY_GRASS == pcode) + || (LL_PCODE_LEGACY_TREE == pcode) + || (LL_PCODE_TREE_NEW == pcode)) + { + return true; + } + return false; } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 121b5b6fad..fc22b003d5 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -1,25 +1,25 @@ -/** +/** * @file llviewerwindow.h * @brief Description of the LLViewerWindow class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -77,69 +77,69 @@ class LLCubeMapArray; class LLPickInfo { public: - typedef enum - { - PICK_OBJECT, - PICK_FLORA, - PICK_LAND, - PICK_ICON, - PICK_PARCEL_WALL, - PICK_INVALID - } EPickType; + typedef enum + { + PICK_OBJECT, + PICK_FLORA, + PICK_LAND, + PICK_ICON, + PICK_PARCEL_WALL, + PICK_INVALID + } EPickType; public: - LLPickInfo(); - LLPickInfo(const LLCoordGL& mouse_pos, - MASK keyboard_mask, - BOOL pick_transparent, - BOOL pick_rigged, - BOOL pick_particle, + LLPickInfo(); + LLPickInfo(const LLCoordGL& mouse_pos, + MASK keyboard_mask, + BOOL pick_transparent, + BOOL pick_rigged, + BOOL pick_particle, BOOL pick_reflection_probe, - BOOL pick_surface_info, - BOOL pick_unselectable, - void (*pick_callback)(const LLPickInfo& pick_info)); + BOOL pick_surface_info, + BOOL pick_unselectable, + void (*pick_callback)(const LLPickInfo& pick_info)); - void fetchResults(); - LLPointer getObject() const; - LLUUID getObjectID() const { return mObjectID; } - bool isValid() const { return mPickType != PICK_INVALID; } + void fetchResults(); + LLPointer getObject() const; + LLUUID getObjectID() const { return mObjectID; } + bool isValid() const { return mPickType != PICK_INVALID; } - static bool isFlora(LLViewerObject* object); + static bool isFlora(LLViewerObject* object); public: - LLCoordGL mMousePt; - MASK mKeyMask; - void (*mPickCallback)(const LLPickInfo& pick_info); - - EPickType mPickType; - LLCoordGL mPickPt; - LLVector3d mPosGlobal; - LLVector3 mObjectOffset; - LLUUID mObjectID; - LLUUID mParticleOwnerID; - LLUUID mParticleSourceID; - S32 mObjectFace; + LLCoordGL mMousePt; + MASK mKeyMask; + void (*mPickCallback)(const LLPickInfo& pick_info); + + EPickType mPickType; + LLCoordGL mPickPt; + LLVector3d mPosGlobal; + LLVector3 mObjectOffset; + LLUUID mObjectID; + LLUUID mParticleOwnerID; + LLUUID mParticleSourceID; + S32 mObjectFace; S32 mGLTFNodeIndex = -1; S32 mGLTFPrimitiveIndex = -1; - LLHUDIcon* mHUDIcon; - LLVector3 mIntersection; - LLVector2 mUVCoords; - LLVector2 mSTCoords; - LLCoordScreen mXYCoords; - LLVector3 mNormal; - LLVector4 mTangent; - LLVector3 mBinormal; - BOOL mPickTransparent; - BOOL mPickRigged; - BOOL mPickParticle; - BOOL mPickUnselectable; + LLHUDIcon* mHUDIcon; + LLVector3 mIntersection; + LLVector2 mUVCoords; + LLVector2 mSTCoords; + LLCoordScreen mXYCoords; + LLVector3 mNormal; + LLVector4 mTangent; + LLVector3 mBinormal; + BOOL mPickTransparent; + BOOL mPickRigged; + BOOL mPickParticle; + BOOL mPickUnselectable; BOOL mPickReflectionProbe = FALSE; - void getSurfaceInfo(); + void getSurfaceInfo(); private: - void updateXYCoords(); + void updateXYCoords(); - BOOL mWantSurfaceInfo; // do we populate mUVCoord, mNormal, mBinormal? + BOOL mWantSurfaceInfo; // do we populate mUVCoord, mNormal, mBinormal? }; @@ -148,228 +148,228 @@ static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 class LLViewerWindow : public LLWindowCallbacks { public: - // - // CREATORS - // - struct Params : public LLInitParam::Block - { - Mandatory title, - name; - Mandatory x, - y, - width, - height, - min_width, - min_height; - Optional fullscreen, - ignore_pixel_depth, - first_run; - - Params(); - }; - - LLViewerWindow(const Params& p); - virtual ~LLViewerWindow(); - - void shutdownViews(); - void shutdownGL(); - - void initGLDefaults(); - void initBase(); - void adjustRectanglesForFirstUse(const LLRect& window); - void adjustControlRectanglesForFirstUse(const LLRect& window); - void initWorldUI(); - void setUIVisibility(bool); - bool getUIVisibility(); - void handlePieMenu(S32 x, S32 y, MASK mask); + // + // CREATORS + // + struct Params : public LLInitParam::Block + { + Mandatory title, + name; + Mandatory x, + y, + width, + height, + min_width, + min_height; + Optional fullscreen, + ignore_pixel_depth, + first_run; + + Params(); + }; + + LLViewerWindow(const Params& p); + virtual ~LLViewerWindow(); + + void shutdownViews(); + void shutdownGL(); + + void initGLDefaults(); + void initBase(); + void adjustRectanglesForFirstUse(const LLRect& window); + void adjustControlRectanglesForFirstUse(const LLRect& window); + void initWorldUI(); + void setUIVisibility(bool); + bool getUIVisibility(); + void handlePieMenu(S32 x, S32 y, MASK mask); void reshapeStatusBarContainer(); - BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action); - - // - // LLWindowCallback interface implementation - // - /*virtual*/ BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated); - /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask); - /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); - /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended - /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleCloseRequest(LLWindow *window); - /*virtual*/ void handleQuit(LLWindow *window); - /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); - /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); - BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down); - /*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data); - void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action); + + // + // LLWindowCallback interface implementation + // + /*virtual*/ BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated); + /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask); + /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); + /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended + /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleCloseRequest(LLWindow *window); + /*virtual*/ void handleQuit(LLWindow *window); + /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); + /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button); + BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down); + /*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data); + void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ void handleMouseLeave(LLWindow *window); - /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); - /*virtual*/ void handleFocus(LLWindow *window); - /*virtual*/ void handleFocusLost(LLWindow *window); - /*virtual*/ BOOL handleActivate(LLWindow *window, BOOL activated); - /*virtual*/ BOOL handleActivateApp(LLWindow *window, BOOL activating); - /*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item); - /*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height); - /*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks); - /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks); - /*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ void handleWindowBlock(LLWindow *window); - /*virtual*/ void handleWindowUnblock(LLWindow *window); - /*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data); - /*virtual*/ BOOL handleTimerEvent(LLWindow *window); - /*virtual*/ BOOL handleDeviceChange(LLWindow *window); - /*virtual*/ BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); - /*virtual*/ BOOL handleWindowDidChangeScreen(LLWindow *window); - - /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg); - /*virtual*/ void handlePauseWatchdog(LLWindow *window); - /*virtual*/ void handleResumeWatchdog(LLWindow *window); - /*virtual*/ std::string translateString(const char* tag); - /*virtual*/ std::string translateString(const char* tag, - const std::map& args); - - // signal on update of WorldView rect - typedef boost::function world_rect_callback_t; - typedef boost::signals2::signal world_rect_signal_t; - world_rect_signal_t mOnWorldViewRectUpdated; - boost::signals2::connection setOnWorldViewRectUpdated(world_rect_callback_t cb) { return mOnWorldViewRectUpdated.connect(cb); } - - // - // ACCESSORS - // - LLRootView* getRootView() const; - - // 3D world area in scaled pixels (via UI scale), use for most UI computations - LLRect getWorldViewRectScaled() const; - S32 getWorldViewHeightScaled() const; - S32 getWorldViewWidthScaled() const; - - // 3D world area, in raw unscaled pixels - LLRect getWorldViewRectRaw() const { return mWorldViewRectRaw; } - S32 getWorldViewHeightRaw() const; - S32 getWorldViewWidthRaw() const; - - // Window in scaled pixels (via UI scale), use for most UI computations - LLRect getWindowRectScaled() const { return mWindowRectScaled; } - S32 getWindowHeightScaled() const; - S32 getWindowWidthScaled() const; - - // Window in raw pixels as seen on screen. - LLRect getWindowRectRaw() const { return mWindowRectRaw; } - S32 getWindowHeightRaw() const; - S32 getWindowWidthRaw() const; - - LLWindow* getWindow() const { return mWindow; } - void* getPlatformWindow() const; - void* getMediaWindow() const; - void focusClient() const; - - LLCoordGL getLastMouse() const { return mLastMousePoint; } - S32 getLastMouseX() const { return mLastMousePoint.mX; } - S32 getLastMouseY() const { return mLastMousePoint.mY; } - LLCoordGL getCurrentMouse() const { return mCurrentMousePoint; } - S32 getCurrentMouseX() const { return mCurrentMousePoint.mX; } - S32 getCurrentMouseY() const { return mCurrentMousePoint.mY; } - S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } - S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } - LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } - BOOL getLeftMouseDown() const { return mLeftMouseDown; } - BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } - BOOL getRightMouseDown() const { return mRightMouseDown; } - - const LLPickInfo& getLastPick() const { return mLastPick; } - - void setup2DViewport(S32 x_offset = 0, S32 y_offset = 0); - void setup3DViewport(S32 x_offset = 0, S32 y_offset = 0); - void setup3DRender(); - void setup2DRender(); - - LLVector3 mouseDirectionGlobal(const S32 x, const S32 y) const; - LLVector3 mouseDirectionCamera(const S32 x, const S32 y) const; - LLVector3 mousePointHUD(const S32 x, const S32 y) const; - - - // Is window of our application frontmost? - BOOL getActive() const { return mActive; } - - const std::string& getInitAlert() { return mInitAlert; } - - // - // MANIPULATORS - // - void saveLastMouse(const LLCoordGL &point); - - void setCursor( ECursorType c ); - void showCursor(); - void hideCursor(); - BOOL getCursorHidden() { return mCursorHidden; } - void moveCursorToCenter(); // move to center of window - - void initTextures(S32 location_id); - void setShowProgress(const BOOL show); - BOOL getShowProgress() const; - void setProgressString(const std::string& string); - void setProgressPercent(const F32 percent); - void setProgressMessage(const std::string& msg); - void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null ); - LLProgressView *getProgressView() const; - void revealIntroPanel(); - void setStartupComplete(); - - void updateObjectUnderCursor(); - - void updateUI(); // Once per frame, update UI based on mouse position, calls following update* functions - void updateLayout(); - void updateMouseDelta(); - void updateKeyboardFocus(); - - void updateWorldViewRect(bool use_full_window=false); - LLView* getToolBarHolder() { return mToolBarHolder.get(); } - LLView* getHintHolder() { return mHintHolder.get(); } - LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); } - BOOL handleKey(KEY key, MASK mask); - BOOL handleKeyUp(KEY key, MASK mask); - void handleScrollWheel (S32 clicks); - void handleScrollHWheel (S32 clicks); - - // add and remove views from "popup" layer - void addPopup(LLView* popup); - void removePopup(LLView* popup); - void clearPopups(); - - // Hide normal UI when a logon fails, re-show everything when logon is attempted again - void setNormalControlsVisible( BOOL visible ); - void setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false); - - void reshape(S32 width, S32 height); - void sendShapeToSim(); - - void draw(); - void updateDebugText(); - void drawDebugText(); - - static void loadUserImage(void **cb_data, const LLUUID &uuid); - - static void movieSize(S32 new_width, S32 new_height); - - // snapshot functionality. - // perhaps some of this should move to llfloatershapshot? -MG - - BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP); - BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, - BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE); - - BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes); - - - + /*virtual*/ void handleMouseLeave(LLWindow *window); + /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); + /*virtual*/ void handleFocus(LLWindow *window); + /*virtual*/ void handleFocusLost(LLWindow *window); + /*virtual*/ BOOL handleActivate(LLWindow *window, BOOL activated); + /*virtual*/ BOOL handleActivateApp(LLWindow *window, BOOL activating); + /*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item); + /*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height); + /*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks); + /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks); + /*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); + /*virtual*/ void handleWindowBlock(LLWindow *window); + /*virtual*/ void handleWindowUnblock(LLWindow *window); + /*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data); + /*virtual*/ BOOL handleTimerEvent(LLWindow *window); + /*virtual*/ BOOL handleDeviceChange(LLWindow *window); + /*virtual*/ BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); + /*virtual*/ BOOL handleWindowDidChangeScreen(LLWindow *window); + + /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg); + /*virtual*/ void handlePauseWatchdog(LLWindow *window); + /*virtual*/ void handleResumeWatchdog(LLWindow *window); + /*virtual*/ std::string translateString(const char* tag); + /*virtual*/ std::string translateString(const char* tag, + const std::map& args); + + // signal on update of WorldView rect + typedef boost::function world_rect_callback_t; + typedef boost::signals2::signal world_rect_signal_t; + world_rect_signal_t mOnWorldViewRectUpdated; + boost::signals2::connection setOnWorldViewRectUpdated(world_rect_callback_t cb) { return mOnWorldViewRectUpdated.connect(cb); } + + // + // ACCESSORS + // + LLRootView* getRootView() const; + + // 3D world area in scaled pixels (via UI scale), use for most UI computations + LLRect getWorldViewRectScaled() const; + S32 getWorldViewHeightScaled() const; + S32 getWorldViewWidthScaled() const; + + // 3D world area, in raw unscaled pixels + LLRect getWorldViewRectRaw() const { return mWorldViewRectRaw; } + S32 getWorldViewHeightRaw() const; + S32 getWorldViewWidthRaw() const; + + // Window in scaled pixels (via UI scale), use for most UI computations + LLRect getWindowRectScaled() const { return mWindowRectScaled; } + S32 getWindowHeightScaled() const; + S32 getWindowWidthScaled() const; + + // Window in raw pixels as seen on screen. + LLRect getWindowRectRaw() const { return mWindowRectRaw; } + S32 getWindowHeightRaw() const; + S32 getWindowWidthRaw() const; + + LLWindow* getWindow() const { return mWindow; } + void* getPlatformWindow() const; + void* getMediaWindow() const; + void focusClient() const; + + LLCoordGL getLastMouse() const { return mLastMousePoint; } + S32 getLastMouseX() const { return mLastMousePoint.mX; } + S32 getLastMouseY() const { return mLastMousePoint.mY; } + LLCoordGL getCurrentMouse() const { return mCurrentMousePoint; } + S32 getCurrentMouseX() const { return mCurrentMousePoint.mX; } + S32 getCurrentMouseY() const { return mCurrentMousePoint.mY; } + S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } + S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } + LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } + static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } + BOOL getLeftMouseDown() const { return mLeftMouseDown; } + BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } + BOOL getRightMouseDown() const { return mRightMouseDown; } + + const LLPickInfo& getLastPick() const { return mLastPick; } + + void setup2DViewport(S32 x_offset = 0, S32 y_offset = 0); + void setup3DViewport(S32 x_offset = 0, S32 y_offset = 0); + void setup3DRender(); + void setup2DRender(); + + LLVector3 mouseDirectionGlobal(const S32 x, const S32 y) const; + LLVector3 mouseDirectionCamera(const S32 x, const S32 y) const; + LLVector3 mousePointHUD(const S32 x, const S32 y) const; + + + // Is window of our application frontmost? + BOOL getActive() const { return mActive; } + + const std::string& getInitAlert() { return mInitAlert; } + + // + // MANIPULATORS + // + void saveLastMouse(const LLCoordGL &point); + + void setCursor( ECursorType c ); + void showCursor(); + void hideCursor(); + BOOL getCursorHidden() { return mCursorHidden; } + void moveCursorToCenter(); // move to center of window + + void initTextures(S32 location_id); + void setShowProgress(const BOOL show); + BOOL getShowProgress() const; + void setProgressString(const std::string& string); + void setProgressPercent(const F32 percent); + void setProgressMessage(const std::string& msg); + void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null ); + LLProgressView *getProgressView() const; + void revealIntroPanel(); + void setStartupComplete(); + + void updateObjectUnderCursor(); + + void updateUI(); // Once per frame, update UI based on mouse position, calls following update* functions + void updateLayout(); + void updateMouseDelta(); + void updateKeyboardFocus(); + + void updateWorldViewRect(bool use_full_window=false); + LLView* getToolBarHolder() { return mToolBarHolder.get(); } + LLView* getHintHolder() { return mHintHolder.get(); } + LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); } + BOOL handleKey(KEY key, MASK mask); + BOOL handleKeyUp(KEY key, MASK mask); + void handleScrollWheel (S32 clicks); + void handleScrollHWheel (S32 clicks); + + // add and remove views from "popup" layer + void addPopup(LLView* popup); + void removePopup(LLView* popup); + void clearPopups(); + + // Hide normal UI when a logon fails, re-show everything when logon is attempted again + void setNormalControlsVisible( BOOL visible ); + void setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false); + + void reshape(S32 width, S32 height); + void sendShapeToSim(); + + void draw(); + void updateDebugText(); + void drawDebugText(); + + static void loadUserImage(void **cb_data, const LLUUID &uuid); + + static void movieSize(S32 new_width, S32 new_height); + + // snapshot functionality. + // perhaps some of this should move to llfloatershapshot? -MG + + BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP); + BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, + BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE); + + BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes); + + + // take a cubemap snapshot // origin - vantage point to take the snapshot from // cubearray - cubemap array for storing the results @@ -379,202 +379,202 @@ public: BOOL cubeSnapshot(const LLVector3 &origin, LLCubeMapArray *cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars, bool customCullingPlane = false, LLPlane cullingPlane = LLPlane(LLVector3(0, 0, 0), LLVector3(0, 0, 1))); - + // special implementation of simpleSnapshot for reflection maps - BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes); - - BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type); - BOOL isSnapshotLocSet() const; - void resetSnapshotLoc() const; - - typedef boost::signals2::signal snapshot_saved_signal_t; - - void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); - void onDirectorySelected(const std::vector& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); - void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); - void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb); - - // Reset the directory where snapshots are saved. - // Client will open directory picker on next snapshot save. - void resetSnapshotLoc(); - - void playSnapshotAnimAndSound(); - - // draws selection boxes around selected objects, must call displayObjects first - void renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud ); - void performPick(); - void returnEmptyPicks(); - - void pickAsync( S32 x, - S32 y_from_bot, - MASK mask, - void (*callback)(const LLPickInfo& pick_info), - BOOL pick_transparent = FALSE, - BOOL pick_rigged = FALSE, - BOOL pick_unselectable = FALSE, + BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes); + + BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type); + BOOL isSnapshotLocSet() const; + void resetSnapshotLoc() const; + + typedef boost::signals2::signal snapshot_saved_signal_t; + + void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); + void onDirectorySelected(const std::vector& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); + void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb); + void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb); + + // Reset the directory where snapshots are saved. + // Client will open directory picker on next snapshot save. + void resetSnapshotLoc(); + + void playSnapshotAnimAndSound(); + + // draws selection boxes around selected objects, must call displayObjects first + void renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud ); + void performPick(); + void returnEmptyPicks(); + + void pickAsync( S32 x, + S32 y_from_bot, + MASK mask, + void (*callback)(const LLPickInfo& pick_info), + BOOL pick_transparent = FALSE, + BOOL pick_rigged = FALSE, + BOOL pick_unselectable = FALSE, BOOL pick_reflection_probes = FALSE); - LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = FALSE); - LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, - LLVector4a* intersection); - - LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f, - LLViewerObject *this_object = NULL, - S32 this_face = -1, - BOOL pick_transparent = FALSE, - BOOL pick_rigged = FALSE, + LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = FALSE); + LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, + LLVector4a* intersection); + + LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f, + LLViewerObject *this_object = NULL, + S32 this_face = -1, + BOOL pick_transparent = FALSE, + BOOL pick_rigged = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = TRUE, - S32* face_hit = NULL, + S32* face_hit = NULL, S32* gltf_node_hit = nullptr, S32* gltf_primitive_hit = nullptr, - LLVector4a *intersection = NULL, - LLVector2 *uv = NULL, - LLVector4a *normal = NULL, - LLVector4a *tangent = NULL, - LLVector4a* start = NULL, - LLVector4a* end = NULL); - - - // Returns a pointer to the last object hit - //LLViewerObject *getObject(); - //LLViewerObject *lastNonFloraObjectHit(); - - //const LLVector3d& getObjectOffset(); - //const LLVector3d& lastNonFloraObjectHitOffset(); - - // mousePointOnLand() returns true if found point - BOOL mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_pos_global, BOOL ignore_distance = FALSE); - BOOL mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, const LLVector3d &plane_point, const LLVector3 &plane_normal); - LLVector3d clickPointInWorldGlobal(const S32 x, const S32 y_from_bot, LLViewerObject* clicked_object) const; - BOOL clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const; - - // Prints window implementation details - void dumpState(); - - // handle shutting down GL and bringing it back up - void requestResolutionUpdate(); - void checkSettings(); - void restartDisplay(BOOL show_progress_bar); - BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar); - BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } - F32 getWorldViewAspectRatio() const; - const LLVector2& getDisplayScale() const { return mDisplayScale; } - void calcDisplayScale(); - static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale); - - static std::string getLastSnapshotDir(); + LLVector4a *intersection = NULL, + LLVector2 *uv = NULL, + LLVector4a *normal = NULL, + LLVector4a *tangent = NULL, + LLVector4a* start = NULL, + LLVector4a* end = NULL); + + + // Returns a pointer to the last object hit + //LLViewerObject *getObject(); + //LLViewerObject *lastNonFloraObjectHit(); + + //const LLVector3d& getObjectOffset(); + //const LLVector3d& lastNonFloraObjectHitOffset(); + + // mousePointOnLand() returns true if found point + BOOL mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_pos_global, BOOL ignore_distance = FALSE); + BOOL mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, const LLVector3d &plane_point, const LLVector3 &plane_normal); + LLVector3d clickPointInWorldGlobal(const S32 x, const S32 y_from_bot, LLViewerObject* clicked_object) const; + BOOL clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const; + + // Prints window implementation details + void dumpState(); + + // handle shutting down GL and bringing it back up + void requestResolutionUpdate(); + void checkSettings(); + void restartDisplay(BOOL show_progress_bar); + BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar); + BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } + F32 getWorldViewAspectRatio() const; + const LLVector2& getDisplayScale() const { return mDisplayScale; } + void calcDisplayScale(); + static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale); + + static std::string getLastSnapshotDir(); private: - bool shouldShowToolTipFor(LLMouseHandler *mh); - - void switchToolByMask(MASK mask); - void destroyWindow(); - void drawMouselookInstructions(); - void stopGL(BOOL save_state = TRUE); - void restoreGL(const std::string& progress_message = LLStringUtil::null); - void initFonts(F32 zoom_factor = 1.f); - void schedulePick(LLPickInfo& pick_info); - S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter - LLRect getChatConsoleRect(); // Get optimal cosole rect. + bool shouldShowToolTipFor(LLMouseHandler *mh); + + void switchToolByMask(MASK mask); + void destroyWindow(); + void drawMouselookInstructions(); + void stopGL(BOOL save_state = TRUE); + void restoreGL(const std::string& progress_message = LLStringUtil::null); + void initFonts(F32 zoom_factor = 1.f); + void schedulePick(LLPickInfo& pick_info); + S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter + LLRect getChatConsoleRect(); // Get optimal cosole rect. private: - LLWindow* mWindow; // graphical window object - bool mActive; - bool mUIVisible; - - LLNotificationChannelPtr mSystemChannel; - LLNotificationChannelPtr mCommunicationChannel; - LLNotificationChannelPtr mAlertsChannel; - LLNotificationChannelPtr mModalAlertsChannel; - - LLRect mWindowRectRaw; // whole window, including UI - LLRect mWindowRectScaled; // whole window, scaled by UI size - LLRect mWorldViewRectRaw; // area of screen for 3D world - LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size - LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views - LLVector2 mDisplayScale; - - LLCoordGL mCurrentMousePoint; // last mouse position in GL coords - LLCoordGL mLastMousePoint; // Mouse point at last frame. - LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame - BOOL mLeftMouseDown; - BOOL mMiddleMouseDown; - BOOL mRightMouseDown; - - LLProgressView *mProgressView; - - LLFrameTimer mToolTipFadeTimer; - LLPanel* mToolTip; - std::string mLastToolTipMessage; - LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect. - - BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse. - BOOL mFocusCycleMode; + LLWindow* mWindow; // graphical window object + bool mActive; + bool mUIVisible; + + LLNotificationChannelPtr mSystemChannel; + LLNotificationChannelPtr mCommunicationChannel; + LLNotificationChannelPtr mAlertsChannel; + LLNotificationChannelPtr mModalAlertsChannel; + + LLRect mWindowRectRaw; // whole window, including UI + LLRect mWindowRectScaled; // whole window, scaled by UI size + LLRect mWorldViewRectRaw; // area of screen for 3D world + LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size + LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views + LLVector2 mDisplayScale; + + LLCoordGL mCurrentMousePoint; // last mouse position in GL coords + LLCoordGL mLastMousePoint; // Mouse point at last frame. + LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame + BOOL mLeftMouseDown; + BOOL mMiddleMouseDown; + BOOL mRightMouseDown; + + LLProgressView *mProgressView; + + LLFrameTimer mToolTipFadeTimer; + LLPanel* mToolTip; + std::string mLastToolTipMessage; + LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect. + + BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse. + BOOL mFocusCycleMode; BOOL mAllowMouseDragging; LLFrameTimer mMouseDownTimer; - typedef std::set > view_handle_set_t; - view_handle_set_t mMouseHoverViews; - - // Variables used for tool override switching based on modifier keys. JC - MASK mLastMask; // used to detect changes in modifier mask - LLTool* mToolStored; // the tool we're overriding - BOOL mHideCursorPermanent; // true during drags, mouselook - BOOL mCursorHidden; - LLPickInfo mLastPick; - std::vector mPicks; - LLRect mPickScreenRegion; // area of frame buffer for rendering pick frames (generally follows mouse to avoid going offscreen) - LLTimer mPickTimer; // timer for scheduling n picks per second - - std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta" - - BOOL mIgnoreActivate; - - std::string mInitAlert; // Window / GL initialization requires an alert - - LLHandle mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world - LLHandle mToolBarHolder; // container for toolbars - LLHandle mHintHolder; // container for hints - LLHandle mLoginPanelHolder; // container for login panel - LLPopupView* mPopupView; // container for transient popups - - class LLDebugText* mDebugText; // Internal class for debug text - - bool mResDirty; - bool mStatesDirty; - U32 mCurrResolutionIndex; - - std::unique_ptr mWindowListener; - std::unique_ptr mViewerWindowListener; - - // Object temporarily hovered over while dragging - LLPointer mDragHoveredObject; - - static LLTrace::SampleStatHandle<> sMouseVelocityStat; + typedef std::set > view_handle_set_t; + view_handle_set_t mMouseHoverViews; + + // Variables used for tool override switching based on modifier keys. JC + MASK mLastMask; // used to detect changes in modifier mask + LLTool* mToolStored; // the tool we're overriding + BOOL mHideCursorPermanent; // true during drags, mouselook + BOOL mCursorHidden; + LLPickInfo mLastPick; + std::vector mPicks; + LLRect mPickScreenRegion; // area of frame buffer for rendering pick frames (generally follows mouse to avoid going offscreen) + LLTimer mPickTimer; // timer for scheduling n picks per second + + std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta" + + BOOL mIgnoreActivate; + + std::string mInitAlert; // Window / GL initialization requires an alert + + LLHandle mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world + LLHandle mToolBarHolder; // container for toolbars + LLHandle mHintHolder; // container for hints + LLHandle mLoginPanelHolder; // container for login panel + LLPopupView* mPopupView; // container for transient popups + + class LLDebugText* mDebugText; // Internal class for debug text + + bool mResDirty; + bool mStatesDirty; + U32 mCurrResolutionIndex; + + std::unique_ptr mWindowListener; + std::unique_ptr mViewerWindowListener; + + // Object temporarily hovered over while dragging + LLPointer mDragHoveredObject; + + static LLTrace::SampleStatHandle<> sMouseVelocityStat; }; // // Globals // -extern LLViewerWindow* gViewerWindow; +extern LLViewerWindow* gViewerWindow; -extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true -extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away +extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true +extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away extern LLViewerObject* gDebugRaycastObject; extern LLVector4a gDebugRaycastIntersection; -extern LLVOPartGroup* gDebugRaycastParticle; -extern LLVector4a gDebugRaycastParticleIntersection; +extern LLVOPartGroup* gDebugRaycastParticle; +extern LLVector4a gDebugRaycastParticleIntersection; extern LLVector2 gDebugRaycastTexCoord; extern LLVector4a gDebugRaycastNormal; extern LLVector4a gDebugRaycastTangent; -extern S32 gDebugRaycastFaceHit; -extern LLVector4a gDebugRaycastStart; -extern LLVector4a gDebugRaycastEnd; - -extern BOOL gDisplayCameraPos; -extern BOOL gDisplayWindInfo; -extern BOOL gDisplayFOV; -extern BOOL gDisplayBadge; +extern S32 gDebugRaycastFaceHit; +extern LLVector4a gDebugRaycastStart; +extern LLVector4a gDebugRaycastEnd; + +extern BOOL gDisplayCameraPos; +extern BOOL gDisplayWindInfo; +extern BOOL gDisplayFOV; +extern BOOL gDisplayBadge; #endif diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d3b5cc8a5..1ffbf20410 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvlcomposition.cpp * @brief Viewer-side representation of a composition layer... * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -161,7 +161,7 @@ LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) // Assume both the the material and texture were fetched in the same way // using the same UUID. However, we may not know at this point which one // will load. - return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; + return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -183,9 +183,9 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) unboost_minimap_texture(mDetailTextures[asset]); unboost_minimap_material(mDetailMaterials[asset]); - // This is terrain texture, but we are not setting it as BOOST_TERRAIN - // since we will be manipulating it later as needed. - mDetailTextures[asset] = fetch_terrain_texture(id); + // This is terrain texture, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. + mDetailTextures[asset] = fetch_terrain_texture(id); LLPointer& mat = mDetailMaterials[asset]; mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; @@ -193,7 +193,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { - LL_PROFILE_ZONE_SCOPED; + LL_PROFILE_ZONE_SCOPED; const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false); return use_textures ? Type::TEXTURE : Type::PBR; @@ -372,23 +372,23 @@ const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT] LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : LLTerrainMaterials(), - LLViewerLayer(width, scale) + LLViewerLayer(width, scale) { - // Load Terrain Textures - Original ones + // Load Terrain Textures - Original ones const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); for (S32 i = 0; i < ASSET_COUNT; ++i) { setDetailAssetID(i, default_textures[i]); } - mSurfacep = surfacep; + mSurfacep = surfacep; - // Initialize the texture matrix to defaults. - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); - mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); - } + // Initialize the texture matrix to defaults. + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); + mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); + } } @@ -400,117 +400,117 @@ LLVLComposition::~LLVLComposition() void LLVLComposition::setSurface(LLSurface *surfacep) { - mSurfacep = surfacep; + mSurfacep = surfacep; } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, - const F32 width, const F32 height) + const F32 width, const F32 height) { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } - - llassert(mSurfacep); - - if (!mSurfacep || !mSurfacep->getRegion()) - { - // We don't always have the region yet here.... - return FALSE; - } - - S32 x_begin, y_begin, x_end, y_end; - - x_begin = ll_round( x * mScaleInv ); - y_begin = ll_round( y * mScaleInv ); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); - - if (x_end > mWidth) - { - x_end = mWidth; - } - if (y_end > mWidth) - { - y_end = mWidth; - } - - LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); - - // For perlin noise generation... - const F32 slope_squared = 1.5f*1.5f; - const F32 xyScale = 4.9215f; //0.93284f; - const F32 zScale = 4; //0.92165f; - const F32 z_offset = 0.f; - const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus - // simple height) - - const F32 xyScaleInv = (1.f / xyScale); - const F32 zScaleInv = (1.f / zScale); - - const F32 inv_width = 1.f/mWidth; - - // OK, for now, just have the composition value equal the height at the point. - for (S32 j = y_begin; j < y_end; j++) - { - for (S32 i = x_begin; i < x_end; i++) - { - - F32 vec[3]; - F32 vec1[3]; - F32 twiddle; - - // Bilinearly interpolate the start height and height range of the textures - F32 start_height = bilinear(mStartHeight[SOUTHWEST], - mStartHeight[SOUTHEAST], - mStartHeight[NORTHWEST], - mStartHeight[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - F32 height_range = bilinear(mHeightRange[SOUTHWEST], - mHeightRange[SOUTHEAST], - mHeightRange[NORTHWEST], - mHeightRange[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - - LLVector3 location(i*mScale, j*mScale, 0.f); - - F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; - - // Step 0: Measure the exact height at this texel - vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice - vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; - vec[2] = height*zScaleInv; - // - // Choose material value by adding to the exact height a random value - // - vec1[0] = vec[0]*(0.2222222222f); - vec1[1] = vec[1]*(0.2222222222f); - vec1[2] = vec[2]*(0.2222222222f); - twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions - - twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component - twiddle *= noise_magnitude; - - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; - - scaled_noisy_height = llmax(0.f, scaled_noisy_height); - scaled_noisy_height = llmin(3.f, scaled_noisy_height); - *(mDatap + i + j*mWidth) = scaled_noisy_height; - } - } - return TRUE; + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } + + llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) + { + // We don't always have the region yet here.... + return FALSE; + } + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round( x * mScaleInv ); + y_begin = ll_round( y * mScaleInv ); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { + x_end = mWidth; + } + if (y_end > mWidth) + { + y_end = mWidth; + } + + LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); + + // For perlin noise generation... + const F32 slope_squared = 1.5f*1.5f; + const F32 xyScale = 4.9215f; //0.93284f; + const F32 zScale = 4; //0.92165f; + const F32 z_offset = 0.f; + const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus + // simple height) + + const F32 xyScaleInv = (1.f / xyScale); + const F32 zScaleInv = (1.f / zScale); + + const F32 inv_width = 1.f/mWidth; + + // OK, for now, just have the composition value equal the height at the point. + for (S32 j = y_begin; j < y_end; j++) + { + for (S32 i = x_begin; i < x_end; i++) + { + + F32 vec[3]; + F32 vec1[3]; + F32 twiddle; + + // Bilinearly interpolate the start height and height range of the textures + F32 start_height = bilinear(mStartHeight[SOUTHWEST], + mStartHeight[SOUTHEAST], + mStartHeight[NORTHWEST], + mStartHeight[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + F32 height_range = bilinear(mHeightRange[SOUTHWEST], + mHeightRange[SOUTHEAST], + mHeightRange[NORTHWEST], + mHeightRange[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + + LLVector3 location(i*mScale, j*mScale, 0.f); + + F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; + + // Step 0: Measure the exact height at this texel + vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice + vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; + vec[2] = height*zScaleInv; + // + // Choose material value by adding to the exact height a random value + // + vec1[0] = vec[0]*(0.2222222222f); + vec1[1] = vec[1]*(0.2222222222f); + vec1[2] = vec[2]*(0.2222222222f); + twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions + + twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component + twiddle *= noise_magnitude; + + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; + + scaled_noisy_height = llmax(0.f, scaled_noisy_height); + scaled_noisy_height = llmin(3.f, scaled_noisy_height); + *(mDatap + i + j*mWidth) = scaled_noisy_height; + } + } + return TRUE; } LLTerrainMaterials gLocalTerrainMaterials; BOOL LLVLComposition::generateComposition() { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } return LLTerrainMaterials::generateMaterials(); } @@ -618,22 +618,22 @@ namespace }; BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, - const F32 width, const F32 height) + const F32 width, const F32 height) { - LL_PROFILE_ZONE_SCOPED - llassert(mSurfacep); - llassert(x >= 0.f); - llassert(y >= 0.f); + LL_PROFILE_ZONE_SCOPED + llassert(mSurfacep); + llassert(x >= 0.f); + llassert(y >= 0.f); - /////////////////////////// - // - // Generate raw data arrays for surface textures - // - // + /////////////////////////// + // + // Generate raw data arrays for surface textures + // + // - // These have already been validated by generateComposition. - U8* st_data[ASSET_COUNT]; - S32 st_data_size[ASSET_COUNT]; // for debugging + // These have already been validated by generateComposition. + U8* st_data[ASSET_COUNT]; + S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; if (use_textures) @@ -645,11 +645,11 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, if (!materialsReady(true, true)) { return FALSE; } } - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (mRawImages[i].isNull()) - { - // Read back a raw image for this discard level, if it exists + for (S32 i = 0; i < ASSET_COUNT; i++) + { + if (mRawImages[i].isNull()) + { + // Read back a raw image for this discard level, if it exists LLViewerFetchedTexture* tex; LLViewerFetchedTexture* tex_emissive; // Can be null bool has_base_color_factor; @@ -721,14 +721,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, raw_emissive = newraw_emissive; } } - if (has_base_color_factor || + if (has_base_color_factor || raw_emissive || has_alpha || tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE || - tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || - tex->getComponents() != 3) - { - LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); + tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || + tex->getComponents() != 3) + { + LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); if (has_alpha) { // Approximate the water underneath terrain alpha with solid water color @@ -738,7 +738,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, MAX_WATER_COLOR.mV[VZ], 255); } - newraw->composite(mRawImagesBaseColor[i]); + newraw->composite(mRawImagesBaseColor[i]); if (has_base_color_factor) { newraw->tint(base_color_factor); @@ -749,8 +749,8 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, newraw->addEmissive(raw_emissive); } - mRawImages[i] = newraw; // deletes old - } + mRawImages[i] = newraw; // deletes old + } if (delete_raw_post) { @@ -764,150 +764,150 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, // Remove intermediary image references mRawImagesBaseColor[i] = nullptr; mRawImagesEmissive[i] = nullptr; - } - st_data[i] = mRawImages[i]->getData(); - st_data_size[i] = mRawImages[i]->getDataSize(); - } - - /////////////////////////////////////// - // - // Generate and clamp x/y bounding box. - // - // - - S32 x_begin, y_begin, x_end, y_end; - x_begin = (S32)(x * mScaleInv); - y_begin = (S32)(y * mScaleInv); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); - - if (x_end > mWidth) - { + } + st_data[i] = mRawImages[i]->getData(); + st_data_size[i] = mRawImages[i]->getDataSize(); + } + + /////////////////////////////////////// + // + // Generate and clamp x/y bounding box. + // + // + + S32 x_begin, y_begin, x_end, y_end; + x_begin = (S32)(x * mScaleInv); + y_begin = (S32)(y * mScaleInv); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { llassert(false); - x_end = mWidth; - } - if (y_end > mWidth) - { + x_end = mWidth; + } + if (y_end > mWidth) + { llassert(false); - y_end = mWidth; - } - - - /////////////////////////////////////////// - // - // Generate target texture information, stride ratios. - // - // - - LLViewerTexture *texturep; - U32 tex_width, tex_height, tex_comps; - U32 tex_stride; - F32 tex_x_scalef, tex_y_scalef; - S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; - F32 tex_x_ratiof, tex_y_ratiof; - - texturep = mSurfacep->getSTexture(); - tex_width = texturep->getWidth(); - tex_height = texturep->getHeight(); - tex_comps = texturep->getComponents(); - tex_stride = tex_width * tex_comps; - - U32 st_comps = 3; - U32 st_width = BASE_SIZE; - U32 st_height = BASE_SIZE; - - if (tex_comps != st_comps) - { + y_end = mWidth; + } + + + /////////////////////////////////////////// + // + // Generate target texture information, stride ratios. + // + // + + LLViewerTexture *texturep; + U32 tex_width, tex_height, tex_comps; + U32 tex_stride; + F32 tex_x_scalef, tex_y_scalef; + S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; + F32 tex_x_ratiof, tex_y_ratiof; + + texturep = mSurfacep->getSTexture(); + tex_width = texturep->getWidth(); + tex_height = texturep->getHeight(); + tex_comps = texturep->getComponents(); + tex_stride = tex_width * tex_comps; + + U32 st_comps = 3; + U32 st_width = BASE_SIZE; + U32 st_height = BASE_SIZE; + + if (tex_comps != st_comps) + { llassert(false); - return FALSE; - } - - tex_x_scalef = (F32)tex_width / (F32)mWidth; - tex_y_scalef = (F32)tex_height / (F32)mWidth; - tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); - tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); - tex_x_end = (S32)((F32)x_end * tex_x_scalef); - tex_y_end = (S32)((F32)y_end * tex_y_scalef); - - tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; - tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; - - LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); - U8 *rawp = raw->getData(); - - F32 st_x_stride, st_y_stride; - st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); - st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); - - llassert(st_x_stride > 0.f); - llassert(st_y_stride > 0.f); - //////////////////////////////// - // - // Iterate through the target texture, striding through the - // subtextures and interpolating appropriately. - // - // - - F32 sti, stj; - S32 st_offset; - sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); - stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); - - st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; - for (S32 j = tex_y_begin; j < tex_y_end; j++) - { - U32 offset = j * tex_stride + tex_x_begin * tex_comps; - sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); - for (S32 i = tex_x_begin; i < tex_x_end; i++) - { - S32 tex0, tex1; - F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); - - tex0 = llfloor( composition ); - tex0 = llclamp(tex0, 0, 3); - composition -= tex0; - tex1 = tex0 + 1; - tex1 = llclamp(tex1, 0, 3); - - st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; - for (U32 k = 0; k < tex_comps; k++) - { - // Linearly interpolate based on composition. - if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) - { - // SJB: This shouldn't be happening, but does... Rounding error? - //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL; - //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL; - } - else - { - F32 a = *(st_data[tex0] + st_offset); - F32 b = *(st_data[tex1] + st_offset); - rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); - } - offset++; - st_offset++; - } - - sti += st_x_stride; - if (sti >= st_width) - { - sti -= st_width; - } - } - - stj += st_y_stride; - if (stj >= st_height) - { - stj -= st_height; - } - } - - if (!texturep->hasGLTexture()) - { - texturep->createGLTexture(0, raw); - } - texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); + return FALSE; + } + + tex_x_scalef = (F32)tex_width / (F32)mWidth; + tex_y_scalef = (F32)tex_height / (F32)mWidth; + tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); + tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); + tex_x_end = (S32)((F32)x_end * tex_x_scalef); + tex_y_end = (S32)((F32)y_end * tex_y_scalef); + + tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; + tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; + + LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); + U8 *rawp = raw->getData(); + + F32 st_x_stride, st_y_stride; + st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); + st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); + + llassert(st_x_stride > 0.f); + llassert(st_y_stride > 0.f); + //////////////////////////////// + // + // Iterate through the target texture, striding through the + // subtextures and interpolating appropriately. + // + // + + F32 sti, stj; + S32 st_offset; + sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); + stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); + + st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; + for (S32 j = tex_y_begin; j < tex_y_end; j++) + { + U32 offset = j * tex_stride + tex_x_begin * tex_comps; + sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); + for (S32 i = tex_x_begin; i < tex_x_end; i++) + { + S32 tex0, tex1; + F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); + + tex0 = llfloor( composition ); + tex0 = llclamp(tex0, 0, 3); + composition -= tex0; + tex1 = tex0 + 1; + tex1 = llclamp(tex1, 0, 3); + + st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; + for (U32 k = 0; k < tex_comps; k++) + { + // Linearly interpolate based on composition. + if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) + { + // SJB: This shouldn't be happening, but does... Rounding error? + //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL; + //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL; + } + else + { + F32 a = *(st_data[tex0] + st_offset); + F32 b = *(st_data[tex1] + st_offset); + rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); + } + offset++; + st_offset++; + } + + sti += st_x_stride; + if (sti >= st_width) + { + sti -= st_width; + } + } + + stj += st_y_stride; + if (stj >= st_height) + { + stj -= st_height; + } + } + + if (!texturep->hasGLTexture()) + { + texturep->createGLTexture(0, raw); + } + texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); // Un-boost detail textures (will get re-boosted if rendering in high detail) for (S32 i = 0; i < ASSET_COUNT; i++) @@ -920,38 +920,38 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { unboost_minimap_material(mDetailMaterials[i]); } - - return TRUE; + + return TRUE; } F32 LLVLComposition::getStartHeight(S32 corner) { - return mStartHeight[corner]; + return mStartHeight[corner]; } void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { - if (id.isNull()) - { + if (id.isNull()) + { return; } LLTerrainMaterials::setDetailAssetID(asset, id); - mRawImages[asset] = NULL; - mRawImagesBaseColor[asset] = NULL; - mRawImagesEmissive[asset] = NULL; + mRawImages[asset] = NULL; + mRawImagesBaseColor[asset] = NULL; + mRawImagesEmissive[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) { - mStartHeight[corner] = start_height; + mStartHeight[corner] = start_height; } F32 LLVLComposition::getHeightRange(S32 corner) { - return mHeightRange[corner]; + return mHeightRange[corner]; } void LLVLComposition::setHeightRange(S32 corner, const F32 range) { - mHeightRange[corner] = range; + mHeightRange[corner] = range; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 5db832e034..e0b08a3aca 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -1,25 +1,25 @@ -/** +/** * @file llvlcomposition.h * @brief Viewer-side representation of a composition layer... * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,13 +40,13 @@ class LLFetchedGLTFMaterial; class LLTerrainMaterials { public: - friend class LLDrawPoolTerrain; + friend class LLDrawPoolTerrain; LLTerrainMaterials(); virtual ~LLTerrainMaterials(); - // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; enum class Type @@ -60,8 +60,8 @@ public: void boost(); - virtual LLUUID getDetailAssetID(S32 asset); - virtual void setDetailAssetID(S32 asset, const LLUUID& id); + virtual LLUUID getDetailAssetID(S32 asset); + virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); bool texturesReady(bool boost, bool strict); // strict = true -> all materials must be sufficiently loaded @@ -74,8 +74,8 @@ protected: // strict = true -> all materials must be sufficiently loaded // strict = false -> at least one material must be loaded static bool materialReady(LLPointer& mat, bool& textures_set, bool boost, bool strict); - LLPointer mDetailTextures[ASSET_COUNT]; - LLPointer mDetailMaterials[ASSET_COUNT]; + LLPointer mDetailTextures[ASSET_COUNT]; + LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; }; @@ -85,63 +85,63 @@ extern LLTerrainMaterials gLocalTerrainMaterials; class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer { public: - // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; - static const LLUUID (&getDefaultTextures())[ASSET_COUNT]; + static const LLUUID (&getDefaultTextures())[ASSET_COUNT]; - LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale); - /*virtual*/ ~LLVLComposition(); + LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale); + /*virtual*/ ~LLVLComposition(); - void setSurface(LLSurface *surfacep); + void setSurface(LLSurface *surfacep); - // Viewer side hack to generate composition values - BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); - BOOL generateComposition(); - // Generate texture from composition values. - BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); + // Viewer side hack to generate composition values + BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); + BOOL generateComposition(); + // Generate texture from composition values. + BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); - // Use these as indeces ito the get/setters below that use 'corner' - enum ECorner - { - SOUTHWEST = 0, - SOUTHEAST = 1, - NORTHWEST = 2, - NORTHEAST = 3, - CORNER_COUNT = 4 - }; + // Use these as indeces ito the get/setters below that use 'corner' + enum ECorner + { + SOUTHWEST = 0, + SOUTHEAST = 1, + NORTHWEST = 2, + NORTHEAST = 3, + CORNER_COUNT = 4 + }; - void setDetailAssetID(S32 asset, const LLUUID& id) override; - F32 getStartHeight(S32 corner); - F32 getHeightRange(S32 corner); + void setDetailAssetID(S32 asset, const LLUUID& id) override; + F32 getStartHeight(S32 corner); + F32 getHeightRange(S32 corner); - void setStartHeight(S32 corner, F32 start_height); - void setHeightRange(S32 corner, F32 range); + void setStartHeight(S32 corner, F32 start_height); + void setHeightRange(S32 corner, F32 range); - friend class LLVOSurfacePatch; - friend class LLDrawPoolTerrain; - void setParamsReady() { mParamsReady = TRUE; } - BOOL getParamsReady() const { return mParamsReady; } + friend class LLVOSurfacePatch; + friend class LLDrawPoolTerrain; + void setParamsReady() { mParamsReady = TRUE; } + BOOL getParamsReady() const { return mParamsReady; } protected: static bool textureReady(LLPointer& tex, bool boost = false); static bool materialReady(LLPointer& mat, bool& textures_set, bool boost = false); - BOOL mParamsReady = FALSE; - LLSurface *mSurfacep; + BOOL mParamsReady = FALSE; + LLSurface *mSurfacep; // Final minimap raw images - LLPointer mRawImages[LLTerrainMaterials::ASSET_COUNT]; + LLPointer mRawImages[LLTerrainMaterials::ASSET_COUNT]; // Only non-null during minimap tile generation - LLPointer mRawImagesBaseColor[LLTerrainMaterials::ASSET_COUNT]; - LLPointer mRawImagesEmissive[LLTerrainMaterials::ASSET_COUNT]; + LLPointer mRawImagesBaseColor[LLTerrainMaterials::ASSET_COUNT]; + LLPointer mRawImagesEmissive[LLTerrainMaterials::ASSET_COUNT]; - F32 mStartHeight[CORNER_COUNT]; - F32 mHeightRange[CORNER_COUNT]; + F32 mStartHeight[CORNER_COUNT]; + F32 mHeightRange[CORNER_COUNT]; - F32 mTexScaleX = 16.f; - F32 mTexScaleY = 16.f; + F32 mTexScaleX = 16.f; + F32 mTexScaleY = 16.f; }; #endif //LL_LLVLCOMPOSITION_H diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d8ac3613bc..0366106aad 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,7 +49,7 @@ #include "llexperiencecache.h" #include "llphysicsmotion.h" #include "llviewercontrol.h" -#include "llcallingcard.h" // IDEVO for LLAvatarTracker +#include "llcallingcard.h" // IDEVO for LLAvatarTracker #include "lldrawpoolavatar.h" #include "lldriverparam.h" #include "llpolyskeletaldistortion.h" @@ -60,7 +60,7 @@ #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llhudnametag.h" -#include "llhudtext.h" // for mText/mDebugText +#include "llhudtext.h" // for mText/mDebugText #include "llimview.h" #include "llinitparam.h" #include "llkeyframefallmotion.h" @@ -141,30 +141,30 @@ using namespace LLAvatarAppearanceDefines; // Global constants //----------------------------------------------------------------------------- const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" -const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" -const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" -const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" +const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" +const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" +const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust" -const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" +const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot" const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix" const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target" -const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" +const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion" //----------------------------------------------------------------------------- // Constants //----------------------------------------------------------------------------- -const F32 DELTA_TIME_MIN = 0.01f; // we clamp measured delta_time to this -const F32 DELTA_TIME_MAX = 0.2f; // range to insure stability of computations. +const F32 DELTA_TIME_MIN = 0.01f; // we clamp measured delta_time to this +const F32 DELTA_TIME_MAX = 0.2f; // range to insure stability of computations. -const F32 PELVIS_LAG_FLYING = 0.22f;// pelvis follow half life while flying -const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking +const F32 PELVIS_LAG_FLYING = 0.22f;// pelvis follow half life while flying +const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking const F32 PELVIS_LAG_MOUSELOOK = 0.15f; const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f; -const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees -const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise. +const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees +const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise. const F32 BREATHE_ROT_MOTION_STRENGTH = 0.05f; @@ -211,9 +211,9 @@ const S32 MIN_NONTUNED_AVS = 5; enum ERenderName { - RENDER_NAME_NEVER, - RENDER_NAME_ALWAYS, - RENDER_NAME_FADE + RENDER_NAME_NEVER, + RENDER_NAME_ALWAYS, + RENDER_NAME_FADE }; #define JELLYDOLLS_SHOULD_IMPOSTOR @@ -224,12 +224,12 @@ enum ERenderName struct LLTextureMaskData { - LLTextureMaskData( const LLUUID& id ) : - mAvatarID(id), - mLastDiscardLevel(S32_MAX) - {} - LLUUID mAvatarID; - S32 mLastDiscardLevel; + LLTextureMaskData( const LLUUID& id ) : + mAvatarID(id), + mLastDiscardLevel(S32_MAX) + {} + LLUUID mAvatarID; + S32 mLastDiscardLevel; }; /********************************************************************************* @@ -241,22 +241,22 @@ struct LLTextureMaskData struct LLAppearanceMessageContents: public LLRefCount { - LLAppearanceMessageContents(): - mAppearanceVersion(-1), - mParamAppearanceVersion(-1), - mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) - { - } - LLTEContents mTEContents; - S32 mAppearanceVersion; - S32 mParamAppearanceVersion; - S32 mCOFVersion; - // For future use: - //U32 appearance_flags = 0; - std::vector mParamWeights; - std::vector mParams; - LLVector3 mHoverOffset; - bool mHoverOffsetWasSet; + LLAppearanceMessageContents(): + mAppearanceVersion(-1), + mParamAppearanceVersion(-1), + mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) + { + } + LLTEContents mTEContents; + S32 mAppearanceVersion; + S32 mParamAppearanceVersion; + S32 mCOFVersion; + // For future use: + //U32 appearance_flags = 0; + std::vector mParamWeights; + std::vector mParams; + LLVector3 mHoverOffset; + bool mHoverOffsetWasSet; }; @@ -264,317 +264,317 @@ struct LLAppearanceMessageContents: public LLRefCount // class LLBodyNoiseMotion //----------------------------------------------------------------------------- class LLBodyNoiseMotion : - public LLMotion + public LLMotion { public: - // Constructor - LLBodyNoiseMotion(const LLUUID &id) - : LLMotion(id) - { - mName = "body_noise"; - mTorsoState = new LLJointState; - } + // Constructor + LLBodyNoiseMotion(const LLUUID &id) + : LLMotion(id) + { + mName = "body_noise"; + mTorsoState = new LLJointState; + } - // Destructor - virtual ~LLBodyNoiseMotion() { } + // Destructor + virtual ~LLBodyNoiseMotion() { } public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); } + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 0.0; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 0.0; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 0.0; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 0.0; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } + virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character) - { - if( !mTorsoState->setJoint( character->getJoint("mTorso") )) - { - return STATUS_FAILURE; - } + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character) + { + if( !mTorsoState->setJoint( character->getJoint("mTorso") )) + { + return STATUS_FAILURE; + } - mTorsoState->setUsage(LLJointState::ROT); + mTorsoState->setUsage(LLJointState::ROT); - addJointState( mTorsoState ); - return STATUS_SUCCESS; - } + addJointState( mTorsoState ); + return STATUS_SUCCESS; + } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate() { return TRUE; } - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask) - { + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - F32 nx[2]; - nx[0]=time*TORSO_NOISE_SPEED; - nx[1]=0.0f; - F32 ny[2]; - ny[0]=0.0f; - ny[1]=time*TORSO_NOISE_SPEED; - F32 noiseX = noise2(nx); - F32 noiseY = noise2(ny); - - F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f; - F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f; - LLQuaternion tQn; - tQn.setQuat( rx, ry, 0.0f ); - mTorsoState->setRotation( tQn ); - - return TRUE; - } - - // called when a motion is deactivated - virtual void onDeactivate() {} + F32 nx[2]; + nx[0]=time*TORSO_NOISE_SPEED; + nx[1]=0.0f; + F32 ny[2]; + ny[0]=0.0f; + ny[1]=time*TORSO_NOISE_SPEED; + F32 noiseX = noise2(nx); + F32 noiseY = noise2(ny); + + F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f; + F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f; + LLQuaternion tQn; + tQn.setQuat( rx, ry, 0.0f ); + mTorsoState->setRotation( tQn ); + + return TRUE; + } + + // called when a motion is deactivated + virtual void onDeactivate() {} private: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LLPointer mTorsoState; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LLPointer mTorsoState; }; //----------------------------------------------------------------------------- // class LLBreatheMotionRot //----------------------------------------------------------------------------- class LLBreatheMotionRot : - public LLMotion + public LLMotion { public: - // Constructor - LLBreatheMotionRot(const LLUUID &id) : - LLMotion(id), - mBreatheRate(1.f), - mCharacter(NULL) - { - mName = "breathe_rot"; - mChestState = new LLJointState; - } - - // Destructor - virtual ~LLBreatheMotionRot() {} + // Constructor + LLBreatheMotionRot(const LLUUID &id) : + LLMotion(id), + mBreatheRate(1.f), + mCharacter(NULL) + { + mName = "breathe_rot"; + mChestState = new LLJointState; + } + + // Destructor + virtual ~LLBreatheMotionRot() {} public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); } + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } - - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } - - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 0.0; } - - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 0.0; } - - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } - - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; } - - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character) - { - mCharacter = character; - BOOL success = true; - - if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) - { - success = false; - } - - if ( success ) - { - mChestState->setUsage(LLJointState::ROT); - addJointState( mChestState ); - } - - if ( success ) - { - return STATUS_SUCCESS; - } - else - { - return STATUS_FAILURE; - } - } - - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask) - { + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } + + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } + + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 0.0; } + + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 0.0; } + + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } + + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; } + + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character) + { + mCharacter = character; + BOOL success = true; + + if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) + { + success = false; + } + + if ( success ) + { + mChestState->setUsage(LLJointState::ROT); + addJointState( mChestState ); + } + + if ( success ) + { + return STATUS_SUCCESS; + } + else + { + return STATUS_FAILURE; + } + } + + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate() { return TRUE; } + + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - mBreatheRate = 1.f; + mBreatheRate = 1.f; - F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH); + F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH); - mChestState->setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f))); + mChestState->setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f))); - return TRUE; - } + return TRUE; + } - // called when a motion is deactivated - virtual void onDeactivate() {} + // called when a motion is deactivated + virtual void onDeactivate() {} private: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LLPointer mChestState; - F32 mBreatheRate; - LLCharacter* mCharacter; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LLPointer mChestState; + F32 mBreatheRate; + LLCharacter* mCharacter; }; //----------------------------------------------------------------------------- // class LLPelvisFixMotion //----------------------------------------------------------------------------- class LLPelvisFixMotion : - public LLMotion + public LLMotion { public: - // Constructor - LLPelvisFixMotion(const LLUUID &id) - : LLMotion(id), mCharacter(NULL) - { - mName = "pelvis_fix"; + // Constructor + LLPelvisFixMotion(const LLUUID &id) + : LLMotion(id), mCharacter(NULL) + { + mName = "pelvis_fix"; - mPelvisState = new LLJointState; - } + mPelvisState = new LLJointState; + } - // Destructor - virtual ~LLPelvisFixMotion() { } + // Destructor + virtual ~LLPelvisFixMotion() { } public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); } + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 0.5f; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 0.5f; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 0.5f; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 0.5f; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character) - { - mCharacter = character; + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character) + { + mCharacter = character; - if (!mPelvisState->setJoint( character->getJoint("mPelvis"))) - { - return STATUS_FAILURE; - } + if (!mPelvisState->setJoint( character->getJoint("mPelvis"))) + { + return STATUS_FAILURE; + } - mPelvisState->setUsage(LLJointState::POS); + mPelvisState->setUsage(LLJointState::POS); - addJointState( mPelvisState ); - return STATUS_SUCCESS; - } + addJointState( mPelvisState ); + return STATUS_SUCCESS; + } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate() { return TRUE; } - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask) - { + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - mPelvisState->setPosition(LLVector3::zero); + mPelvisState->setPosition(LLVector3::zero); - return TRUE; - } + return TRUE; + } - // called when a motion is deactivated - virtual void onDeactivate() {} + // called when a motion is deactivated + virtual void onDeactivate() {} private: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LLPointer mPelvisState; - LLCharacter* mCharacter; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LLPointer mPelvisState; + LLCharacter* mCharacter; }; /** @@ -590,19 +590,19 @@ private: U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited) F32 LLVOAvatar::sRenderDistance = 256.f; -S32 LLVOAvatar::sNumVisibleAvatars = 0; -S32 LLVOAvatar::sNumLODChangesThisFrame = 0; +S32 LLVOAvatar::sNumVisibleAvatars = 0; +S32 LLVOAvatar::sNumLODChangesThisFrame = 0; const LLUUID LLVOAvatar::sStepSoundOnLand("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] = { - SND_STONE_RUBBER, - SND_METAL_RUBBER, - SND_GLASS_RUBBER, - SND_WOOD_RUBBER, - SND_FLESH_RUBBER, - SND_RUBBER_PLASTIC, - SND_RUBBER_RUBBER + SND_STONE_RUBBER, + SND_METAL_RUBBER, + SND_GLASS_RUBBER, + SND_WOOD_RUBBER, + SND_FLESH_RUBBER, + SND_RUBBER_PLASTIC, + SND_RUBBER_RUBBER }; S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS; @@ -632,138 +632,138 @@ static F32 calc_bouncy_animation(F32 x); // LLVOAvatar() //----------------------------------------------------------------------------- LLVOAvatar::LLVOAvatar(const LLUUID& id, - const LLPCode pcode, - LLViewerRegion* regionp) : - LLAvatarAppearance(&gAgentWearables), - LLViewerObject(id, pcode, regionp), - mSpecialRenderMode(0), - mAttachmentSurfaceArea(0.f), - mAttachmentVisibleTriangleCount(0), - mAttachmentEstTriangleCount(0.f), - mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), - mTurning(FALSE), - mLastSkeletonSerialNum( 0 ), - mIsSitting(FALSE), - mTimeVisible(), - mTyping(FALSE), - mMeshValid(FALSE), - mVisible(FALSE), - mLastImpostorUpdateFrameTime(0.f), - mLastImpostorUpdateReason(0), - mWindFreq(0.f), - mRipplePhase( 0.f ), - mBelowWater(FALSE), - mLastAppearanceBlendTime(0.f), - mAppearanceAnimating(FALSE), + const LLPCode pcode, + LLViewerRegion* regionp) : + LLAvatarAppearance(&gAgentWearables), + LLViewerObject(id, pcode, regionp), + mSpecialRenderMode(0), + mAttachmentSurfaceArea(0.f), + mAttachmentVisibleTriangleCount(0), + mAttachmentEstTriangleCount(0.f), + mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), + mTurning(FALSE), + mLastSkeletonSerialNum( 0 ), + mIsSitting(FALSE), + mTimeVisible(), + mTyping(FALSE), + mMeshValid(FALSE), + mVisible(FALSE), + mLastImpostorUpdateFrameTime(0.f), + mLastImpostorUpdateReason(0), + mWindFreq(0.f), + mRipplePhase( 0.f ), + mBelowWater(FALSE), + mLastAppearanceBlendTime(0.f), + mAppearanceAnimating(FALSE), mNameIsSet(false), - mTitle(), - mNameAway(false), - mNameDoNotDisturb(false), - mNameMute(false), - mNameAppearance(false), - mNameFriend(false), - mNameAlpha(0.f), - mRenderGroupTitles(sRenderGroupTitles), - mNameCloud(false), - mFirstTEMessageReceived( FALSE ), - mFirstAppearanceMessageReceived( FALSE ), - mCulled( FALSE ), - mVisibilityRank(0), - mNeedsSkin(FALSE), - mLastSkinTime(0.f), - mUpdatePeriod(1), - mOverallAppearance(AOA_INVISIBLE), - mVisualComplexityStale(true), - mVisuallyMuteSetting(AV_RENDER_NORMALLY), - mMutedAVColor(LLColor4::white /* used for "uninitialize" */), - mFirstFullyVisible(TRUE), - mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY), - mFullyLoaded(FALSE), - mPreviousFullyLoaded(FALSE), - mFullyLoadedInitialized(FALSE), - mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), - mLoadedCallbacksPaused(FALSE), - mLoadedCallbackTextures(0), - mRenderUnloadedAvatar(LLCachedControl(gSavedSettings, "RenderUnloadedAvatar", false)), - mLastRezzedStatus(-1), - mIsEditingAppearance(FALSE), - mUseLocalAppearance(FALSE), - mLastUpdateRequestCOFVersion(-1), - mLastUpdateReceivedCOFVersion(-1), - mCachedMuteListUpdateTime(0), - mCachedInMuteList(false), + mTitle(), + mNameAway(false), + mNameDoNotDisturb(false), + mNameMute(false), + mNameAppearance(false), + mNameFriend(false), + mNameAlpha(0.f), + mRenderGroupTitles(sRenderGroupTitles), + mNameCloud(false), + mFirstTEMessageReceived( FALSE ), + mFirstAppearanceMessageReceived( FALSE ), + mCulled( FALSE ), + mVisibilityRank(0), + mNeedsSkin(FALSE), + mLastSkinTime(0.f), + mUpdatePeriod(1), + mOverallAppearance(AOA_INVISIBLE), + mVisualComplexityStale(true), + mVisuallyMuteSetting(AV_RENDER_NORMALLY), + mMutedAVColor(LLColor4::white /* used for "uninitialize" */), + mFirstFullyVisible(TRUE), + mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY), + mFullyLoaded(FALSE), + mPreviousFullyLoaded(FALSE), + mFullyLoadedInitialized(FALSE), + mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), + mLoadedCallbacksPaused(FALSE), + mLoadedCallbackTextures(0), + mRenderUnloadedAvatar(LLCachedControl(gSavedSettings, "RenderUnloadedAvatar", false)), + mLastRezzedStatus(-1), + mIsEditingAppearance(FALSE), + mUseLocalAppearance(FALSE), + mLastUpdateRequestCOFVersion(-1), + mLastUpdateReceivedCOFVersion(-1), + mCachedMuteListUpdateTime(0), + mCachedInMuteList(false), mIsControlAvatar(false), mIsUIAvatar(false), mEnableDefaultMotions(true) { - LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; + LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; - //VTResume(); // VTune - setHoverOffset(LLVector3(0.0, 0.0, 0.0)); + //VTResume(); // VTune + setHoverOffset(LLVector3(0.0, 0.0, 0.0)); - // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline - const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job - mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim ); + // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline + const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job + mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim ); - LL_DEBUGS("Avatar","Message") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; - mPelvisp = NULL; + LL_DEBUGS("Avatar","Message") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; + mPelvisp = NULL; - mDirtyMesh = 2; // Dirty geometry, need to regenerate. - mMeshTexturesDirty = FALSE; - mHeadp = NULL; + mDirtyMesh = 2; // Dirty geometry, need to regenerate. + mMeshTexturesDirty = FALSE; + mHeadp = NULL; - // set up animation variables - mSpeed = 0.f; - setAnimationData("Speed", &mSpeed); + // set up animation variables + mSpeed = 0.f; + setAnimationData("Speed", &mSpeed); - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 0; - mNeedsAnimUpdate = TRUE; + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 0; + mNeedsAnimUpdate = TRUE; - mNeedsExtentUpdate = true; + mNeedsExtentUpdate = true; - mImpostorDistance = 0; - mImpostorPixelArea = 0; + mImpostorDistance = 0; + mImpostorPixelArea = 0; - setNumTEs(TEX_NUM_INDICES); + setNumTEs(TEX_NUM_INDICES); - mbCanSelect = TRUE; + mbCanSelect = TRUE; - mSignaledAnimations.clear(); - mPlayingAnimations.clear(); + mSignaledAnimations.clear(); + mPlayingAnimations.clear(); - mWasOnGroundLeft = FALSE; - mWasOnGroundRight = FALSE; + mWasOnGroundLeft = FALSE; + mWasOnGroundRight = FALSE; - mTimeLast = 0.0f; - mSpeedAccum = 0.0f; + mTimeLast = 0.0f; + mSpeedAccum = 0.0f; - mRippleTimeLast = 0.f; + mRippleTimeLast = 0.f; - mInAir = FALSE; + mInAir = FALSE; - mStepOnLand = TRUE; - mStepMaterial = 0; + mStepOnLand = TRUE; + mStepMaterial = 0; - mLipSyncActive = false; - mOohMorph = NULL; - mAahMorph = NULL; + mLipSyncActive = false; + mOohMorph = NULL; + mAahMorph = NULL; - mCurrentGesticulationLevel = 0; + mCurrentGesticulationLevel = 0; mFirstAppearanceMessageTimer.reset(); - mRuthTimer.reset(); - mRuthDebugTimer.reset(); - mDebugExistenceTimer.reset(); - mLastAppearanceMessageTimer.reset(); + mRuthTimer.reset(); + mRuthDebugTimer.reset(); + mDebugExistenceTimer.reset(); + mLastAppearanceMessageTimer.reset(); - if(LLSceneMonitor::getInstance()->isEnabled()) - { - LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); - } + if(LLSceneMonitor::getInstance()->isEnabled()) + { + LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); + } - mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID())); + mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID())); } std::string LLVOAvatar::avString() const @@ -774,8 +774,8 @@ std::string LLVOAvatar::avString() const } else { - std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); - return " Avatar '" + getFullname() + "' " + viz_string + " "; + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + return " Avatar '" + getFullname() + "' " + viz_string + " "; } } @@ -788,22 +788,22 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c return; } - LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() - << "sec ]" - << avString() - << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() - << " Notification " << notification_name - << " : " << comment - << LL_ENDL; + LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " Notification " << notification_name + << " : " << comment + << LL_ENDL; - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add(notification_name,args); - } + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add(notification_name,args); + } } //------------------------------------------------------------------------ @@ -811,14 +811,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c //------------------------------------------------------------------------ LLVOAvatar::~LLVOAvatar() { - if (!mFullyLoaded) - { - debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); - } - else - { - debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); - } + if (!mFullyLoaded) + { + debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); + } + else + { + debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); + } if(mTuned) { @@ -828,306 +828,306 @@ LLVOAvatar::~LLVOAvatar() sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end()); - logPendingPhases(); - - LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL; + logPendingPhases(); + + LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL; + + std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); + mAttachmentPoints.clear(); - std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); - mAttachmentPoints.clear(); + mDead = TRUE; - mDead = TRUE; - - mAnimationSources.clear(); - LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + mAnimationSources.clear(); + LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; - getPhases().clearPhases(); - - LL_DEBUGS() << "LLVOAvatar Destructor end" << LL_ENDL; + getPhases().clearPhases(); + + LL_DEBUGS() << "LLVOAvatar Destructor end" << LL_ENDL; } void LLVOAvatar::markDead() { - if (mNameText) - { - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; - } - mVoiceVisualizer->markDead(); - LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; - LLViewerObject::markDead(); + if (mNameText) + { + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + mVoiceVisualizer->markDead(); + LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + LLViewerObject::markDead(); } BOOL LLVOAvatar::isFullyBaked() { - if (mIsDummy) return TRUE; - if (getNumTEs() == 0) return FALSE; + if (mIsDummy) return TRUE; + if (getNumTEs() == 0) return FALSE; - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex) - && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)) - && (i != BAKED_LEFT_ARM) && (i != BAKED_LEFT_LEG) && (i != BAKED_AUX1) && (i != BAKED_AUX2) && (i != BAKED_AUX3)) - { - return FALSE; - } - } - return TRUE; + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex) + && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)) + && (i != BAKED_LEFT_ARM) && (i != BAKED_LEFT_LEG) && (i != BAKED_AUX1) && (i != BAKED_AUX2) && (i != BAKED_AUX3)) + { + return FALSE; + } + } + return TRUE; } BOOL LLVOAvatar::isFullyTextured() const { - for (S32 i = 0; i < mMeshLOD.size(); i++) - { - LLAvatarJoint* joint = mMeshLOD[i]; - if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) - { - continue; // don't care about skirt textures if we're not wearing one. - } - if (!joint) - { - continue; // nonexistent LOD OK. - } - avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin(); - if (meshIter != joint->mMeshParts.end()) - { - LLAvatarJointMesh *mesh = (*meshIter); - if (!mesh) - { - continue; // nonexistent mesh OK - } - if (mesh->hasGLTexture()) - { - continue; // Mesh exists and has a baked texture. - } - if (mesh->hasComposite()) - { - continue; // Mesh exists and has a composite texture. - } - // Fail - return FALSE; - } - } - return TRUE; + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLAvatarJoint* joint = mMeshLOD[i]; + if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) + { + continue; // don't care about skirt textures if we're not wearing one. + } + if (!joint) + { + continue; // nonexistent LOD OK. + } + avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin(); + if (meshIter != joint->mMeshParts.end()) + { + LLAvatarJointMesh *mesh = (*meshIter); + if (!mesh) + { + continue; // nonexistent mesh OK + } + if (mesh->hasGLTexture()) + { + continue; // Mesh exists and has a baked texture. + } + if (mesh->hasComposite()) + { + continue; // Mesh exists and has a composite texture. + } + // Fail + return FALSE; + } + } + return TRUE; } BOOL LLVOAvatar::hasGray() const { - return !getIsCloud() && !isFullyTextured(); + return !getIsCloud() && !isFullyTextured(); } S32 LLVOAvatar::getRezzedStatus() const { - if (getIsCloud()) return 0; - bool textured = isFullyTextured(); - if (textured && allBakedTexturesCompletelyDownloaded()) return 3; - if (textured) return 2; - llassert(hasGray()); - return 1; // gray + if (getIsCloud()) return 0; + bool textured = isFullyTextured(); + if (textured && allBakedTexturesCompletelyDownloaded()) return 3; + if (textured) return 2; + llassert(hasGray()); + return 1; // gray } void LLVOAvatar::deleteLayerSetCaches(bool clearAll) { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (mBakedTextureDatas[i].mTexLayerSet) - { - // ! BACKWARDS COMPATIBILITY ! - // Can be removed after hair baking is mandatory on the grid - if ((i != BAKED_HAIR || isSelf()) && !clearAll) - { - mBakedTextureDatas[i].mTexLayerSet->deleteCaches(); - } - } - if (mBakedTextureDatas[i].mMaskTexName) - { - LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); - mBakedTextureDatas[i].mMaskTexName = 0 ; - } - } -} - -// static + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (mBakedTextureDatas[i].mTexLayerSet) + { + // ! BACKWARDS COMPATIBILITY ! + // Can be removed after hair baking is mandatory on the grid + if ((i != BAKED_HAIR || isSelf()) && !clearAll) + { + mBakedTextureDatas[i].mTexLayerSet->deleteCaches(); + } + } + if (mBakedTextureDatas[i].mMaskTexName) + { + LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); + mBakedTextureDatas[i].mMaskTexName = 0 ; + } + } +} + +// static BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) { - BOOL res = TRUE; - grey_avatars = 0; - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - if( inst->isDead() ) - { - continue; - } - else if( !inst->isFullyBaked() ) - { - res = FALSE; - if (inst->mHasGrey) - { - ++grey_avatars; - } - } - } - return res; + BOOL res = TRUE; + grey_avatars = 0; + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if( inst->isDead() ) + { + continue; + } + else if( !inst->isFullyBaked() ) + { + res = FALSE; + if (inst->mHasGrey) + { + ++grey_avatars; + } + } + } + return res; } // static void LLVOAvatar::getNearbyRezzedStats(std::vector& counts) { - counts.clear(); - counts.resize(4); - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - if (inst) - { - S32 rez_status = inst->getRezzedStatus(); - counts[rez_status]++; - } - } + counts.clear(); + counts.resize(4); + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if (inst) + { + S32 rez_status = inst->getRezzedStatus(); + counts[rez_status]++; + } + } } // static std::string LLVOAvatar::rezStatusToString(S32 rez_status) { - if (rez_status==0) return "cloud"; - if (rez_status==1) return "gray"; - if (rez_status==2) return "downloading"; - if (rez_status==3) return "full"; - return "unknown"; + if (rez_status==0) return "cloud"; + if (rez_status==1) return "gray"; + if (rez_status==2) return "downloading"; + if (rez_status==3) return "full"; + return "unknown"; } // static void LLVOAvatar::dumpBakedStatus() { - LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); - - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - LL_INFOS() << "Avatar "; - - LLNameValue* firstname = inst->getNVPair("FirstName"); - LLNameValue* lastname = inst->getNVPair("LastName"); - - if( firstname ) - { - LL_CONT << firstname->getString(); - } - if( lastname ) - { - LL_CONT << " " << lastname->getString(); - } - - LL_CONT << " " << inst->mID; - - if( inst->isDead() ) - { - LL_CONT << " DEAD ("<< inst->getNumRefs() << " refs)"; - } - - if( inst->isSelf() ) - { - LL_CONT << " (self)"; - } - - - F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).length(); - LL_CONT << " " << dist_to_camera << "m "; - - LL_CONT << " " << inst->mPixelArea << " pixels"; - - if( inst->isVisible() ) - { - LL_CONT << " (visible)"; - } - else - { - LL_CONT << " (not visible)"; - } - - if( inst->isFullyBaked() ) - { - LL_CONT << " Baked"; - } - else - { - LL_CONT << " Unbaked ("; - - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin(); - iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end(); - ++iter) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second; - const ETextureIndex index = baked_dict->mTextureIndex; - if (!inst->isTextureDefined(index)) - { - LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : ""); - } - } - LL_CONT << " ) " << inst->getUnbakedPixelAreaRank(); - if( inst->isCulled() ) - { - LL_CONT << " culled"; - } - } - LL_CONT << LL_ENDL; - } + LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); + + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + LL_INFOS() << "Avatar "; + + LLNameValue* firstname = inst->getNVPair("FirstName"); + LLNameValue* lastname = inst->getNVPair("LastName"); + + if( firstname ) + { + LL_CONT << firstname->getString(); + } + if( lastname ) + { + LL_CONT << " " << lastname->getString(); + } + + LL_CONT << " " << inst->mID; + + if( inst->isDead() ) + { + LL_CONT << " DEAD ("<< inst->getNumRefs() << " refs)"; + } + + if( inst->isSelf() ) + { + LL_CONT << " (self)"; + } + + + F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).length(); + LL_CONT << " " << dist_to_camera << "m "; + + LL_CONT << " " << inst->mPixelArea << " pixels"; + + if( inst->isVisible() ) + { + LL_CONT << " (visible)"; + } + else + { + LL_CONT << " (not visible)"; + } + + if( inst->isFullyBaked() ) + { + LL_CONT << " Baked"; + } + else + { + LL_CONT << " Unbaked ("; + + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin(); + iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end(); + ++iter) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second; + const ETextureIndex index = baked_dict->mTextureIndex; + if (!inst->isTextureDefined(index)) + { + LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : ""); + } + } + LL_CONT << " ) " << inst->getUnbakedPixelAreaRank(); + if( inst->isCulled() ) + { + LL_CONT << " culled"; + } + } + LL_CONT << LL_ENDL; + } } //static void LLVOAvatar::restoreGL() { - if (!isAgentAvatarValid()) return; + if (!isAgentAvatarValid()) return; - gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); - for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++) - { - gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i)); - } - gAgentAvatarp->updateMeshTextures(); + gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); + for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++) + { + gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i)); + } + gAgentAvatarp->updateMeshTextures(); } //static void LLVOAvatar::destroyGL() { - deleteCachedImages(); + deleteCachedImages(); - resetImpostors(); + resetImpostors(); } //static void LLVOAvatar::resetImpostors() { - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* avatar = (LLVOAvatar*) *iter; - avatar->mImpostor.release(); - avatar->mNeedsImpostorUpdate = TRUE; - avatar->mLastImpostorUpdateReason = 1; - } + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* avatar = (LLVOAvatar*) *iter; + avatar->mImpostor.release(); + avatar->mNeedsImpostorUpdate = TRUE; + avatar->mLastImpostorUpdateReason = 1; + } } // static void LLVOAvatar::deleteCachedImages(bool clearAll) -{ - if (LLViewerTexLayerSet::sHasCaches) - { - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - inst->deleteLayerSetCaches(clearAll); - } - LLViewerTexLayerSet::sHasCaches = FALSE; - } - LLVOAvatarSelf::deleteScratchTextures(); - LLTexLayerStaticImageList::getInstance()->deleteCachedImages(); +{ + if (LLViewerTexLayerSet::sHasCaches) + { + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + inst->deleteLayerSetCaches(clearAll); + } + LLViewerTexLayerSet::sHasCaches = FALSE; + } + LLVOAvatarSelf::deleteScratchTextures(); + LLTexLayerStaticImageList::getInstance()->deleteCachedImages(); } @@ -1136,23 +1136,23 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) // LLVOAvatar::initClass() //------------------------------------------------------------------------ void LLVOAvatar::initClass() -{ - gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise"); - gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye"); - gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); - gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); - gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); +{ + gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye"); + gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); + gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); + gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); // Where should this be set initially? LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints")); - LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged); + LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged); sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); } @@ -1165,74 +1165,74 @@ void LLVOAvatar::cleanupClass() // virtual void LLVOAvatar::initInstance() { - //------------------------------------------------------------------------- - // register motions - //------------------------------------------------------------------------- - if (LLCharacter::sInstances.size() == 1) - { - registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create ); - registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create ); - registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create ); - registerMotion( ANIM_AGENT_FEMALE_RUN_NEW, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_FEMALE_WALK_NEW, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_RUN_NEW, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create ); - registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create ); - registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create ); - - // motions without a start/stop bit - registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create ); - registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create ); - registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create ); - registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create ); - registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create ); - registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create ); - registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create ); - registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create ); - registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create ); - registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create ); - registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); - registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); - registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); - } - - LLAvatarAppearance::initInstance(); - - // preload specific motions here - createMotion( ANIM_AGENT_CUSTOMIZE); - createMotion( ANIM_AGENT_CUSTOMIZE_DONE); - - //VTPause(); // VTune - - mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) ); + //------------------------------------------------------------------------- + // register motions + //------------------------------------------------------------------------- + if (LLCharacter::sInstances.size() == 1) + { + registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create ); + registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create ); + registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create ); + registerMotion( ANIM_AGENT_FEMALE_RUN_NEW, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_FEMALE_WALK_NEW, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_RUN_NEW, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create ); + registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create ); + registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create ); + + // motions without a start/stop bit + registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create ); + registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create ); + registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create ); + registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create ); + registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create ); + registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create ); + registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create ); + registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create ); + registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create ); + registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create ); + registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); + registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); + registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); + } + + LLAvatarAppearance::initInstance(); + + // preload specific motions here + createMotion( ANIM_AGENT_CUSTOMIZE); + createMotion( ANIM_AGENT_CUSTOMIZE_DONE); + + //VTPause(); // VTune + + mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) ); mInitFlags |= 1<<1; } @@ -1240,65 +1240,65 @@ void LLVOAvatar::initInstance() // virtual LLAvatarJoint* LLVOAvatar::createAvatarJoint() { - return new LLViewerJoint(); + return new LLViewerJoint(); } // virtual LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num) { - return new LLViewerJoint(joint_num); + return new LLViewerJoint(joint_num); } // virtual LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh() { - return new LLViewerJointMesh(); + return new LLViewerJointMesh(); } // virtual LLTexLayerSet* LLVOAvatar::createTexLayerSet() { - return new LLViewerTexLayerSet(this); + return new LLViewerTexLayerSet(this); } const LLVector3 LLVOAvatar::getRenderPosition() const { - if (mDrawable.isNull() || mDrawable->getGeneration() < 0) - { - return getPositionAgent(); - } - else if (isRoot()) - { - F32 fixup; - if ( hasPelvisFixup( fixup) ) - { - //Apply a pelvis fixup (as defined by the avs skin) - LLVector3 pos = mDrawable->getPositionAgent(); - pos[VZ] += fixup; - return pos; - } - else - { - return mDrawable->getPositionAgent(); - } - } - else - { - return getPosition() * mDrawable->getParent()->getRenderMatrix(); - } + if (mDrawable.isNull() || mDrawable->getGeneration() < 0) + { + return getPositionAgent(); + } + else if (isRoot()) + { + F32 fixup; + if ( hasPelvisFixup( fixup) ) + { + //Apply a pelvis fixup (as defined by the avs skin) + LLVector3 pos = mDrawable->getPositionAgent(); + pos[VZ] += fixup; + return pos; + } + else + { + return mDrawable->getPositionAgent(); + } + } + else + { + return getPosition() * mDrawable->getParent()->getRenderMatrix(); + } } void LLVOAvatar::updateDrawable(BOOL force_damped) { - clearChanged(SHIFTED); + clearChanged(SHIFTED); } void LLVOAvatar::onShift(const LLVector4a& shift_vector) { - const LLVector3& shift = reinterpret_cast(shift_vector); - mLastAnimExtents[0] += shift; - mLastAnimExtents[1] += shift; + const LLVector3& shift = reinterpret_cast(shift_vector); + mLastAnimExtents[0] += shift; + mLastAnimExtents[1] += shift; } void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) @@ -1313,37 +1313,37 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) calculateSpatialExtents(newMin,newMax); mLastAnimExtents[0].set(newMin.getF32ptr()); mLastAnimExtents[1].set(newMax.getF32ptr()); - mLastAnimBasePos = mPelvisp->getWorldPosition(); + mLastAnimBasePos = mPelvisp->getWorldPosition(); mNeedsExtentUpdate = false; } - else - { - LLVector3 new_base_pos = mPelvisp->getWorldPosition(); - LLVector3 shift = new_base_pos-mLastAnimBasePos; - mLastAnimExtents[0] += shift; - mLastAnimExtents[1] += shift; - mLastAnimBasePos = new_base_pos; - - } - - if (isImpostor() && !needsImpostorUpdate()) - { - LLVector3 delta = getRenderPosition() - - ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset)); - - newMin.load3( (mLastAnimExtents[0] + delta).mV); - newMax.load3( (mLastAnimExtents[1] + delta).mV); - } - else - { + else + { + LLVector3 new_base_pos = mPelvisp->getWorldPosition(); + LLVector3 shift = new_base_pos-mLastAnimBasePos; + mLastAnimExtents[0] += shift; + mLastAnimExtents[1] += shift; + mLastAnimBasePos = new_base_pos; + + } + + if (isImpostor() && !needsImpostorUpdate()) + { + LLVector3 delta = getRenderPosition() - + ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset)); + + newMin.load3( (mLastAnimExtents[0] + delta).mV); + newMax.load3( (mLastAnimExtents[1] + delta).mV); + } + else + { newMin.load3(mLastAnimExtents[0].mV); newMax.load3(mLastAnimExtents[1].mV); - LLVector4a pos_group; - pos_group.setAdd(newMin,newMax); - pos_group.mul(0.5f); - mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition(); - mDrawable->setPositionGroup(pos_group); - } + LLVector4a pos_group; + pos_group.setAdd(newMin,newMax); + pos_group.mul(0.5f); + mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition(); + mDrawable->setPositionGroup(pos_group); + } } @@ -1414,8 +1414,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) if (box_detail >= 2) { float max_attachment_span = get_default_max_prim_scale() * 5.0f; - - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) { @@ -1434,7 +1434,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) const LLVOVolume *vol = dynamic_cast(attached_object); if (vol && vol->isAnimatedObject()) { - // Animated objects already have a bounding box in their control av, use that. + // Animated objects already have a bounding box in their control av, use that. // Could lag by a frame if there's no guarantee on order of processing for avatars. LLControlAvatar *cav = vol->getControlAvatar(); if (cav) @@ -1464,10 +1464,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLVector4a max_span(max_attachment_span); S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; - + // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) if (lt == 0x7) { update_min_max(newMin,newMax,ext[0]); @@ -1521,10 +1521,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLVector4a center, size; center.setAdd(newMin, newMax); center.mul(0.5f); - + size.setSub(newMax,newMin); size.mul(0.5f); - + mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); } @@ -1537,24 +1537,24 @@ void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos gGL.diffuseColor3f(visible_color[0], visible_color[1], visible_color[2]); gGL.begin(LLRender::LINES); - gGL.vertex3fv(begin_pos.mV); + gGL.vertex3fv(begin_pos.mV); gGL.vertex3fv(end_pos.mV); gGL.end(); - + // Draw sphere representing joint pos gGL.pushMatrix(); gGL.scalef(sphere_scale, sphere_scale, sphere_scale); gSphere.renderGGL(); gGL.popMatrix(); - + LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); // Occluded bone portions gGL.diffuseColor3f(occ_color[0], occ_color[1], occ_color[2]); gGL.begin(LLRender::LINES); - gGL.vertex3fv(begin_pos.mV); + gGL.vertex3fv(begin_pos.mV); gGL.vertex3fv(end_pos.mV); gGL.end(); @@ -1570,18 +1570,18 @@ void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos //----------------------------------------------------------------------------- void LLVOAvatar::renderCollisionVolumes() { - std::ostringstream ostr; + std::ostringstream ostr; - for (S32 i = 0; i < mNumCollisionVolumes; i++) - { - ostr << mCollisionVolumes[i].getName() << ", "; + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + ostr << mCollisionVolumes[i].getName() << ", "; LLAvatarJointCollisionVolume& collision_volume = mCollisionVolumes[i]; - collision_volume.updateWorldMatrix(); + collision_volume.updateWorldMatrix(); - gGL.pushMatrix(); - gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] ); + gGL.pushMatrix(); + gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] ); LLVector3 begin_pos(0,0,0); LLVector3 end_pos(collision_volume.getEnd()); @@ -1593,7 +1593,7 @@ void LLVOAvatar::renderCollisionVolumes() static LLVector3 RED(1.0f, 0.0f, 0.0f); static LLVector3 PASTEL_RED(1.0f, 0.5f, 0.5f); static LLVector3 WHITE(1.0f, 1.0f, 1.0f); - + LLVector3 cv_color_occluded; LLVector3 cv_color_visible; @@ -1615,20 +1615,20 @@ void LLVOAvatar::renderCollisionVolumes() gGL.popMatrix(); } - - if (mNameText.notNull()) - { - LLVector4a unused; - - mNameText->lineSegmentIntersect(unused, unused, unused, TRUE); - } + + if (mNameText.notNull()) + { + LLVector4a unused; + + mNameText->lineSegmentIntersect(unused, unused, unused, TRUE); + } } void LLVOAvatar::renderBones(const std::string &selected_joint) { LLGLEnable blend(GL_BLEND); - avatar_joint_list_t::iterator iter = mSkeleton.begin(); + avatar_joint_list_t::iterator iter = mSkeleton.begin(); avatar_joint_list_t::iterator end = mSkeleton.end(); // For selected joints @@ -1643,18 +1643,18 @@ void LLVOAvatar::renderBones(const std::string &selected_joint) // For bones not otherwise colored static LLVector3 OTHER_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f); static LLVector3 OTHER_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); - + static F32 SPHERE_SCALEF = 0.001f; - for (; iter != end; ++iter) - { - LLJoint* jointp = *iter; - if (!jointp) - { - continue; - } + for (; iter != end; ++iter) + { + LLJoint* jointp = *iter; + if (!jointp) + { + continue; + } - jointp->updateWorldMatrix(); + jointp->updateWorldMatrix(); LLVector3 occ_color, visible_color; @@ -1692,343 +1692,343 @@ void LLVOAvatar::renderBones(const std::string &selected_joint) LLVector3 begin_pos(0,0,0); LLVector3 end_pos(jointp->getEnd()); - - gGL.pushMatrix(); - gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); + + gGL.pushMatrix(); + gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); render_sphere_and_line(begin_pos, end_pos, sphere_scale, occ_color, visible_color); - - gGL.popMatrix(); - } + + gGL.popMatrix(); + } } void LLVOAvatar::renderJoints() { - std::ostringstream ostr; - std::ostringstream nullstr; + std::ostringstream ostr; + std::ostringstream nullstr; + + for (joint_map_t::iterator iter = mJointMap.begin(); iter != mJointMap.end(); ++iter) + { + LLJoint* jointp = iter->second; + if (!jointp) + { + nullstr << iter->first << " is NULL" << std::endl; + continue; + } - for (joint_map_t::iterator iter = mJointMap.begin(); iter != mJointMap.end(); ++iter) - { - LLJoint* jointp = iter->second; - if (!jointp) - { - nullstr << iter->first << " is NULL" << std::endl; - continue; - } + ostr << jointp->getName() << ", "; - ostr << jointp->getName() << ", "; + jointp->updateWorldMatrix(); - jointp->updateWorldMatrix(); - - gGL.pushMatrix(); - gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); + gGL.pushMatrix(); + gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); - gGL.diffuseColor3f( 1.f, 0.f, 1.f ); - - gGL.begin(LLRender::LINES); - - LLVector3 v[] = - { - LLVector3(1,0,0), - LLVector3(-1,0,0), - LLVector3(0,1,0), - LLVector3(0,-1,0), + gGL.diffuseColor3f( 1.f, 0.f, 1.f ); - LLVector3(0,0,-1), - LLVector3(0,0,1), - }; + gGL.begin(LLRender::LINES); - //sides - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[2].mV); + LLVector3 v[] = + { + LLVector3(1,0,0), + LLVector3(-1,0,0), + LLVector3(0,1,0), + LLVector3(0,-1,0), + + LLVector3(0,0,-1), + LLVector3(0,0,1), + }; - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[3].mV); + //sides + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[3].mV); + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[3].mV); - //top - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[4].mV); - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[4].mV); + //top + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[4].mV); - gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[4].mV); + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[4].mV); - gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[4].mV); + gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[4].mV); + gGL.vertex3fv(v[3].mV); + gGL.vertex3fv(v[4].mV); - //bottom - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[5].mV); - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[5].mV); + //bottom + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[5].mV); - gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[5].mV); + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[5].mV); - gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[5].mV); + gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[5].mV); - gGL.end(); + gGL.vertex3fv(v[3].mV); + gGL.vertex3fv(v[5].mV); - gGL.popMatrix(); - } + gGL.end(); + + gGL.popMatrix(); + } - mDebugText.clear(); - addDebugText(ostr.str()); - addDebugText(nullstr.str()); + mDebugText.clear(); + addDebugText(ostr.str()); + addDebugText(nullstr.str()); } BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face, - BOOL pick_transparent, - BOOL pick_rigged, + S32 face, + BOOL pick_transparent, + BOOL pick_rigged, BOOL pick_unselectable, - S32* face_hit, - LLVector4a* intersection, - LLVector2* tex_coord, - LLVector4a* normal, - LLVector4a* tangent) + S32* face_hit, + LLVector4a* intersection, + LLVector2* tex_coord, + LLVector4a* normal, + LLVector4a* tangent) { - if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar) - { - return FALSE; - } + if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar) + { + return FALSE; + } if (isControlAvatar()) { return FALSE; } - - if (lineSegmentBoundingBox(start, end)) - { - for (S32 i = 0; i < mNumCollisionVolumes; ++i) - { - mCollisionVolumes[i].updateWorldMatrix(); - - glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); - glh::matrix4f inverse = mat.inverse(); - glh::matrix4f norm_mat = inverse.transpose(); - - glh::vec3f p1(start.getF32ptr()); - glh::vec3f p2(end.getF32ptr()); - - inverse.mult_matrix_vec(p1); - inverse.mult_matrix_vec(p2); - - LLVector3 position; - LLVector3 norm; - - if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm)) - { - glh::vec3f res_pos(position.mV); - mat.mult_matrix_vec(res_pos); - - norm.normalize(); - glh::vec3f res_norm(norm.mV); - norm_mat.mult_matrix_dir(res_norm); - - if (intersection) - { - intersection->load3(res_pos.v); - } - - if (normal) - { - normal->load3(res_norm.v); - } - - return TRUE; - } - } - - if (isSelf()) - { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject* attached_object = attachment_iter->get(); - - if (attached_object && !attached_object->isDead() && attachment->getValid()) - { - LLDrawable* drawable = attached_object->mDrawable; - if (drawable->isState(LLDrawable::RIGGED)) - { //regenerate octree for rigged attachment - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED); - } - } - } - } - } - } - - - - LLVector4a position; - if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) - { - if (intersection) - { - *intersection = position; - } - - return TRUE; - } - - return FALSE; -} -// virtual -LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, - S32 face, - BOOL pick_transparent, - BOOL pick_rigged, - BOOL pick_unselectable, - S32* face_hit, - LLVector4a* intersection, - LLVector2* tex_coord, - LLVector4a* normal, - LLVector4a* tangent) -{ - if (isSelf() && !gAgent.needsRenderAvatar()) - { - return NULL; - } - - LLViewerObject* hit = NULL; - - if (lineSegmentBoundingBox(start, end)) - { - LLVector4a local_end = end; - LLVector4a local_intersection; - - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject* attached_object = attachment_iter->get(); - - if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent)) - { - local_end = local_intersection; - if (intersection) - { - *intersection = local_intersection; - } - - hit = attached_object; - } - } - } - } - - return hit; -} + if (lineSegmentBoundingBox(start, end)) + { + for (S32 i = 0; i < mNumCollisionVolumes; ++i) + { + mCollisionVolumes[i].updateWorldMatrix(); + glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); + glh::matrix4f inverse = mat.inverse(); + glh::matrix4f norm_mat = inverse.transpose(); -LLVOAvatar* LLVOAvatar::asAvatar() -{ - return this; -} + glh::vec3f p1(start.getF32ptr()); + glh::vec3f p2(end.getF32ptr()); -//----------------------------------------------------------------------------- -// LLVOAvatar::startDefaultMotions() -//----------------------------------------------------------------------------- -void LLVOAvatar::startDefaultMotions() -{ - //------------------------------------------------------------------------- - // start default motions - //------------------------------------------------------------------------- - startMotion( ANIM_AGENT_HEAD_ROT ); - startMotion( ANIM_AGENT_EYE ); - startMotion( ANIM_AGENT_BODY_NOISE ); - startMotion( ANIM_AGENT_BREATHE_ROT ); - startMotion( ANIM_AGENT_PHYSICS_MOTION ); - startMotion( ANIM_AGENT_HAND_MOTION ); - startMotion( ANIM_AGENT_PELVIS_FIX ); + inverse.mult_matrix_vec(p1); + inverse.mult_matrix_vec(p2); - //------------------------------------------------------------------------- - // restart any currently active motions - //------------------------------------------------------------------------- - processAnimationStateChanges(); -} + LLVector3 position; + LLVector3 norm; -//----------------------------------------------------------------------------- -// LLVOAvatar::buildCharacter() -// Deferred initialization and rebuild of the avatar. -//----------------------------------------------------------------------------- -// virtual -void LLVOAvatar::buildCharacter() -{ - LLAvatarAppearance::buildCharacter(); + if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm)) + { + glh::vec3f res_pos(position.mV); + mat.mult_matrix_vec(res_pos); - // Not done building yet; more to do. - mIsBuilt = FALSE; + norm.normalize(); + glh::vec3f res_norm(norm.mV); + norm_mat.mult_matrix_dir(res_norm); - //------------------------------------------------------------------------- - // set head offset from pelvis - //------------------------------------------------------------------------- - updateHeadOffset(); + if (intersection) + { + intersection->load3(res_pos.v); + } - //------------------------------------------------------------------------- - // initialize lip sync morph pointers - //------------------------------------------------------------------------- - mOohMorph = getVisualParam( "Lipsync_Ooh" ); - mAahMorph = getVisualParam( "Lipsync_Aah" ); + if (normal) + { + normal->load3(res_norm.v); + } - // If we don't have the Ooh morph, use the Kiss morph - if (!mOohMorph) - { - LL_WARNS() << "Missing 'Ooh' morph for lipsync, using fallback." << LL_ENDL; - mOohMorph = getVisualParam( "Express_Kiss" ); - } + return TRUE; + } + } - // If we don't have the Aah morph, use the Open Mouth morph - if (!mAahMorph) - { - LL_WARNS() << "Missing 'Aah' morph for lipsync, using fallback." << LL_ENDL; - mAahMorph = getVisualParam( "Express_Open_Mouth" ); - } + if (isSelf()) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; - // Currently disabled for control avatars (animated objects), enabled for all others. + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + + if (attached_object && !attached_object->isDead() && attachment->getValid()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable->isState(LLDrawable::RIGGED)) + { //regenerate octree for rigged attachment + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED); + } + } + } + } + } + } + + + + LLVector4a position; + if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) + { + if (intersection) + { + *intersection = position; + } + + return TRUE; + } + + return FALSE; +} + +// virtual +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, + S32 face, + BOOL pick_transparent, + BOOL pick_rigged, + BOOL pick_unselectable, + S32* face_hit, + LLVector4a* intersection, + LLVector2* tex_coord, + LLVector4a* normal, + LLVector4a* tangent) +{ + if (isSelf() && !gAgent.needsRenderAvatar()) + { + return NULL; + } + + LLViewerObject* hit = NULL; + + if (lineSegmentBoundingBox(start, end)) + { + LLVector4a local_end = end; + LLVector4a local_intersection; + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + + if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent)) + { + local_end = local_intersection; + if (intersection) + { + *intersection = local_intersection; + } + + hit = attached_object; + } + } + } + } + + return hit; +} + + +LLVOAvatar* LLVOAvatar::asAvatar() +{ + return this; +} + +//----------------------------------------------------------------------------- +// LLVOAvatar::startDefaultMotions() +//----------------------------------------------------------------------------- +void LLVOAvatar::startDefaultMotions() +{ + //------------------------------------------------------------------------- + // start default motions + //------------------------------------------------------------------------- + startMotion( ANIM_AGENT_HEAD_ROT ); + startMotion( ANIM_AGENT_EYE ); + startMotion( ANIM_AGENT_BODY_NOISE ); + startMotion( ANIM_AGENT_BREATHE_ROT ); + startMotion( ANIM_AGENT_PHYSICS_MOTION ); + startMotion( ANIM_AGENT_HAND_MOTION ); + startMotion( ANIM_AGENT_PELVIS_FIX ); + + //------------------------------------------------------------------------- + // restart any currently active motions + //------------------------------------------------------------------------- + processAnimationStateChanges(); +} + +//----------------------------------------------------------------------------- +// LLVOAvatar::buildCharacter() +// Deferred initialization and rebuild of the avatar. +//----------------------------------------------------------------------------- +// virtual +void LLVOAvatar::buildCharacter() +{ + LLAvatarAppearance::buildCharacter(); + + // Not done building yet; more to do. + mIsBuilt = FALSE; + + //------------------------------------------------------------------------- + // set head offset from pelvis + //------------------------------------------------------------------------- + updateHeadOffset(); + + //------------------------------------------------------------------------- + // initialize lip sync morph pointers + //------------------------------------------------------------------------- + mOohMorph = getVisualParam( "Lipsync_Ooh" ); + mAahMorph = getVisualParam( "Lipsync_Aah" ); + + // If we don't have the Ooh morph, use the Kiss morph + if (!mOohMorph) + { + LL_WARNS() << "Missing 'Ooh' morph for lipsync, using fallback." << LL_ENDL; + mOohMorph = getVisualParam( "Express_Kiss" ); + } + + // If we don't have the Aah morph, use the Open Mouth morph + if (!mAahMorph) + { + LL_WARNS() << "Missing 'Aah' morph for lipsync, using fallback." << LL_ENDL; + mAahMorph = getVisualParam( "Express_Open_Mouth" ); + } + + // Currently disabled for control avatars (animated objects), enabled for all others. if (mEnableDefaultMotions) { - startDefaultMotions(); + startDefaultMotions(); } - //------------------------------------------------------------------------- - // restart any currently active motions - //------------------------------------------------------------------------- - processAnimationStateChanges(); + //------------------------------------------------------------------------- + // restart any currently active motions + //------------------------------------------------------------------------- + processAnimationStateChanges(); - mIsBuilt = TRUE; - stop_glerror(); + mIsBuilt = TRUE; + stop_glerror(); - mMeshValid = TRUE; + mMeshValid = TRUE; } //----------------------------------------------------------------------------- @@ -2036,30 +2036,30 @@ void LLVOAvatar::buildCharacter() //----------------------------------------------------------------------------- void LLVOAvatar::resetVisualParams() { - // Skeletal params - { - LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); - iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); - ++iter) - { - LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter; - LLPolySkeletalDistortion *param = dynamic_cast(getVisualParam(info->getID())); + // Skeletal params + { + LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; + for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); + iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); + ++iter) + { + LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter; + LLPolySkeletalDistortion *param = dynamic_cast(getVisualParam(info->getID())); *param = LLPolySkeletalDistortion(this); llassert(param); - if (!param->setInfo(info)) - { - llassert(false); - } - } - } - - // Driver parameters - for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); - iter != sAvatarXmlInfo->mDriverInfoList.end(); - ++iter) - { - LLDriverParamInfo *info = *iter; + if (!param->setInfo(info)) + { + llassert(false); + } + } + } + + // Driver parameters + for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); + iter != sAvatarXmlInfo->mDriverInfoList.end(); + ++iter) + { + LLDriverParamInfo *info = *iter; LLDriverParam *param = dynamic_cast(getVisualParam(info->getID())); LLDriverParam::entry_list_t driven_list = param->getDrivenList(); *param = LLDriverParam(this); @@ -2067,41 +2067,41 @@ void LLVOAvatar::resetVisualParams() if (!param->setInfo(info)) { llassert(false); - } + } param->setDrivenList(driven_list); - } + } } void LLVOAvatar::applyDefaultParams() { - // These are params from avs with newly created copies of shape, - // skin, hair, eyes, plus gender set as noted. Run arche_tool.py - // to get params from some other xml appearance dump. - std::map male_params = { - {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} - }; - std::map female_params = { - {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} - }; - std::map *params = NULL; - if (getSex() == SEX_MALE) - params = &male_params; - else - params = &female_params; - - for( auto it = params->begin(); it != params->end(); ++it) - { - LLVisualParam* param = getVisualParam(it->first); - if( !param ) - { - // invalid id - break; - } - - U8 value = it->second; - F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); - param->setWeight(newWeight); - } + // These are params from avs with newly created copies of shape, + // skin, hair, eyes, plus gender set as noted. Run arche_tool.py + // to get params from some other xml appearance dump. + std::map male_params = { + {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} + }; + std::map female_params = { + {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} + }; + std::map *params = NULL; + if (getSex() == SEX_MALE) + params = &male_params; + else + params = &female_params; + + for( auto it = params->begin(); it != params->end(); ++it) + { + LLVisualParam* param = getVisualParam(it->first); + if( !param ) + { + // invalid id + break; + } + + U8 value = it->second; + F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); + param->setWeight(newWeight); + } } //----------------------------------------------------------------------------- @@ -2127,10 +2127,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) // just to get the right scale for the collision volumes, because // this will be used in setting the mJointScales for the // LLPolySkeletalDistortions of which the CVs are children. - if( !buildSkeleton(sAvatarSkeletonInfo) ) + if( !buildSkeleton(sAvatarSkeletonInfo) ) { LL_ERRS() << "Error resetting skeleton" << LL_ENDL; - } + } // Reset some params to default state, without propagating changes downstream. resetVisualParams(); @@ -2138,10 +2138,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) // Now we have to reset the skeleton again, because its state // got clobbered by the resetVisualParams() calls // above. - if( !buildSkeleton(sAvatarSkeletonInfo) ) + if( !buildSkeleton(sAvatarSkeletonInfo) ) { LL_ERRS() << "Error resetting skeleton" << LL_ENDL; - } + } // Reset attachment points // BuildSkeleton only does bones and CVs but we still need to reinit huds @@ -2150,7 +2150,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) initAttachmentPoints(ignore_hud_joints); // Fix up collision volumes - for (LLVisualParam *param = getFirstVisualParam(); + for (LLVisualParam *param = getFirstVisualParam(); param; param = getNextVisualParam()) { @@ -2166,30 +2166,30 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) } // Reset tweakable params to preserved state - if (getOverallAppearance() == AOA_NORMAL) - { - if (mLastProcessedAppearance) - { - bool slam_params = true; - applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); - } - } - else - { - // Stripped down approximation of - // applyParsedAppearanceMessage, but with alternative default - // (jellydoll) params - setCompositeUpdatesEnabled( FALSE ); - gPipeline.markGLRebuild(this); - applyDefaultParams(); - setCompositeUpdatesEnabled( TRUE ); - updateMeshTextures(); - updateMeshVisibility(); - } + if (getOverallAppearance() == AOA_NORMAL) + { + if (mLastProcessedAppearance) + { + bool slam_params = true; + applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); + } + } + else + { + // Stripped down approximation of + // applyParsedAppearanceMessage, but with alternative default + // (jellydoll) params + setCompositeUpdatesEnabled( FALSE ); + gPipeline.markGLRebuild(this); + applyDefaultParams(); + setCompositeUpdatesEnabled( TRUE ); + updateMeshTextures(); + updateMeshVisibility(); + } updateVisualParams(); // Restore attachment pos overrides - updateAttachmentOverrides(); + updateAttachmentOverrides(); // Animations if (reset_animations) @@ -2207,7 +2207,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) resetAnimations(); } } - + LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL; } @@ -2216,49 +2216,49 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) //----------------------------------------------------------------------------- void LLVOAvatar::releaseMeshData() { - if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || isUIAvatar()) - { - return; - } - - // cleanup mesh data - for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); - iter != mMeshLOD.end(); - ++iter) - { - LLAvatarJoint* joint = (*iter); - joint->setValid(FALSE, TRUE); - } - - //cleanup data - if (mDrawable.notNull()) - { - LLFace* facep = mDrawable->getFace(0); - if (facep) - { - facep->setSize(0, 0); - for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) - { - facep = mDrawable->getFace(i); - if (facep) - { - facep->setSize(0, 0); - } - } - } - } - - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (!attachment->getIsHUDAttachment()) - { - attachment->setAttachmentVisibility(FALSE); - } - } - mMeshValid = FALSE; + if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || isUIAvatar()) + { + return; + } + + // cleanup mesh data + for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); + iter != mMeshLOD.end(); + ++iter) + { + LLAvatarJoint* joint = (*iter); + joint->setValid(FALSE, TRUE); + } + + //cleanup data + if (mDrawable.notNull()) + { + LLFace* facep = mDrawable->getFace(0); + if (facep) + { + facep->setSize(0, 0); + for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) + { + facep = mDrawable->getFace(i); + if (facep) + { + facep->setSize(0, 0); + } + } + } + } + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (!attachment->getIsHUDAttachment()) + { + attachment->setAttachmentVisibility(FALSE); + } + } + mMeshValid = FALSE; } //----------------------------------------------------------------------------- @@ -2267,29 +2267,29 @@ void LLVOAvatar::releaseMeshData() // virtual void LLVOAvatar::restoreMeshData() { - llassert(!isSelf()); + llassert(!isSelf()); if (mDrawable.isNull()) { return; } - - //LL_INFOS() << "Restoring" << LL_ENDL; - mMeshValid = TRUE; - updateJointLODs(); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (!attachment->getIsHUDAttachment()) - { - attachment->setAttachmentVisibility(TRUE); - } - } + //LL_INFOS() << "Restoring" << LL_ENDL; + mMeshValid = TRUE; + updateJointLODs(); + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (!attachment->getIsHUDAttachment()) + { + attachment->setAttachmentVisibility(TRUE); + } + } - // force mesh update as LOD might not have changed to trigger this - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + // force mesh update as LOD might not have changed to trigger this + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); } //----------------------------------------------------------------------------- @@ -2297,149 +2297,149 @@ void LLVOAvatar::restoreMeshData() //----------------------------------------------------------------------------- void LLVOAvatar::updateMeshData() { - if (mDrawable.notNull()) - { - stop_glerror(); - - S32 f_num = 0 ; - const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. - const S32 num_parts = mMeshLOD.size(); - - // this order is determined by number of LODS - // if a mesh earlier in this list changed LODs while a later mesh doesn't, - // the later mesh's index offset will be inaccurate - for(S32 part_index = 0 ; part_index < num_parts ;) - { - S32 j = part_index ; - U32 last_v_num = 0, num_vertices = 0 ; - U32 last_i_num = 0, num_indices = 0 ; - - while(part_index < num_parts && num_vertices < VERTEX_NUMBER_THRESHOLD) - { - last_v_num = num_vertices ; - last_i_num = num_indices ; - - LLViewerJoint* part_mesh = getViewerJoint(part_index++); - if (part_mesh) - { - part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); - } - } - if(num_vertices < 1)//skip empty meshes - { - continue ; - } - if(last_v_num > 0)//put the last inserted part into next vertex buffer. - { - num_vertices = last_v_num ; - num_indices = last_i_num ; - part_index-- ; - } - - LLFace* facep = NULL; - if(f_num < mDrawable->getNumFaces()) - { - facep = mDrawable->getFace(f_num); - } - else - { - facep = mDrawable->getFace(0); - if (facep) - { - facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ; - } - } - if (!facep) continue; - - // resize immediately - facep->setSize(num_vertices, num_indices); - - bool terse_update = false; - - facep->setGeomIndex(0); - facep->setIndicesIndex(0); - - LLVertexBuffer* buff = facep->getVertexBuffer(); - if(!facep->getVertexBuffer()) - { + if (mDrawable.notNull()) + { + stop_glerror(); + + S32 f_num = 0 ; + const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. + const S32 num_parts = mMeshLOD.size(); + + // this order is determined by number of LODS + // if a mesh earlier in this list changed LODs while a later mesh doesn't, + // the later mesh's index offset will be inaccurate + for(S32 part_index = 0 ; part_index < num_parts ;) + { + S32 j = part_index ; + U32 last_v_num = 0, num_vertices = 0 ; + U32 last_i_num = 0, num_indices = 0 ; + + while(part_index < num_parts && num_vertices < VERTEX_NUMBER_THRESHOLD) + { + last_v_num = num_vertices ; + last_i_num = num_indices ; + + LLViewerJoint* part_mesh = getViewerJoint(part_index++); + if (part_mesh) + { + part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); + } + } + if(num_vertices < 1)//skip empty meshes + { + continue ; + } + if(last_v_num > 0)//put the last inserted part into next vertex buffer. + { + num_vertices = last_v_num ; + num_indices = last_i_num ; + part_index-- ; + } + + LLFace* facep = NULL; + if(f_num < mDrawable->getNumFaces()) + { + facep = mDrawable->getFace(f_num); + } + else + { + facep = mDrawable->getFace(0); + if (facep) + { + facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ; + } + } + if (!facep) continue; + + // resize immediately + facep->setSize(num_vertices, num_indices); + + bool terse_update = false; + + facep->setGeomIndex(0); + facep->setIndicesIndex(0); + + LLVertexBuffer* buff = facep->getVertexBuffer(); + if(!facep->getVertexBuffer()) + { buff = new LLVertexBuffer(LLDrawPoolAvatar::VERTEX_DATA_MASK); - if (!buff->allocateBuffer(num_vertices, num_indices)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to " - << num_vertices << " vertices and " - << num_indices << " indices" << LL_ENDL; - // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) - facep->setSize(1, 3); - buff->allocateBuffer(1, 3); - memset((U8*) buff->getMappedData(), 0, buff->getSize()); - memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); - } - facep->setVertexBuffer(buff); - } - else - { - if (buff->getNumIndices() == num_indices && - buff->getNumVerts() == num_vertices) - { - terse_update = true; - } - else - { + if (!buff->allocateBuffer(num_vertices, num_indices)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to " + << num_vertices << " vertices and " + << num_indices << " indices" << LL_ENDL; + // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) + facep->setSize(1, 3); + buff->allocateBuffer(1, 3); + memset((U8*) buff->getMappedData(), 0, buff->getSize()); + memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); + } + facep->setVertexBuffer(buff); + } + else + { + if (buff->getNumIndices() == num_indices && + buff->getNumVerts() == num_vertices) + { + terse_update = true; + } + else + { buff = new LLVertexBuffer(buff->getTypeMask()); if (!buff->allocateBuffer(num_vertices, num_indices)) { - LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL; - // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) - facep->setSize(1, 3); - buff->allocateBuffer(1, 3); - memset((U8*) buff->getMappedData(), 0, buff->getSize()); - memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); - } - } - } - - - // This is a hack! Avatars have their own pool, so we are detecting - // the case of more than one avatar in the pool (thus > 0 instead of >= 0) - if (facep->getGeomIndex() > 0) - { - LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL; - } - - if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices()) - { - for(S32 k = j ; k < part_index ; k++) - { - bool rigid = false; - if (k == MESH_ID_EYEBALL_LEFT || - k == MESH_ID_EYEBALL_RIGHT) - { - //eyeballs can't have terse updates since they're never rendered with - //the hardware skinning shader - rigid = true; - } - - LLViewerJoint* mesh = getViewerJoint(k); - if (mesh) - { - mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); - } - } - } - - stop_glerror(); - buff->unmapBuffer(); - - if(!f_num) - { - f_num += mNumInitFaces ; - } - else - { - f_num++ ; - } - } - } + LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL; + // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) + facep->setSize(1, 3); + buff->allocateBuffer(1, 3); + memset((U8*) buff->getMappedData(), 0, buff->getSize()); + memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); + } + } + } + + + // This is a hack! Avatars have their own pool, so we are detecting + // the case of more than one avatar in the pool (thus > 0 instead of >= 0) + if (facep->getGeomIndex() > 0) + { + LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL; + } + + if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices()) + { + for(S32 k = j ; k < part_index ; k++) + { + bool rigid = false; + if (k == MESH_ID_EYEBALL_LEFT || + k == MESH_ID_EYEBALL_RIGHT) + { + //eyeballs can't have terse updates since they're never rendered with + //the hardware skinning shader + rigid = true; + } + + LLViewerJoint* mesh = getViewerJoint(k); + if (mesh) + { + mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); + } + } + } + + stop_glerror(); + buff->unmapBuffer(); + + if(!f_num) + { + f_num += mNumInitFaces ; + } + else + { + f_num++ ; + } + } + } } //------------------------------------------------------------------------ @@ -2448,78 +2448,78 @@ void LLVOAvatar::updateMeshData() // LLVOAvatar::processUpdateMessage() //------------------------------------------------------------------------ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, const EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, const EObjectUpdateType update_type, + LLDataPacker *dp) { - const BOOL has_name = !getNVPair("FirstName"); + const BOOL has_name = !getNVPair("FirstName"); - // Do base class updates... - U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + // Do base class updates... + U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - // Print out arrival information once we have name of avatar. + // Print out arrival information once we have name of avatar. if (has_name && getNVPair("FirstName")) { mDebugExistenceTimer.reset(); debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); } - if(retval & LLViewerObject::INVALID_UPDATE) - { - if (isSelf()) - { - //tell sim to cancel this update - gAgent.teleportViaLocation(gAgent.getPositionGlobal()); - } - } + if(retval & LLViewerObject::INVALID_UPDATE) + { + if (isSelf()) + { + //tell sim to cancel this update + gAgent.teleportViaLocation(gAgent.getPositionGlobal()); + } + } - return retval; + return retval; } LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid) { - LLViewerFetchedTexture *result = NULL; - - if (uuid == IMG_DEFAULT_AVATAR || - uuid == IMG_DEFAULT || - uuid == IMG_INVISIBLE) - { - // Should already exist, don't need to find it on sim or baked-texture host. - result = gTextureList.findImage(uuid, TEX_LIST_STANDARD); - } - if (!result) - { - const std::string url = getImageURL(te,uuid); - - if (url.empty()) - { - LL_WARNS() << "unable to determine URL for te " << te << " uuid " << uuid << LL_ENDL; - return NULL; - } - LL_DEBUGS("Avatar") << avString() << "get server-bake image from URL " << url << LL_ENDL; - result = LLViewerTextureManager::getFetchedTextureFromUrl( - url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); - if (result->isMissingAsset()) - { - result->setIsMissingAsset(false); - } - - } - return result; + LLViewerFetchedTexture *result = NULL; + + if (uuid == IMG_DEFAULT_AVATAR || + uuid == IMG_DEFAULT || + uuid == IMG_INVISIBLE) + { + // Should already exist, don't need to find it on sim or baked-texture host. + result = gTextureList.findImage(uuid, TEX_LIST_STANDARD); + } + if (!result) + { + const std::string url = getImageURL(te,uuid); + + if (url.empty()) + { + LL_WARNS() << "unable to determine URL for te " << te << " uuid " << uuid << LL_ENDL; + return NULL; + } + LL_DEBUGS("Avatar") << avString() << "get server-bake image from URL " << url << LL_ENDL; + result = LLViewerTextureManager::getFetchedTextureFromUrl( + url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); + if (result->isMissingAsset()) + { + result->setIsMissingAsset(false); + } + + } + return result; } // virtual S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) { - if (!isIndexBakedTexture((ETextureIndex)te)) - { - // Sim still sends some uuids for non-baked slots sometimes - ignore. - return LLViewerObject::setTETexture(te, LLUUID::null); - } + if (!isIndexBakedTexture((ETextureIndex)te)) + { + // Sim still sends some uuids for non-baked slots sometimes - ignore. + return LLViewerObject::setTETexture(te, LLUUID::null); + } - LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid); - llassert(image); - return setTETextureCore(te, image); + LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid); + llassert(image); + return setTETextureCore(te, image); } //------------------------------------------------------------------------ @@ -2527,26 +2527,26 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) //------------------------------------------------------------------------ void LLVOAvatar::dumpAnimationState() { - LL_INFOS() << "==============================================" << LL_ENDL; - for (LLVOAvatar::AnimIterator it = mSignaledAnimations.begin(); it != mSignaledAnimations.end(); ++it) - { - LLUUID id = it->first; - std::string playtag = ""; - if (mPlayingAnimations.find(id) != mPlayingAnimations.end()) - { - playtag = "*"; - } - LL_INFOS() << gAnimLibrary.animationName(id) << playtag << LL_ENDL; - } - for (LLVOAvatar::AnimIterator it = mPlayingAnimations.begin(); it != mPlayingAnimations.end(); ++it) - { - LLUUID id = it->first; - bool is_signaled = mSignaledAnimations.find(id) != mSignaledAnimations.end(); - if (!is_signaled) - { - LL_INFOS() << gAnimLibrary.animationName(id) << "!S" << LL_ENDL; - } - } + LL_INFOS() << "==============================================" << LL_ENDL; + for (LLVOAvatar::AnimIterator it = mSignaledAnimations.begin(); it != mSignaledAnimations.end(); ++it) + { + LLUUID id = it->first; + std::string playtag = ""; + if (mPlayingAnimations.find(id) != mPlayingAnimations.end()) + { + playtag = "*"; + } + LL_INFOS() << gAnimLibrary.animationName(id) << playtag << LL_ENDL; + } + for (LLVOAvatar::AnimIterator it = mPlayingAnimations.begin(); it != mPlayingAnimations.end(); ++it) + { + LLUUID id = it->first; + bool is_signaled = mSignaledAnimations.find(id) != mSignaledAnimations.end(); + if (!is_signaled) + { + LL_INFOS() << gAnimLibrary.animationName(id) << "!S" << LL_ENDL; + } + } } //------------------------------------------------------------------------ @@ -2556,127 +2556,127 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (isDead()) - { - LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL; - return; - } + if (isDead()) + { + LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL; + return; + } // record time and refresh "tooSlow" status updateTooSlow(); - static LLCachedControl disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); - if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)) - && !disable_all_render_types && !isSelf()) - { + static LLCachedControl disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); + if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)) + && !disable_all_render_types && !isSelf()) + { if (!mIsControlAvatar) { idleUpdateNameTag(idleCalcNameTagPosition(mLastRootPos)); } - return; - } + return; + } // Update should be happening max once per frame. - if ((mLastAnimExtents[0]==LLVector3())|| - (mLastAnimExtents[1])==LLVector3()) - { - mNeedsExtentUpdate = true; - } - else - { - const S32 upd_freq = 4; // force update every upd_freq frames. - mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0); - } - + if ((mLastAnimExtents[0]==LLVector3())|| + (mLastAnimExtents[1])==LLVector3()) + { + mNeedsExtentUpdate = true; + } + else + { + const S32 upd_freq = 4; // force update every upd_freq frames. + mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0); + } + LLScopedContextString str("avatar_idle_update " + getFullname()); - - checkTextureLoading() ; - - // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) - setPixelAreaAndAngle(gAgent); - - // force asynchronous drawable update - if(mDrawable.notNull()) - { - if (isSitting() && getParent()) - { - LLViewerObject *root_object = (LLViewerObject*)getRoot(); - LLDrawable* drawablep = root_object->mDrawable; - // if this object hasn't already been updated by another avatar... - if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE)) - { - if (root_object->isSelected()) - { - gPipeline.updateMoveNormalAsync(drawablep); - } - else - { - gPipeline.updateMoveDampedAsync(drawablep); - } - } - } - else - { - gPipeline.updateMoveDampedAsync(mDrawable); - } - } - - //-------------------------------------------------------------------- - // set alpha flag depending on state - //-------------------------------------------------------------------- - - if (isSelf()) - { - LLViewerObject::idleUpdate(agent, time); - - // trigger fidget anims - if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS)) - { - agent.fidget(); - } - } - else - { - // Should override the idleUpdate stuff and leave out the angular update part. - LLQuaternion rotation = getRotation(); - LLViewerObject::idleUpdate(agent, time); - setRotation(rotation); - } - - // attach objects that were waiting for a drawable - lazyAttach(); - - // animate the character - // store off last frame's root position to be consistent with camera position - mLastRootPos = mRoot->getWorldPosition(); - BOOL detailed_update = updateCharacter(agent); - - static LLUICachedControl visualizers_in_calls("ShowVoiceVisualizersInCalls", false); - bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) && - LLVoiceClient::getInstance()->getVoiceEnabled(mID); - LLVector3 hud_name_pos = idleCalcNameTagPosition(mLastRootPos); + checkTextureLoading() ; - idleUpdateVoiceVisualizer(voice_enabled, hud_name_pos); - idleUpdateMisc( detailed_update ); - idleUpdateAppearanceAnimation(); - if (detailed_update) - { - idleUpdateLipSync( voice_enabled ); - idleUpdateLoadingEffect(); - idleUpdateBelowWater(); // wind effect uses this - idleUpdateWindEffect(); - } - - idleUpdateNameTag(hud_name_pos); + // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) + setPixelAreaAndAngle(gAgent); - // Complexity has stale mechanics, but updates still can be very rapid - // so spread avatar complexity calculations over frames to lesen load from - // rapid updates and to make sure all avatars are not calculated at once. - S32 compl_upd_freq = 20; - if (isControlAvatar()) + // force asynchronous drawable update + if(mDrawable.notNull()) { - // animeshes do not (or won't) have impostors nor change outfis, - // no need for high frequency + if (isSitting() && getParent()) + { + LLViewerObject *root_object = (LLViewerObject*)getRoot(); + LLDrawable* drawablep = root_object->mDrawable; + // if this object hasn't already been updated by another avatar... + if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE)) + { + if (root_object->isSelected()) + { + gPipeline.updateMoveNormalAsync(drawablep); + } + else + { + gPipeline.updateMoveDampedAsync(drawablep); + } + } + } + else + { + gPipeline.updateMoveDampedAsync(mDrawable); + } + } + + //-------------------------------------------------------------------- + // set alpha flag depending on state + //-------------------------------------------------------------------- + + if (isSelf()) + { + LLViewerObject::idleUpdate(agent, time); + + // trigger fidget anims + if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS)) + { + agent.fidget(); + } + } + else + { + // Should override the idleUpdate stuff and leave out the angular update part. + LLQuaternion rotation = getRotation(); + LLViewerObject::idleUpdate(agent, time); + setRotation(rotation); + } + + // attach objects that were waiting for a drawable + lazyAttach(); + + // animate the character + // store off last frame's root position to be consistent with camera position + mLastRootPos = mRoot->getWorldPosition(); + BOOL detailed_update = updateCharacter(agent); + + static LLUICachedControl visualizers_in_calls("ShowVoiceVisualizersInCalls", false); + bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) && + LLVoiceClient::getInstance()->getVoiceEnabled(mID); + + LLVector3 hud_name_pos = idleCalcNameTagPosition(mLastRootPos); + + idleUpdateVoiceVisualizer(voice_enabled, hud_name_pos); + idleUpdateMisc( detailed_update ); + idleUpdateAppearanceAnimation(); + if (detailed_update) + { + idleUpdateLipSync( voice_enabled ); + idleUpdateLoadingEffect(); + idleUpdateBelowWater(); // wind effect uses this + idleUpdateWindEffect(); + } + + idleUpdateNameTag(hud_name_pos); + + // Complexity has stale mechanics, but updates still can be very rapid + // so spread avatar complexity calculations over frames to lesen load from + // rapid updates and to make sure all avatars are not calculated at once. + S32 compl_upd_freq = 20; + if (isControlAvatar()) + { + // animeshes do not (or won't) have impostors nor change outfis, + // no need for high frequency compl_upd_freq = 100; } else if (mLastRezzedStatus <= 0) //cloud or init @@ -2698,7 +2698,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0) { - // DEPRECATED + // DEPRECATED // replace with LLPipeline::profileAvatar? // Avatar profile takes ~ 0.5ms while idleUpdateRenderComplexity takes ~5ms // (both are unacceptably costly) @@ -2709,96 +2709,96 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled, const LLVector3 &position) { - bool render_visualizer = voice_enabled; - - // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled. - if(isSelf()) - { + bool render_visualizer = voice_enabled; + + // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled. + if(isSelf()) + { static LLCachedControl voice_disable_mic(gSavedSettings, "VoiceDisableMic"); - if(gAgentCamera.cameraMouselook() || voice_disable_mic) - { - render_visualizer = false; - } - } - - mVoiceVisualizer->setVoiceEnabled(render_visualizer); - - if ( voice_enabled ) - { - //---------------------------------------------------------------- - // Only do gesture triggering for your own avatar, and only when you're in a proximal channel. - //---------------------------------------------------------------- - if( isSelf() ) - { - //---------------------------------------------------------------------------------------- - // The following takes the voice signal and uses that to trigger gesticulations. - //---------------------------------------------------------------------------------------- - int lastGesticulationLevel = mCurrentGesticulationLevel; - mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel(); - - //--------------------------------------------------------------------------------------------------- - // If "current gesticulation level" changes, we catch this, and trigger the new gesture - //--------------------------------------------------------------------------------------------------- - if ( lastGesticulationLevel != mCurrentGesticulationLevel ) - { - if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF ) - { - std::string gestureString = "unInitialized"; - if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; } - else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; } - else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; } - else { LL_INFOS() << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << LL_ENDL; } - - // this is the call that Karl S. created for triggering gestures from within the code. - LLGestureMgr::instance().triggerAndReviseString( gestureString ); - } - } - - } //if( isSelf() ) - - //----------------------------------------------------------------------------------------------------------------- - // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer. - // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol. - // - // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been - // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. - //----------------------------------------------------------------------------------------------------------------- - if (LLVoiceClient::getInstance()->getIsSpeaking( mID )) - { - if (!mVoiceVisualizer->getCurrentlySpeaking()) - { - mVoiceVisualizer->setStartSpeaking(); - - //printf( "gAwayTimer.reset();\n" ); - } - - mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) ); - - if( isSelf() ) - { - gAgent.clearAFK(); - } - } - else - { - if ( mVoiceVisualizer->getCurrentlySpeaking() ) - { - mVoiceVisualizer->setStopSpeaking(); - - if ( mLipSyncActive ) - { - if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight()); - if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight()); - - mLipSyncActive = false; - LLCharacter::updateVisualParams(); - dirtyMesh(); - } - } - } + if(gAgentCamera.cameraMouselook() || voice_disable_mic) + { + render_visualizer = false; + } + } + + mVoiceVisualizer->setVoiceEnabled(render_visualizer); + + if ( voice_enabled ) + { + //---------------------------------------------------------------- + // Only do gesture triggering for your own avatar, and only when you're in a proximal channel. + //---------------------------------------------------------------- + if( isSelf() ) + { + //---------------------------------------------------------------------------------------- + // The following takes the voice signal and uses that to trigger gesticulations. + //---------------------------------------------------------------------------------------- + int lastGesticulationLevel = mCurrentGesticulationLevel; + mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel(); + + //--------------------------------------------------------------------------------------------------- + // If "current gesticulation level" changes, we catch this, and trigger the new gesture + //--------------------------------------------------------------------------------------------------- + if ( lastGesticulationLevel != mCurrentGesticulationLevel ) + { + if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF ) + { + std::string gestureString = "unInitialized"; + if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; } + else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; } + else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; } + else { LL_INFOS() << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << LL_ENDL; } + + // this is the call that Karl S. created for triggering gestures from within the code. + LLGestureMgr::instance().triggerAndReviseString( gestureString ); + } + } + + } //if( isSelf() ) + + //----------------------------------------------------------------------------------------------------------------- + // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer. + // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol. + // + // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been + // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. + //----------------------------------------------------------------------------------------------------------------- + if (LLVoiceClient::getInstance()->getIsSpeaking( mID )) + { + if (!mVoiceVisualizer->getCurrentlySpeaking()) + { + mVoiceVisualizer->setStartSpeaking(); + + //printf( "gAwayTimer.reset();\n" ); + } + + mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) ); + + if( isSelf() ) + { + gAgent.clearAFK(); + } + } + else + { + if ( mVoiceVisualizer->getCurrentlySpeaking() ) + { + mVoiceVisualizer->setStopSpeaking(); + + if ( mLipSyncActive ) + { + if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight()); + if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight()); + + mLipSyncActive = false; + LLCharacter::updateVisualParams(); + dirtyMesh(); + } + } + } mVoiceVisualizer->setPositionAgent(position); - }//if ( voiceEnabled ) -} + }//if ( voiceEnabled ) +} static void override_bbox(LLDrawable* drawable, LLVector4a* extents) { @@ -2811,31 +2811,31 @@ static void override_bbox(LLDrawable* drawable, LLVector4a* extents) void LLVOAvatar::idleUpdateMisc(bool detailed_update) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (LLVOAvatar::sJointDebug) - { - LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL; - } + if (LLVOAvatar::sJointDebug) + { + LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL; + } - LLJoint::sNumUpdates = 0; - LLJoint::sNumTouches = 0; + LLJoint::sNumUpdates = 0; + LLJoint::sNumTouches = 0; - BOOL visible = isVisible() || mNeedsAnimUpdate; + BOOL visible = isVisible() || mNeedsAnimUpdate; - // update attachments positions - if (detailed_update) - { + // update attachments positions + if (detailed_update) + { U32 draw_order = 0; S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment(); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { LLViewerObject* attached_object = attachment_iter->get(); if (!attached_object || attached_object->isDead() @@ -2846,9 +2846,9 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); - - if (visible || !(bridge && bridge->getRadius() < 2.0)) - { + + if (visible || !(bridge && bridge->getRadius() < 2.0)) + { //override rigged attachments' octree spatial extents with this avatar's bounding box bool rigged = false; if (bridge) @@ -2902,839 +2902,839 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } } - attached_object->updateText(); - } - } - } - } - - mNeedsAnimUpdate = FALSE; - - if (isImpostor() && !mNeedsImpostorUpdate) - { - LL_ALIGN_16(LLVector4a ext[2]); - F32 distance; - LLVector3 angle; - - getImpostorValues(ext, angle, distance); - - for (U32 i = 0; i < 3 && !mNeedsImpostorUpdate; i++) - { - F32 cur_angle = angle.mV[i]; - F32 old_angle = mImpostorAngle.mV[i]; - F32 angle_diff = fabsf(cur_angle-old_angle); - - if (angle_diff > F_PI/512.f*distance*mUpdatePeriod) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 2; - } - } - - if (detailed_update && !mNeedsImpostorUpdate) - { //update impostor if view angle, distance, or bounding box change - //significantly - - F32 dist_diff = fabsf(distance-mImpostorDistance); - if (dist_diff/mImpostorDistance > 0.1f) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 3; - } - else - { - ext[0].load3(mLastAnimExtents[0].mV); + attached_object->updateText(); + } + } + } + } + + mNeedsAnimUpdate = FALSE; + + if (isImpostor() && !mNeedsImpostorUpdate) + { + LL_ALIGN_16(LLVector4a ext[2]); + F32 distance; + LLVector3 angle; + + getImpostorValues(ext, angle, distance); + + for (U32 i = 0; i < 3 && !mNeedsImpostorUpdate; i++) + { + F32 cur_angle = angle.mV[i]; + F32 old_angle = mImpostorAngle.mV[i]; + F32 angle_diff = fabsf(cur_angle-old_angle); + + if (angle_diff > F_PI/512.f*distance*mUpdatePeriod) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 2; + } + } + + if (detailed_update && !mNeedsImpostorUpdate) + { //update impostor if view angle, distance, or bounding box change + //significantly + + F32 dist_diff = fabsf(distance-mImpostorDistance); + if (dist_diff/mImpostorDistance > 0.1f) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 3; + } + else + { + ext[0].load3(mLastAnimExtents[0].mV); ext[1].load3(mLastAnimExtents[1].mV); // Expensive. Just call this once per frame, in updateSpatialExtents(); //calculateSpatialExtents(ext[0], ext[1]); - LLVector4a diff; - diff.setSub(ext[1], mImpostorExtents[1]); - if (diff.getLength3().getF32() > 0.05f) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 4; - } - else - { - diff.setSub(ext[0], mImpostorExtents[0]); - if (diff.getLength3().getF32() > 0.05f) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 5; - } - } - } - } - } + LLVector4a diff; + diff.setSub(ext[1], mImpostorExtents[1]); + if (diff.getLength3().getF32() > 0.05f) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 4; + } + else + { + diff.setSub(ext[0], mImpostorExtents[0]); + if (diff.getLength3().getF32() > 0.05f) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 5; + } + } + } + } + } if (mDrawable.notNull()) { - mDrawable->movePartition(); - - //force a move if sitting on an active object - if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) - { - gPipeline.markMoved(mDrawable, TRUE); - } + mDrawable->movePartition(); + + //force a move if sitting on an active object + if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) + { + gPipeline.markMoved(mDrawable, TRUE); + } } } void LLVOAvatar::idleUpdateAppearanceAnimation() { - // update morphing params - if (mAppearanceAnimating) - { - ESex avatar_sex = getSex(); - F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32(); - if (appearance_anim_time >= APPEARANCE_MORPH_TIME) - { - mAppearanceAnimating = FALSE; - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->isTweakable()) - { - param->stopAnimating(); - } - } - updateVisualParams(); - } - else - { - F32 morph_amt = calcMorphAmount(); - LLVisualParam *param; - - if (!isSelf()) - { - // animate only top level params for non-self avatars - for (param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->isTweakable()) - { - param->animate(morph_amt); - } - } - } - - // apply all params - for (param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - param->apply(avatar_sex); - } - - mLastAppearanceBlendTime = appearance_anim_time; - } - dirtyMesh(); - } + // update morphing params + if (mAppearanceAnimating) + { + ESex avatar_sex = getSex(); + F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32(); + if (appearance_anim_time >= APPEARANCE_MORPH_TIME) + { + mAppearanceAnimating = FALSE; + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isTweakable()) + { + param->stopAnimating(); + } + } + updateVisualParams(); + } + else + { + F32 morph_amt = calcMorphAmount(); + LLVisualParam *param; + + if (!isSelf()) + { + // animate only top level params for non-self avatars + for (param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isTweakable()) + { + param->animate(morph_amt); + } + } + } + + // apply all params + for (param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + param->apply(avatar_sex); + } + + mLastAppearanceBlendTime = appearance_anim_time; + } + dirtyMesh(); + } } F32 LLVOAvatar::calcMorphAmount() { - F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32(); - F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME); - F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME); + F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32(); + F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME); + F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME); - F32 morph_amt; - if (last_blend_frac == 1.f) - { - morph_amt = 1.f; - } - else - { - morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac); - } + F32 morph_amt; + if (last_blend_frac == 1.f) + { + morph_amt = 1.f; + } + else + { + morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac); + } - return morph_amt; + return morph_amt; } void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { - // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync + // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync if ( voice_enabled && mLastRezzedStatus > 0 // no point updating lip-sync for clouds && (LLVoiceClient::getInstance()->lipSyncEnabled()) && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) - { - F32 ooh_morph_amount = 0.0f; - F32 aah_morph_amount = 0.0f; + { + F32 ooh_morph_amount = 0.0f; + F32 aah_morph_amount = 0.0f; - mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount ); + mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount ); - if( mOohMorph ) - { - F32 ooh_weight = mOohMorph->getMinWeight() - + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight()); + if( mOohMorph ) + { + F32 ooh_weight = mOohMorph->getMinWeight() + + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight()); - mOohMorph->setWeight( ooh_weight); - } + mOohMorph->setWeight( ooh_weight); + } - if( mAahMorph ) - { - F32 aah_weight = mAahMorph->getMinWeight() - + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight()); + if( mAahMorph ) + { + F32 aah_weight = mAahMorph->getMinWeight() + + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight()); - mAahMorph->setWeight( aah_weight); - } + mAahMorph->setWeight( aah_weight); + } - mLipSyncActive = true; - LLCharacter::updateVisualParams(); - dirtyMesh(); - } + mLipSyncActive = true; + LLCharacter::updateVisualParams(); + dirtyMesh(); + } } void LLVOAvatar::idleUpdateLoadingEffect() { - // update visibility when avatar is partially loaded - if (updateIsFullyLoaded()) // changed? - { - if (isFullyLoaded()) - { - if (mFirstFullyVisible) - { - mFirstFullyVisible = FALSE; - if (isSelf()) - { - LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; - LLAppearanceMgr::instance().onFirstFullyVisible(); - } - else - { - LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL; - } - } - - deleteParticleSource(); - updateLOD(); - } - else - { - LLPartSysData particle_parameters; - - // fancy particle cloud designed by Brent - particle_parameters.mPartData.mMaxAge = 4.f; - particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f; - particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f; - particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f; - particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); - particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); - particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - particle_parameters.mPartImageID = sCloudTexture->getID(); - particle_parameters.mMaxAge = 0.f; - particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; - particle_parameters.mInnerAngle = F_PI; - particle_parameters.mOuterAngle = 0.f; - particle_parameters.mBurstRate = 0.02f; - particle_parameters.mBurstRadius = 0.0f; - particle_parameters.mBurstPartCount = 1; - particle_parameters.mBurstSpeedMin = 0.1f; - particle_parameters.mBurstSpeedMax = 1.f; - particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | - LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | - LLPartData::LL_PART_TARGET_POS_MASK ); - - // do not generate particles for dummy or overly-complex avatars - if (!mIsDummy && !isTooComplex() && !isTooSlow()) - { - setParticleSource(particle_parameters, getID()); - } - } - } -} + // update visibility when avatar is partially loaded + if (updateIsFullyLoaded()) // changed? + { + if (isFullyLoaded()) + { + if (mFirstFullyVisible) + { + mFirstFullyVisible = FALSE; + if (isSelf()) + { + LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + LLAppearanceMgr::instance().onFirstFullyVisible(); + } + else + { + LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + } + } + + deleteParticleSource(); + updateLOD(); + } + else + { + LLPartSysData particle_parameters; + + // fancy particle cloud designed by Brent + particle_parameters.mPartData.mMaxAge = 4.f; + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f; + particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f; + particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f; + particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); + particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); + particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; + particle_parameters.mPartImageID = sCloudTexture->getID(); + particle_parameters.mMaxAge = 0.f; + particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; + particle_parameters.mInnerAngle = F_PI; + particle_parameters.mOuterAngle = 0.f; + particle_parameters.mBurstRate = 0.02f; + particle_parameters.mBurstRadius = 0.0f; + particle_parameters.mBurstPartCount = 1; + particle_parameters.mBurstSpeedMin = 0.1f; + particle_parameters.mBurstSpeedMax = 1.f; + particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | + LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | + LLPartData::LL_PART_TARGET_POS_MASK ); + + // do not generate particles for dummy or overly-complex avatars + if (!mIsDummy && !isTooComplex() && !isTooSlow()) + { + setParticleSource(particle_parameters, getID()); + } + } + } +} void LLVOAvatar::idleUpdateWindEffect() { - // update wind effect - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) - { - F32 hover_strength = 0.f; - F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast; - mRippleTimeLast = mRippleTimer.getElapsedTimeF32(); - LLVector3 velocity = getVelocity(); - F32 speed = velocity.length(); - //RN: velocity varies too much frame to frame for this to work - mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f)); - mLastVel = velocity; - LLVector4 wind; - wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); - - if (mInAir) - { - hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed); - } - - if (mBelowWater) - { - // TODO: make cloth flow more gracefully when underwater - hover_strength += UNDERWATER_EFFECT_STRENGTH; - } - - wind.mV[VZ] += hover_strength; - wind.normalize(); - - wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f); - F32 interp; - if (wind.mV[VW] > mWindVec.mV[VW]) - { - interp = LLSmoothInterpolation::getInterpolant(0.2f); - } - else - { - interp = LLSmoothInterpolation::getInterpolant(0.4f); - } - mWindVec = lerp(mWindVec, wind, interp); - - F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f); - mWindFreq = lerp(mWindFreq, wind_freq, interp); - - if (mBelowWater) - { - mWindFreq *= UNDERWATER_FREQUENCY_DAMP; - } - - mRipplePhase += (time_delta * mWindFreq); - if (mRipplePhase > F_TWO_PI) - { - mRipplePhase = fmodf(mRipplePhase, F_TWO_PI); - } - } + // update wind effect + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) + { + F32 hover_strength = 0.f; + F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast; + mRippleTimeLast = mRippleTimer.getElapsedTimeF32(); + LLVector3 velocity = getVelocity(); + F32 speed = velocity.length(); + //RN: velocity varies too much frame to frame for this to work + mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f)); + mLastVel = velocity; + LLVector4 wind; + wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); + + if (mInAir) + { + hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed); + } + + if (mBelowWater) + { + // TODO: make cloth flow more gracefully when underwater + hover_strength += UNDERWATER_EFFECT_STRENGTH; + } + + wind.mV[VZ] += hover_strength; + wind.normalize(); + + wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f); + F32 interp; + if (wind.mV[VW] > mWindVec.mV[VW]) + { + interp = LLSmoothInterpolation::getInterpolant(0.2f); + } + else + { + interp = LLSmoothInterpolation::getInterpolant(0.4f); + } + mWindVec = lerp(mWindVec, wind, interp); + + F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f); + mWindFreq = lerp(mWindFreq, wind_freq, interp); + + if (mBelowWater) + { + mWindFreq *= UNDERWATER_FREQUENCY_DAMP; + } + + mRipplePhase += (time_delta * mWindFreq); + if (mRipplePhase > F_TWO_PI) + { + mRipplePhase = fmodf(mRipplePhase, F_TWO_PI); + } + } } void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // update chat bubble - //-------------------------------------------------------------------- - // draw text label over character's head - //-------------------------------------------------------------------- - if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME) - { - mChats.clear(); - } - - const F32 time_visible = mTimeVisible.getElapsedTimeF32(); + // update chat bubble + //-------------------------------------------------------------------- + // draw text label over character's head + //-------------------------------------------------------------------- + if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME) + { + mChats.clear(); + } + + const F32 time_visible = mTimeVisible.getElapsedTimeF32(); static LLCachedControl NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds static LLCachedControl FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds static LLCachedControl use_chat_bubbles(gSavedSettings, "UseChatBubbles"); - bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping); - bool render_name = visible_chat || - (((sRenderName == RENDER_NAME_ALWAYS) || - (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); - // If it's your own avatar, don't draw in mouselook, and don't - // draw if we're specifically hiding our own name. - if (isSelf()) - { + bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping); + bool render_name = visible_chat || + (((sRenderName == RENDER_NAME_ALWAYS) || + (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); + // If it's your own avatar, don't draw in mouselook, and don't + // draw if we're specifically hiding our own name. + if (isSelf()) + { static LLCachedControl render_name_show_self(gSavedSettings, "RenderNameShowSelf"); static LLCachedControl name_tag_mode(gSavedSettings, "AvatarNameTagMode"); - render_name = render_name - && !gAgentCamera.cameraMouselook() - && (visible_chat || (render_name_show_self && name_tag_mode)); - } - - if ( !render_name ) - { - if (mNameText) - { - // ...clean up old name tag - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; - } - return; - } - - bool new_name = FALSE; - if (visible_chat != mVisibleChat) - { - mVisibleChat = visible_chat; - new_name = TRUE; - } - - if (sRenderGroupTitles != mRenderGroupTitles) - { - mRenderGroupTitles = sRenderGroupTitles; - new_name = TRUE; - } - - // First Calculate Alpha - // If alpha > 0, create mNameText if necessary, otherwise delete it - F32 alpha = 0.f; - if (mAppAngle > 5.f) - { - const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; - if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) - { - alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; - } - else - { - // ...not fading, full alpha - alpha = 1.f; - } - } - else if (mAppAngle > 2.f) - { - // far away is faded out also - alpha = (mAppAngle-2.f)/3.f; - } - - if (alpha <= 0.f) - { - if (mNameText) - { - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; - } - return; - } - - if (!mNameText) - { - mNameText = static_cast( LLHUDObject::addHUDObject( - LLHUDObject::LL_HUD_NAME_TAG) ); - //mNameText->setMass(10.f); - mNameText->setSourceObject(this); - mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); - mNameText->setVisibleOffScreen(TRUE); - mNameText->setMaxLines(11); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - sNumVisibleChatBubbles++; - new_name = TRUE; - } - - mNameText->setPositionAgent(root_pos_last); - - idleUpdateNameTagText(new_name); - idleUpdateNameTagAlpha(new_name, alpha); -} + render_name = render_name + && !gAgentCamera.cameraMouselook() + && (visible_chat || (render_name_show_self && name_tag_mode)); + } -void LLVOAvatar::idleUpdateNameTagText(bool new_name) -{ - LLNameValue *title = getNVPair("Title"); - LLNameValue* firstname = getNVPair("FirstName"); - LLNameValue* lastname = getNVPair("LastName"); - - // Avatars must have a first and last name - if (!firstname || !lastname) return; - - bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); - bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end(); - bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); - bool is_muted; - if (isSelf()) - { - is_muted = false; - } - else - { - is_muted = isInMuteList(); - } - bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); - bool is_cloud = getIsCloud(); - - if (is_appearance != mNameAppearance) - { - if (is_appearance) - { - debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode"); - } - else - { - debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode"); - } - } - - // Rebuild name tag if state change detected - if (!mNameIsSet - || new_name - || (!title && !mTitle.empty()) - || (title && mTitle != title->getString()) - || is_away != mNameAway - || is_do_not_disturb != mNameDoNotDisturb - || is_muted != mNameMute - || is_appearance != mNameAppearance - || is_friend != mNameFriend - || is_cloud != mNameCloud) - { - LLColor4 name_tag_color = getNameTagColor(is_friend); - - clearNameTag(); - - if (is_away || is_muted || is_do_not_disturb || is_appearance) - { - std::string line; - if (is_away) - { - line += LLTrans::getString("AvatarAway"); - line += ", "; - } - if (is_do_not_disturb) - { - line += LLTrans::getString("AvatarDoNotDisturb"); - line += ", "; - } - if (is_muted) - { - line += LLTrans::getString("AvatarMuted"); - line += ", "; - } - if (is_appearance) - { - line += LLTrans::getString("AvatarEditingAppearance"); - line += ", "; - } - if (is_cloud) - { - line += LLTrans::getString("LoadingData"); - line += ", "; - } - // trim last ", " - line.resize( line.length() - 2 ); - addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); - } - - if (sRenderGroupTitles - && title && title->getString() && title->getString()[0] != '\0') - { - std::string title_str = title->getString(); - LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); - addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall(), true); - } - - static LLUICachedControl show_display_names("NameTagShowDisplayNames", true); - static LLUICachedControl show_usernames("NameTagShowUsernames", true); - - if (LLAvatarName::useDisplayNames()) - { - LLAvatarName av_name; - if (!LLAvatarNameCache::get(getID(), &av_name)) - { - // Force a rebuild at next idle - // Note: do not connect a callback on idle(). - clearNameTag(); - } - - // Might be blank if name not available yet, that's OK - if (show_display_names) - { - addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerif(), true); - } - // Suppress SLID display if display name matches exactly (ugh) - if (show_usernames && !av_name.isDisplayNameDefault()) - { - // *HACK: Desaturate the color - LLColor4 username_color = name_tag_color * 0.83f; - addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall(), true); - } - } - else - { - const LLFontGL* font = LLFontGL::getFontSansSerif(); - std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); - addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true); - } - - mNameAway = is_away; - mNameDoNotDisturb = is_do_not_disturb; - mNameMute = is_muted; - mNameAppearance = is_appearance; - mNameFriend = is_friend; - mNameCloud = is_cloud; - mTitle = title ? title->getString() : ""; - LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); - new_name = TRUE; - } - - if (mVisibleChat) - { - mNameText->setFont(LLFontGL::getFontSansSerif()); - mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - - std::deque::iterator chat_iter = mChats.begin(); - mNameText->clearString(); - - LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); - LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); - LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); - if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) - { - ++chat_iter; - } - - for(; chat_iter != mChats.end(); ++chat_iter) - { - F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); - LLFontGL::StyleFlags style; - switch(chat_iter->mChatType) - { - case CHAT_TYPE_WHISPER: - style = LLFontGL::ITALIC; - break; - case CHAT_TYPE_SHOUT: - style = LLFontGL::BOLD; - break; - default: - style = LLFontGL::NORMAL; - break; - } - if (chat_fade_amt < 1.f) - { - F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); - } - else if (chat_fade_amt < 2.f) - { - F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); - } - else if (chat_fade_amt < 3.f) - { - // *NOTE: only remove lines down to minimum number - mNameText->addLine(chat_iter->mText, old_chat, style); - } - } - mNameText->setVisibleOffScreen(TRUE); - - if (mTyping) - { - S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; - switch(dot_count) - { - case 1: - mNameText->addLine(".", new_chat); - break; - case 2: - mNameText->addLine("..", new_chat); - break; - case 3: - mNameText->addLine("...", new_chat); - break; - } - - } - } - else - { - // ...not using chat bubbles, just names - mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setVisibleOffScreen(FALSE); - } -} + if ( !render_name ) + { + if (mNameText) + { + // ...clean up old name tag + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + return; + } -void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses) -{ - // extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat - llassert(mNameText); - if (mVisibleChat) - { - mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH); - } - else - { - mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH); - } - mNameIsSet |= !line.empty(); -} + bool new_name = FALSE; + if (visible_chat != mVisibleChat) + { + mVisibleChat = visible_chat; + new_name = TRUE; + } -void LLVOAvatar::clearNameTag() -{ - mNameIsSet = false; - if (mNameText) - { - mNameText->setLabel(""); - mNameText->setString(""); - } - mTimeVisible.reset(); -} + if (sRenderGroupTitles != mRenderGroupTitles) + { + mRenderGroupTitles = sRenderGroupTitles; + new_name = TRUE; + } -//static -void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id) -{ - LLViewerObject* obj = gObjectList.findObject(agent_id); - if (!obj) return; + // First Calculate Alpha + // If alpha > 0, create mNameText if necessary, otherwise delete it + F32 alpha = 0.f; + if (mAppAngle > 5.f) + { + const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; + if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) + { + alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; + } + else + { + // ...not fading, full alpha + alpha = 1.f; + } + } + else if (mAppAngle > 2.f) + { + // far away is faded out also + alpha = (mAppAngle-2.f)/3.f; + } - LLVOAvatar* avatar = dynamic_cast(obj); - if (!avatar) return; + if (alpha <= 0.f) + { + if (mNameText) + { + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + return; + } - avatar->clearNameTag(); -} + if (!mNameText) + { + mNameText = static_cast( LLHUDObject::addHUDObject( + LLHUDObject::LL_HUD_NAME_TAG) ); + //mNameText->setMass(10.f); + mNameText->setSourceObject(this); + mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); + mNameText->setVisibleOffScreen(TRUE); + mNameText->setMaxLines(11); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + sNumVisibleChatBubbles++; + new_name = TRUE; + } -//static -void LLVOAvatar::invalidateNameTags() -{ - std::vector::iterator it = LLCharacter::sInstances.begin(); - for ( ; it != LLCharacter::sInstances.end(); ++it) - { - LLVOAvatar* avatar = dynamic_cast(*it); - if (!avatar) continue; - if (avatar->isDead()) continue; + mNameText->setPositionAgent(root_pos_last); - avatar->clearNameTag(); - } + idleUpdateNameTagText(new_name); + idleUpdateNameTagAlpha(new_name, alpha); } -// Compute name tag position during idle update -LLVector3 LLVOAvatar::idleCalcNameTagPosition(const LLVector3 &root_pos_last) +void LLVOAvatar::idleUpdateNameTagText(bool new_name) { - LLQuaternion root_rot = mRoot->getWorldRotation(); - LLQuaternion inv_root_rot = ~root_rot; - LLVector3 pixel_right_vec; - LLVector3 pixel_up_vec; - LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); - LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); - camera_to_av.normalize(); - LLVector3 local_camera_at = camera_to_av * inv_root_rot; - LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); - local_camera_up.normalize(); - local_camera_up = local_camera_up * inv_root_rot; - - // position is based on head position, does not require mAvatarOffset here. - Nyx - LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f, - mBodySize.mV[VY] * 0.4f, - mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT); - - local_camera_up.scaleVec(avatar_ellipsoid); - local_camera_at.scaleVec(avatar_ellipsoid); - - LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot; - - if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD) - { - mTargetRootToHeadOffset = head_offset; - } - - mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f)); - - LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot); - name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); - name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; - - const F32 water_height = getRegion()->getWaterHeight(); - static const F32 WATER_HEIGHT_DELTA = 0.25f; - if (name_position[VZ] < water_height + WATER_HEIGHT_DELTA) - { - if (LLViewerCamera::getInstance()->getOrigin()[VZ] >= water_height) - { - name_position[VZ] = water_height; - } - else if (mNameText) // both camera and HUD are below watermark - { - F32 name_world_height = mNameText->getWorldHeight(); - F32 max_z_position = water_height - name_world_height; - if (name_position[VZ] > max_z_position) - { - name_position[VZ] = max_z_position; - } - } - } - - return name_position; -} + LLNameValue *title = getNVPair("Title"); + LLNameValue* firstname = getNVPair("FirstName"); + LLNameValue* lastname = getNVPair("LastName"); -void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha) -{ - llassert(mNameText); + // Avatars must have a first and last name + if (!firstname || !lastname) return; - if (new_name - || alpha != mNameAlpha) - { - mNameText->setAlpha(alpha); - mNameAlpha = alpha; - } + bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); + bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end(); + bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); + bool is_muted; + if (isSelf()) + { + is_muted = false; + } + else + { + is_muted = isInMuteList(); + } + bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); + bool is_cloud = getIsCloud(); + + if (is_appearance != mNameAppearance) + { + if (is_appearance) + { + debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode"); + } + else + { + debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode"); + } + } + + // Rebuild name tag if state change detected + if (!mNameIsSet + || new_name + || (!title && !mTitle.empty()) + || (title && mTitle != title->getString()) + || is_away != mNameAway + || is_do_not_disturb != mNameDoNotDisturb + || is_muted != mNameMute + || is_appearance != mNameAppearance + || is_friend != mNameFriend + || is_cloud != mNameCloud) + { + LLColor4 name_tag_color = getNameTagColor(is_friend); + + clearNameTag(); + + if (is_away || is_muted || is_do_not_disturb || is_appearance) + { + std::string line; + if (is_away) + { + line += LLTrans::getString("AvatarAway"); + line += ", "; + } + if (is_do_not_disturb) + { + line += LLTrans::getString("AvatarDoNotDisturb"); + line += ", "; + } + if (is_muted) + { + line += LLTrans::getString("AvatarMuted"); + line += ", "; + } + if (is_appearance) + { + line += LLTrans::getString("AvatarEditingAppearance"); + line += ", "; + } + if (is_cloud) + { + line += LLTrans::getString("LoadingData"); + line += ", "; + } + // trim last ", " + line.resize( line.length() - 2 ); + addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall()); + } + + if (sRenderGroupTitles + && title && title->getString() && title->getString()[0] != '\0') + { + std::string title_str = title->getString(); + LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); + addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall(), true); + } + + static LLUICachedControl show_display_names("NameTagShowDisplayNames", true); + static LLUICachedControl show_usernames("NameTagShowUsernames", true); + + if (LLAvatarName::useDisplayNames()) + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(getID(), &av_name)) + { + // Force a rebuild at next idle + // Note: do not connect a callback on idle(). + clearNameTag(); + } + + // Might be blank if name not available yet, that's OK + if (show_display_names) + { + addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerif(), true); + } + // Suppress SLID display if display name matches exactly (ugh) + if (show_usernames && !av_name.isDisplayNameDefault()) + { + // *HACK: Desaturate the color + LLColor4 username_color = name_tag_color * 0.83f; + addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall(), true); + } + } + else + { + const LLFontGL* font = LLFontGL::getFontSansSerif(); + std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); + addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true); + } + + mNameAway = is_away; + mNameDoNotDisturb = is_do_not_disturb; + mNameMute = is_muted; + mNameAppearance = is_appearance; + mNameFriend = is_friend; + mNameCloud = is_cloud; + mTitle = title ? title->getString() : ""; + LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); + new_name = TRUE; + } + + if (mVisibleChat) + { + mNameText->setFont(LLFontGL::getFontSansSerif()); + mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); + + std::deque::iterator chat_iter = mChats.begin(); + mNameText->clearString(); + + LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); + LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); + LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); + if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) + { + ++chat_iter; + } + + for(; chat_iter != mChats.end(); ++chat_iter) + { + F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); + LLFontGL::StyleFlags style; + switch(chat_iter->mChatType) + { + case CHAT_TYPE_WHISPER: + style = LLFontGL::ITALIC; + break; + case CHAT_TYPE_SHOUT: + style = LLFontGL::BOLD; + break; + default: + style = LLFontGL::NORMAL; + break; + } + if (chat_fade_amt < 1.f) + { + F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); + } + else if (chat_fade_amt < 2.f) + { + F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); + } + else if (chat_fade_amt < 3.f) + { + // *NOTE: only remove lines down to minimum number + mNameText->addLine(chat_iter->mText, old_chat, style); + } + } + mNameText->setVisibleOffScreen(TRUE); + + if (mTyping) + { + S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; + switch(dot_count) + { + case 1: + mNameText->addLine(".", new_chat); + break; + case 2: + mNameText->addLine("..", new_chat); + break; + case 3: + mNameText->addLine("...", new_chat); + break; + } + + } + } + else + { + // ...not using chat bubbles, just names + mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + mNameText->setVisibleOffScreen(FALSE); + } +} + +void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses) +{ + // extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat + llassert(mNameText); + if (mVisibleChat) + { + mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH); + } + else + { + mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH); + } + mNameIsSet |= !line.empty(); +} + +void LLVOAvatar::clearNameTag() +{ + mNameIsSet = false; + if (mNameText) + { + mNameText->setLabel(""); + mNameText->setString(""); + } + mTimeVisible.reset(); +} + +//static +void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id) +{ + LLViewerObject* obj = gObjectList.findObject(agent_id); + if (!obj) return; + + LLVOAvatar* avatar = dynamic_cast(obj); + if (!avatar) return; + + avatar->clearNameTag(); +} + +//static +void LLVOAvatar::invalidateNameTags() +{ + std::vector::iterator it = LLCharacter::sInstances.begin(); + for ( ; it != LLCharacter::sInstances.end(); ++it) + { + LLVOAvatar* avatar = dynamic_cast(*it); + if (!avatar) continue; + if (avatar->isDead()) continue; + + avatar->clearNameTag(); + } +} + +// Compute name tag position during idle update +LLVector3 LLVOAvatar::idleCalcNameTagPosition(const LLVector3 &root_pos_last) +{ + LLQuaternion root_rot = mRoot->getWorldRotation(); + LLQuaternion inv_root_rot = ~root_rot; + LLVector3 pixel_right_vec; + LLVector3 pixel_up_vec; + LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); + LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); + camera_to_av.normalize(); + LLVector3 local_camera_at = camera_to_av * inv_root_rot; + LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); + local_camera_up.normalize(); + local_camera_up = local_camera_up * inv_root_rot; + + // position is based on head position, does not require mAvatarOffset here. - Nyx + LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f, + mBodySize.mV[VY] * 0.4f, + mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT); + + local_camera_up.scaleVec(avatar_ellipsoid); + local_camera_at.scaleVec(avatar_ellipsoid); + + LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot; + + if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD) + { + mTargetRootToHeadOffset = head_offset; + } + + mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f)); + + LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot); + name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); + name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; + + const F32 water_height = getRegion()->getWaterHeight(); + static const F32 WATER_HEIGHT_DELTA = 0.25f; + if (name_position[VZ] < water_height + WATER_HEIGHT_DELTA) + { + if (LLViewerCamera::getInstance()->getOrigin()[VZ] >= water_height) + { + name_position[VZ] = water_height; + } + else if (mNameText) // both camera and HUD are below watermark + { + F32 name_world_height = mNameText->getWorldHeight(); + F32 max_z_position = water_height - name_world_height; + if (name_position[VZ] > max_z_position) + { + name_position[VZ] = max_z_position; + } + } + } + + return name_position; +} + +void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha) +{ + llassert(mNameText); + + if (new_name + || alpha != mNameAlpha) + { + mNameText->setAlpha(alpha); + mNameAlpha = alpha; + } } LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) { - static LLUICachedControl show_friends("NameTagShowFriends", false); - const char* color_name; - if (show_friends && is_friend) - { - color_name = "NameTagFriend"; - } - else if (LLAvatarName::useDisplayNames()) - { - // ...color based on whether username "matches" a computed display name - LLAvatarName av_name; - if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault()) - { - color_name = "NameTagMatch"; - } - else - { - color_name = "NameTagMismatch"; - } - } - else - { - // ...not using display names - color_name = "NameTagLegacy"; - } - return LLUIColorTable::getInstance()->getColor( color_name ); + static LLUICachedControl show_friends("NameTagShowFriends", false); + const char* color_name; + if (show_friends && is_friend) + { + color_name = "NameTagFriend"; + } + else if (LLAvatarName::useDisplayNames()) + { + // ...color based on whether username "matches" a computed display name + LLAvatarName av_name; + if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault()) + { + color_name = "NameTagMatch"; + } + else + { + color_name = "NameTagMismatch"; + } + } + else + { + // ...not using display names + color_name = "NameTagLegacy"; + } + return LLUIColorTable::getInstance()->getColor( color_name ); } void LLVOAvatar::idleUpdateBelowWater() { - F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]); + F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]); - F32 water_height; - water_height = getRegion()->getWaterHeight(); + F32 water_height; + water_height = getRegion()->getWaterHeight(); - mBelowWater = avatar_height < water_height; + mBelowWater = avatar_height < water_height; } void LLVOAvatar::slamPosition() { - gAgent.setPositionAgent(getPositionAgent()); - // SL-315 - mRoot->setWorldPosition(getPositionAgent()); // teleport - setChanged(TRANSLATED); - if (mDrawable.notNull()) - { - gPipeline.updateMoveNormalAsync(mDrawable); - } - mRoot->updateWorldMatrixChildren(); + gAgent.setPositionAgent(getPositionAgent()); + // SL-315 + mRoot->setWorldPosition(getPositionAgent()); // teleport + setChanged(TRANSLATED); + if (mDrawable.notNull()) + { + gPipeline.updateMoveNormalAsync(mDrawable); + } + mRoot->updateWorldMatrixChildren(); } bool LLVOAvatar::isVisuallyMuted() { - bool muted = false; - - // Priority order (highest priority first) - // * own avatar is never visually muted - // * if on the "always draw normally" list, draw them normally - // * if on the "always visually mute" list, mute them - // * check against the render cost and attachment limits - if (!isSelf()) - { - if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) - { - muted = false; - } - else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) - { + bool muted = false; + + // Priority order (highest priority first) + // * own avatar is never visually muted + // * if on the "always draw normally" list, draw them normally + // * if on the "always visually mute" list, mute them + // * check against the render cost and attachment limits + if (!isSelf()) + { + if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) + { + muted = false; + } + else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) + { #ifdef JELLYDOLLS_SHOULD_IMPOSTOR - muted = true; - // Always want to see this AV as an impostor + muted = true; + // Always want to see this AV as an impostor #else - muted = false; + muted = false; #endif - } + } else if (isInMuteList()) { muted = true; @@ -3743,89 +3743,89 @@ bool LLVOAvatar::isVisuallyMuted() { muted = isTooSlow(); } - else - { - muted = isTooComplex() || isTooSlow(); - } - } + else + { + muted = isTooComplex() || isTooSlow(); + } + } - return muted; + return muted; } bool LLVOAvatar::isInMuteList() const { - bool muted = false; - F64 now = LLFrameTimer::getTotalSeconds(); - if (now < mCachedMuteListUpdateTime) - { - muted = mCachedInMuteList; - } - else - { - muted = LLMuteList::getInstance()->isMuted(getID()); + bool muted = false; + F64 now = LLFrameTimer::getTotalSeconds(); + if (now < mCachedMuteListUpdateTime) + { + muted = mCachedInMuteList; + } + else + { + muted = LLMuteList::getInstance()->isMuted(getID()); - const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; - mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; - mCachedInMuteList = muted; - } - return muted; + const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; + mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; + mCachedInMuteList = muted; + } + return muted; } void LLVOAvatar::updateAppearanceMessageDebugText() { - S32 central_bake_version = -1; - if (getRegion()) - { - central_bake_version = getRegion()->getCentralBakeVersion(); - } - bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); - bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); - std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", - isSelf() ? (all_local_downloaded ? "L" : "l") : "-", - all_baked_downloaded ? "B" : "b", - mUseLocalAppearance, mIsEditingAppearance, - 1, central_bake_version); - std::string origin_string = bakedTextureOriginInfo(); - debug_line += " [" + origin_string + "]"; - S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); - S32 last_request_cof_version = mLastUpdateRequestCOFVersion; - S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; - if (isSelf()) - { - debug_line += llformat(" - cof: %d req: %d rcv:%d", - curr_cof_version, last_request_cof_version, last_received_cof_version); - static LLCachedControl debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure"); - if (debug_force_failure) - { - debug_line += " FORCING ERRS"; - } - } - else - { - debug_line += llformat(" - cof rcv:%d", last_received_cof_version); - } - debug_line += llformat(" bsz-z: %.3f", mBodySize[2]); + S32 central_bake_version = -1; + if (getRegion()) + { + central_bake_version = getRegion()->getCentralBakeVersion(); + } + bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); + bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); + std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", + isSelf() ? (all_local_downloaded ? "L" : "l") : "-", + all_baked_downloaded ? "B" : "b", + mUseLocalAppearance, mIsEditingAppearance, + 1, central_bake_version); + std::string origin_string = bakedTextureOriginInfo(); + debug_line += " [" + origin_string + "]"; + S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); + S32 last_request_cof_version = mLastUpdateRequestCOFVersion; + S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; + if (isSelf()) + { + debug_line += llformat(" - cof: %d req: %d rcv:%d", + curr_cof_version, last_request_cof_version, last_received_cof_version); + static LLCachedControl debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure"); + if (debug_force_failure) + { + debug_line += " FORCING ERRS"; + } + } + else + { + debug_line += llformat(" - cof rcv:%d", last_received_cof_version); + } + debug_line += llformat(" bsz-z: %.3f", mBodySize[2]); if (mAvatarOffset[2] != 0.0f) { debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]); } - bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled(); - debug_line += hover_enabled ? " H" : " h"; - const LLVector3& hover_offset = getHoverOffset(); - if (hover_offset[2] != 0.0) - { - debug_line += llformat(" hov_z: %.3f", hover_offset[2]); - debug_line += llformat(" %s", (isSitting() ? "S" : "T")); - debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); - } - if (mInAir) - { - debug_line += " A"; - - } + bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled(); + debug_line += hover_enabled ? " H" : " h"; + const LLVector3& hover_offset = getHoverOffset(); + if (hover_offset[2] != 0.0) + { + debug_line += llformat(" hov_z: %.3f", hover_offset[2]); + debug_line += llformat(" %s", (isSitting() ? "S" : "T")); + debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); + } + if (mInAir) + { + debug_line += " A"; + + } LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); - LLVector3 normal; + LLVector3 normal; LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); @@ -3835,40 +3835,40 @@ void LLVOAvatar::updateAppearanceMessageDebugText() LLVector3 pelvis_pos = mPelvisp->getPosition(); debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); - const LLVector3& scale = getScale(); - debug_line += llformat(" scale-z %.3f", scale[2]); - S32 is_visible = (S32) isVisible(); - S32 is_m_visible = (S32) mVisible; - debug_line += llformat(" v %d/%d", is_visible, is_m_visible); - - AvatarOverallAppearance aoa = getOverallAppearance(); - if (aoa == AOA_NORMAL) - { - debug_line += " N"; - } - else if (aoa == AOA_JELLYDOLL) - { - debug_line += " J"; - } - else - { - debug_line += " I"; - } - - if (mMeshValid) - { - debug_line += "m"; - } - else - { - debug_line += "-"; - } - if (isImpostor()) - { - debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime))); - } - - addDebugText(debug_line); + const LLVector3& scale = getScale(); + debug_line += llformat(" scale-z %.3f", scale[2]); + S32 is_visible = (S32) isVisible(); + S32 is_m_visible = (S32) mVisible; + debug_line += llformat(" v %d/%d", is_visible, is_m_visible); + + AvatarOverallAppearance aoa = getOverallAppearance(); + if (aoa == AOA_NORMAL) + { + debug_line += " N"; + } + else if (aoa == AOA_JELLYDOLL) + { + debug_line += " J"; + } + else + { + debug_line += " I"; + } + + if (mMeshValid) + { + debug_line += "m"; + } + else + { + debug_line += "-"; + } + if (isImpostor()) + { + debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime))); + } + + addDebugText(debug_line); } LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset_id) @@ -3879,8 +3879,8 @@ LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset { if (vobj->getInventorySerial()<=0) { - vobj->requestInventory(); - } + vobj->requestInventory(); + } item = vobj->getInventoryItemByAsset(asset_id); } return item; @@ -3898,23 +3898,23 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU LLViewerObject *childp = *it; item = getObjectInventoryItem(childp, asset_id); if (item) - { + { break; } } - } + } return item; } void LLVOAvatar::updateAnimationDebugText() { - for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); - iter != mMotionController.getActiveMotions().end(); ++iter) - { - LLMotion* motionp = *iter; - if (motionp->getMinPixelArea() < getPixelArea()) - { - std::string output; + for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); + iter != mMotionController.getActiveMotions().end(); ++iter) + { + LLMotion* motionp = *iter; + if (motionp->getMinPixelArea() < getPixelArea()) + { + std::string output; std::string motion_name = motionp->getName(); if (motion_name.empty()) { @@ -3931,107 +3931,107 @@ void LLVOAvatar::updateAnimationDebugText() } } if (motion_name.empty()) - { - std::string name; - if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) - { - name = motionp->getID().asString(); - LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); - for (; anim_it != mAnimationSources.end(); ++anim_it) - { - if (anim_it->second == motionp->getID()) - { - LLViewerObject* object = gObjectList.findObject(anim_it->first); - if (!object) - { - break; - } - if (object->isAvatar()) - { - if (mMotionController.mIsSelf) - { - // Searching inventory by asset id is really long - // so just mark as inventory - // Also item is likely to be named by LLPreviewAnim - name += "(inventory)"; - } - } - else - { - LLViewerInventoryItem* item = NULL; - if (!object->isInventoryDirty()) - { - item = object->getInventoryItemByAsset(motionp->getID()); - } - if (item) - { - name = item->getName(); - } - else if (object->isAttachment()) - { - name += "(att:" + getAttachmentItemName() + ")"; - } - else - { - // in-world object, name or content unknown - name += "(in-world)"; - } - } - break; - } - } - } - else - { - name = LLUUID::null.asString(); - } - motion_name = name; - } - std::string motion_tag = ""; - if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end()) - { - motion_tag = "*"; - } - output = llformat("%s%s - %d", - motion_name.c_str(), - motion_tag.c_str(), - (U32)motionp->getPriority()); - addDebugText(output); - } - } + { + std::string name; + if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) + { + name = motionp->getID().asString(); + LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); + for (; anim_it != mAnimationSources.end(); ++anim_it) + { + if (anim_it->second == motionp->getID()) + { + LLViewerObject* object = gObjectList.findObject(anim_it->first); + if (!object) + { + break; + } + if (object->isAvatar()) + { + if (mMotionController.mIsSelf) + { + // Searching inventory by asset id is really long + // so just mark as inventory + // Also item is likely to be named by LLPreviewAnim + name += "(inventory)"; + } + } + else + { + LLViewerInventoryItem* item = NULL; + if (!object->isInventoryDirty()) + { + item = object->getInventoryItemByAsset(motionp->getID()); + } + if (item) + { + name = item->getName(); + } + else if (object->isAttachment()) + { + name += "(att:" + getAttachmentItemName() + ")"; + } + else + { + // in-world object, name or content unknown + name += "(in-world)"; + } + } + break; + } + } + } + else + { + name = LLUUID::null.asString(); + } + motion_name = name; + } + std::string motion_tag = ""; + if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end()) + { + motion_tag = "*"; + } + output = llformat("%s%s - %d", + motion_name.c_str(), + motion_tag.c_str(), + (U32)motionp->getPriority()); + addDebugText(output); + } + } } void LLVOAvatar::updateDebugText() { // Leave mDebugText uncleared here, in case a derived class has added some state first - if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) - { + if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) + { updateAppearanceMessageDebugText(); - } + } - if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) - { - if (!mBakedTextureDebugText.empty()) - addDebugText(mBakedTextureDebugText); - } + if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) + { + if (!mBakedTextureDebugText.empty()) + addDebugText(mBakedTextureDebugText); + } // Develop -> Avatar -> Animation Info - if (LLVOAvatar::sShowAnimationDebug) - { + if (LLVOAvatar::sShowAnimationDebug) + { updateAnimationDebugText(); - } + } - if (!mDebugText.size() && mText.notNull()) - { - mText->markDead(); - mText = NULL; - } - else if (mDebugText.size()) - { - setDebugText(mDebugText); - } - mDebugText.clear(); + if (!mDebugText.size() && mText.notNull()) + { + mText->markDead(); + mText = NULL; + } + else if (mDebugText.size()) + { + setDebugText(mDebugText); + } + mDebugText.clear(); } //------------------------------------------------------------------------ @@ -4045,87 +4045,87 @@ void LLVOAvatar::updateFootstepSounds() { return; } - - //------------------------------------------------------------------------- - // Find the ground under each foot, these are used for a variety - // of things that follow - //------------------------------------------------------------------------- - LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition(); - LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); - LLVector3 ankle_left_ground_agent = ankle_left_pos_agent; - LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; + //------------------------------------------------------------------------- + // Find the ground under each foot, these are used for a variety + // of things that follow + //------------------------------------------------------------------------- + LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition(); + LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); + + LLVector3 ankle_left_ground_agent = ankle_left_pos_agent; + LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; LLVector3 normal; - resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal); - resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); - - F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]); - F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); - - if (!isSitting()) - { - //------------------------------------------------------------------------- - // Figure out which foot is on ground - //------------------------------------------------------------------------- - if (!mInAir) - { - if ((leftElev < 0.0f) || (rightElev < 0.0f)) - { - ankle_left_pos_agent = mFootLeftp->getWorldPosition(); - ankle_right_pos_agent = mFootRightp->getWorldPosition(); - leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]; - rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]; - } - } - } - - const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND}; - const S32 NUM_AGENT_FOOTSTEP_ANIMS = LL_ARRAY_SIZE(AGENT_FOOTSTEP_ANIMS); - - if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) ) - { - BOOL playSound = FALSE; - LLVector3 foot_pos_agent; - - BOOL onGroundLeft = (leftElev <= 0.05f); - BOOL onGroundRight = (rightElev <= 0.05f); - - // did left foot hit the ground? - if ( onGroundLeft && !mWasOnGroundLeft ) - { - foot_pos_agent = ankle_left_pos_agent; - playSound = TRUE; - } - - // did right foot hit the ground? - if ( onGroundRight && !mWasOnGroundRight ) - { - foot_pos_agent = ankle_right_pos_agent; - playSound = TRUE; - } - - mWasOnGroundLeft = onGroundLeft; - mWasOnGroundRight = onGroundRight; - - if ( playSound ) - { - const F32 STEP_VOLUME = 0.1f; - const LLUUID& step_sound_id = getStepSound(); - - LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); - - if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global) - && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) - { - gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global); - } - } - } -} + resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal); + resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); -//------------------------------------------------------------------------ -// computeUpdatePeriod() -// Factored out from updateCharacter() + F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]); + F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); + + if (!isSitting()) + { + //------------------------------------------------------------------------- + // Figure out which foot is on ground + //------------------------------------------------------------------------- + if (!mInAir) + { + if ((leftElev < 0.0f) || (rightElev < 0.0f)) + { + ankle_left_pos_agent = mFootLeftp->getWorldPosition(); + ankle_right_pos_agent = mFootRightp->getWorldPosition(); + leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]; + rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]; + } + } + } + + const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND}; + const S32 NUM_AGENT_FOOTSTEP_ANIMS = LL_ARRAY_SIZE(AGENT_FOOTSTEP_ANIMS); + + if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) ) + { + BOOL playSound = FALSE; + LLVector3 foot_pos_agent; + + BOOL onGroundLeft = (leftElev <= 0.05f); + BOOL onGroundRight = (rightElev <= 0.05f); + + // did left foot hit the ground? + if ( onGroundLeft && !mWasOnGroundLeft ) + { + foot_pos_agent = ankle_left_pos_agent; + playSound = TRUE; + } + + // did right foot hit the ground? + if ( onGroundRight && !mWasOnGroundRight ) + { + foot_pos_agent = ankle_right_pos_agent; + playSound = TRUE; + } + + mWasOnGroundLeft = onGroundLeft; + mWasOnGroundRight = onGroundRight; + + if ( playSound ) + { + const F32 STEP_VOLUME = 0.1f; + const LLUUID& step_sound_id = getStepSound(); + + LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); + + if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global) + && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) + { + gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global); + } + } + } +} + +//------------------------------------------------------------------------ +// computeUpdatePeriod() +// Factored out from updateCharacter() // Set new value for mUpdatePeriod based on distance and various other factors. // // Note 10-2020: it turns out that none of these update period @@ -4137,57 +4137,57 @@ void LLVOAvatar::updateFootstepSounds() // ------------------------------------------------------------------------ void LLVOAvatar::computeUpdatePeriod() { - bool visually_muted = isVisuallyMuted(); - if (mDrawable.notNull() - && isVisible() + bool visually_muted = isVisuallyMuted(); + if (mDrawable.notNull() + && isVisible() && (!isSelf() || visually_muted) && !isUIAvatar() && (sLimitNonImpostors || visually_muted) && !mNeedsAnimUpdate) - { - const LLVector4a* ext = mDrawable->getSpatialExtents(); - LLVector4a size; - size.setSub(ext[1],ext[0]); - F32 mag = size.getLength3().getF32()*0.5f; - - const S32 UPDATE_RATE_SLOW = 64; - const S32 UPDATE_RATE_MED = 48; - const S32 UPDATE_RATE_FAST = 32; - - if (visually_muted) - { // visually muted avatars update at lowest rate - mUpdatePeriod = UPDATE_RATE_SLOW; - } - else if (! shouldImpostor() - || mDrawable->mDistanceWRTCamera < 1.f + mag) - { // first 25% of max visible avatars are not impostored - // also, don't impostor avatars whose bounding box may be penetrating the - // impostor camera near clip plane - mUpdatePeriod = 1; - } - else if ( shouldImpostor(4.0) ) - { //background avatars are REALLY slow updating impostors - mUpdatePeriod = UPDATE_RATE_SLOW; - } - else if (mLastRezzedStatus <= 0) - { - // Don't update cloud avatars too often - mUpdatePeriod = UPDATE_RATE_SLOW; - } - else if ( shouldImpostor(3.0) ) - { //back 25% of max visible avatars are slow updating impostors - mUpdatePeriod = UPDATE_RATE_MED; - } - else - { - //nearby avatars, update the impostors more frequently. - mUpdatePeriod = UPDATE_RATE_FAST; - } - } - else - { - mUpdatePeriod = 1; - } + { + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a size; + size.setSub(ext[1],ext[0]); + F32 mag = size.getLength3().getF32()*0.5f; + + const S32 UPDATE_RATE_SLOW = 64; + const S32 UPDATE_RATE_MED = 48; + const S32 UPDATE_RATE_FAST = 32; + + if (visually_muted) + { // visually muted avatars update at lowest rate + mUpdatePeriod = UPDATE_RATE_SLOW; + } + else if (! shouldImpostor() + || mDrawable->mDistanceWRTCamera < 1.f + mag) + { // first 25% of max visible avatars are not impostored + // also, don't impostor avatars whose bounding box may be penetrating the + // impostor camera near clip plane + mUpdatePeriod = 1; + } + else if ( shouldImpostor(4.0) ) + { //background avatars are REALLY slow updating impostors + mUpdatePeriod = UPDATE_RATE_SLOW; + } + else if (mLastRezzedStatus <= 0) + { + // Don't update cloud avatars too often + mUpdatePeriod = UPDATE_RATE_SLOW; + } + else if ( shouldImpostor(3.0) ) + { //back 25% of max visible avatars are slow updating impostors + mUpdatePeriod = UPDATE_RATE_MED; + } + else + { + //nearby avatars, update the impostors more frequently. + mUpdatePeriod = UPDATE_RATE_FAST; + } + } + else + { + mUpdatePeriod = 1; + } } //------------------------------------------------------------------------ @@ -4200,97 +4200,97 @@ void LLVOAvatar::computeUpdatePeriod() //------------------------------------------------------------------------ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) { - LLQuaternion iQ; - LLVector3 upDir( 0.0f, 0.0f, 1.0f ); - - // Compute a forward direction vector derived from the primitive rotation - // and the velocity vector. When walking or jumping, don't let body deviate - // more than 90 from the view, if necessary, flip the velocity vector. - - LLVector3 primDir; - if (isSelf()) - { - primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector()); - primDir.normalize(); - } - else - { - primDir = getRotation().getMatrix3().getFwdRow(); - } - LLVector3 velDir = getVelocity(); - velDir.normalize(); - if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) - { - F32 vpD = velDir * primDir; - if (vpD < -0.5f) - { - velDir *= -1.0f; - } - } - LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f)); - if (isSelf() && gAgentCamera.cameraMouselook()) - { - // make sure fwdDir stays in same general direction as primdir - if (gAgent.getFlying()) - { - fwdDir = LLViewerCamera::getInstance()->getAtAxis(); - } - else - { - LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); - LLVector3 up_vector = gAgent.getReferenceUpVector(); - at_axis -= up_vector * (at_axis * up_vector); - at_axis.normalize(); - - F32 dot = fwdDir * at_axis; - if (dot < 0.f) - { - fwdDir -= 2.f * at_axis * dot; - fwdDir.normalize(); - } - } - } - - LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); - F32 root_roll, root_pitch, root_yaw; - root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); - - // When moving very slow, the pelvis is allowed to deviate from the + LLQuaternion iQ; + LLVector3 upDir( 0.0f, 0.0f, 1.0f ); + + // Compute a forward direction vector derived from the primitive rotation + // and the velocity vector. When walking or jumping, don't let body deviate + // more than 90 from the view, if necessary, flip the velocity vector. + + LLVector3 primDir; + if (isSelf()) + { + primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector()); + primDir.normalize(); + } + else + { + primDir = getRotation().getMatrix3().getFwdRow(); + } + LLVector3 velDir = getVelocity(); + velDir.normalize(); + if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) + { + F32 vpD = velDir * primDir; + if (vpD < -0.5f) + { + velDir *= -1.0f; + } + } + LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f)); + if (isSelf() && gAgentCamera.cameraMouselook()) + { + // make sure fwdDir stays in same general direction as primdir + if (gAgent.getFlying()) + { + fwdDir = LLViewerCamera::getInstance()->getAtAxis(); + } + else + { + LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); + LLVector3 up_vector = gAgent.getReferenceUpVector(); + at_axis -= up_vector * (at_axis * up_vector); + at_axis.normalize(); + + F32 dot = fwdDir * at_axis; + if (dot < 0.f) + { + fwdDir -= 2.f * at_axis * dot; + fwdDir.normalize(); + } + } + } + + LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); + F32 root_roll, root_pitch, root_yaw; + root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); + + // When moving very slow, the pelvis is allowed to deviate from the // forward direction to allow it to hold its position while the torso - // and head turn. Once in motion, it must conform however. - BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); - - LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); - - static LLCachedControl s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); - static LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); - - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); - - if (self_in_mouselook) - { - pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; - } - pelvis_rot_threshold *= DEG_TO_RAD; - - F32 angle = angle_between( pelvisDir, fwdDir ); - - // The avatar's root is allowed to have a yaw that deviates widely - // from the forward direction, but if roll or pitch are off even - // a little bit we need to correct the rotation. - if(root_roll < 1.f * DEG_TO_RAD - && root_pitch < 5.f * DEG_TO_RAD) - { - // smaller correction vector means pelvis follows prim direction more closely - if (!mTurning && angle > pelvis_rot_threshold*0.75f) - { - mTurning = TRUE; - } - - // use tighter threshold when turning - if (mTurning) - { - pelvis_rot_threshold *= 0.4f; + // and head turn. Once in motion, it must conform however. + BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); + + LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); + + static LLCachedControl s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); + static LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); + + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); + + if (self_in_mouselook) + { + pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; + } + pelvis_rot_threshold *= DEG_TO_RAD; + + F32 angle = angle_between( pelvisDir, fwdDir ); + + // The avatar's root is allowed to have a yaw that deviates widely + // from the forward direction, but if roll or pitch are off even + // a little bit we need to correct the rotation. + if(root_roll < 1.f * DEG_TO_RAD + && root_pitch < 5.f * DEG_TO_RAD) + { + // smaller correction vector means pelvis follows prim direction more closely + if (!mTurning && angle > pelvis_rot_threshold*0.75f) + { + mTurning = TRUE; + } + + // use tighter threshold when turning + if (mTurning) + { + pelvis_rot_threshold *= 0.4f; // account for fps, assume that above value is for ~60fps constexpr F32 default_frame_sec = 0.016f; F32 prev_frame_sec = LLFrameTimer::getFrameDeltaTimeF32(); @@ -4300,62 +4300,62 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) // shorter frame means shorter turn. pelvis_rot_threshold *= prev_frame_sec/default_frame_sec; } - } - - // am I done turning? - if (angle < pelvis_rot_threshold) - { - mTurning = FALSE; - } - - LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f); - fwdDir += correction_vector; - } - else - { - mTurning = FALSE; - } - - // Now compute the full world space rotation for the whole body (wQv) - LLVector3 leftDir = upDir % fwdDir; - leftDir.normalize(); - fwdDir = leftDir % upDir; - LLQuaternion wQv( fwdDir, leftDir, upDir ); - - if (isSelf() && mTurning) - { - if ((fwdDir % pelvisDir) * upDir > 0.f) - { - gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT); - } - } - - // Set the root rotation, but do so incrementally so that it - // lags in time by some fixed amount. - //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG); - F32 pelvis_lag_time = 0.f; - if (self_in_mouselook) - { - pelvis_lag_time = PELVIS_LAG_MOUSELOOK; - } - else if (mInAir) - { - pelvis_lag_time = PELVIS_LAG_FLYING; - // increase pelvis lag time when moving slowly - pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f); - } - else - { - pelvis_lag_time = PELVIS_LAG_WALKING; - } - - F32 u = llclamp((delta_time / pelvis_lag_time), 0.0f, 1.0f); - - mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) ); + } + + // am I done turning? + if (angle < pelvis_rot_threshold) + { + mTurning = FALSE; + } + + LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f); + fwdDir += correction_vector; + } + else + { + mTurning = FALSE; + } + + // Now compute the full world space rotation for the whole body (wQv) + LLVector3 leftDir = upDir % fwdDir; + leftDir.normalize(); + fwdDir = leftDir % upDir; + LLQuaternion wQv( fwdDir, leftDir, upDir ); + + if (isSelf() && mTurning) + { + if ((fwdDir % pelvisDir) * upDir > 0.f) + { + gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT); + } + } + + // Set the root rotation, but do so incrementally so that it + // lags in time by some fixed amount. + //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG); + F32 pelvis_lag_time = 0.f; + if (self_in_mouselook) + { + pelvis_lag_time = PELVIS_LAG_MOUSELOOK; + } + else if (mInAir) + { + pelvis_lag_time = PELVIS_LAG_FLYING; + // increase pelvis lag time when moving slowly + pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f); + } + else + { + pelvis_lag_time = PELVIS_LAG_WALKING; + } + + F32 u = llclamp((delta_time / pelvis_lag_time), 0.0f, 1.0f); + + mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) ); } //------------------------------------------------------------------------ @@ -4368,91 +4368,91 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) // ------------------------------------------------------------------------ void LLVOAvatar::updateTimeStep() { - if (!isSelf() && !isUIAvatar()) // ie, non-self avatars, and animated objects will be affected. - { + if (!isSelf() && !isUIAvatar()) // ie, non-self avatars, and animated objects will be affected. + { // Note that sInstances counts animated objects and // standard avatars in the same bucket. Is this desirable? - F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f); - F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f); - F32 time_step = time_quantum * pixel_area_scale; + F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f); + F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f); + F32 time_step = time_quantum * pixel_area_scale; // Extrema: // If number of avs is 10 or less, time_step is unmodified (flagged with 0.0). // If area of av is 5000 or greater, time_step is unmodified (flagged with 0.0). // If number of avs is 35 or greater, and area of av is 100 or less, // time_step takes the maximum possible value of 0.25. // Other situations will give values within the (0, 0.25) range. - if (time_step != 0.f) - { - // disable walk motion servo controller as it doesn't work with motion timesteps - stopMotion(ANIM_AGENT_WALK_ADJUST); - removeAnimationData("Walk Speed"); - } + if (time_step != 0.f) + { + // disable walk motion servo controller as it doesn't work with motion timesteps + stopMotion(ANIM_AGENT_WALK_ADJUST); + removeAnimationData("Walk Speed"); + } // See SL-763 - playback with altered time step does not // appear to work correctly, odd behavior for distant avatars. // As of 11-2017, LLMotionController::updateMotions() will // ignore the value here. Need to re-enable if it's every // fixed. - mMotionController.setTimeStep(time_step); - } -} - -void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool was_sit_ground_constrained) -{ - if (!(isSitting() && getParent())) - { - // This case includes all configurations except sitting on an - // object, so does include ground sit. - - //-------------------------------------------------------------------- - // get timing info - // handle initial condition case - //-------------------------------------------------------------------- - F32 animation_time = mAnimTimer.getElapsedTimeF32(); - if (mTimeLast == 0.0f) - { - mTimeLast = animation_time; - - // Initially put the pelvis at slaved position/mRotation - // SL-315 - mRoot->setWorldPosition( getPositionAgent() ); // first frame - mRoot->setWorldRotation( getRotation() ); - } - - //-------------------------------------------------------------------- - // dont' let dT get larger than 1/5th of a second - //-------------------------------------------------------------------- - F32 delta_time = animation_time - mTimeLast; - - delta_time = llclamp( delta_time, DELTA_TIME_MIN, DELTA_TIME_MAX ); - mTimeLast = animation_time; - - mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f); - - //-------------------------------------------------------------------- - // compute the position of the avatar's root - //-------------------------------------------------------------------- - LLVector3d root_pos; - LLVector3d ground_under_pelvis; - - if (isSelf()) - { - gAgent.setPositionAgent(getRenderPosition()); - } - - root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); - root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER); + mMotionController.setTimeStep(time_step); + } +} + +void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool was_sit_ground_constrained) +{ + if (!(isSitting() && getParent())) + { + // This case includes all configurations except sitting on an + // object, so does include ground sit. + + //-------------------------------------------------------------------- + // get timing info + // handle initial condition case + //-------------------------------------------------------------------- + F32 animation_time = mAnimTimer.getElapsedTimeF32(); + if (mTimeLast == 0.0f) + { + mTimeLast = animation_time; + + // Initially put the pelvis at slaved position/mRotation + // SL-315 + mRoot->setWorldPosition( getPositionAgent() ); // first frame + mRoot->setWorldRotation( getRotation() ); + } + + //-------------------------------------------------------------------- + // dont' let dT get larger than 1/5th of a second + //-------------------------------------------------------------------- + F32 delta_time = animation_time - mTimeLast; + + delta_time = llclamp( delta_time, DELTA_TIME_MIN, DELTA_TIME_MAX ); + mTimeLast = animation_time; + + mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f); + + //-------------------------------------------------------------------- + // compute the position of the avatar's root + //-------------------------------------------------------------------- + LLVector3d root_pos; + LLVector3d ground_under_pelvis; + + if (isSelf()) + { + gAgent.setPositionAgent(getRenderPosition()); + } + + root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); + root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER); LLVector3 normal; - resolveHeightGlobal(root_pos, ground_under_pelvis, normal); - F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); - BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) || - foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE); + resolveHeightGlobal(root_pos, ground_under_pelvis, normal); + F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); + BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) || + foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE); - if (in_air && !mInAir) - { - mTimeInAir.reset(); - } - mInAir = in_air; + if (in_air && !mInAir) + { + mTimeInAir.reset(); + } + mInAir = in_air; // SL-402: with the ability to animate the position of joints // that affect the body size calculation, computed body size @@ -4460,40 +4460,40 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w // it frequently. // SL-427: this appears to be too frequent, moving to only do on animation state change. //computeBodySize(); - - // correct for the fact that the pelvis is not necessarily the center - // of the agent's physical representation - root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot; - if (!isSitting() && !was_sit_ground_constrained) - { - root_pos += LLVector3d(getHoverOffset()); - if (getOverallAppearance() == AOA_JELLYDOLL) - { - F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]); - root_pos[2] += offz; - // if (!isSelf() && !isControlAvatar()) - // { - // LL_DEBUGS("Avatar") << "av " << getFullname() - // << " frame " << LLFrameTimer::getFrameCount() - // << " root adjust offz " << offz - // << " scalez " << getScale()[VZ] - // << " bsz " << mBodySize.mV[VZ] - // << LL_ENDL; - // } - } - } - // if (!isSelf() && !isControlAvatar()) - // { - // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance() - // << " frame " << LLFrameTimer::getFrameCount() - // << " scalez " << getScale()[VZ] - // << " bsz " << mBodySize.mV[VZ] - // << " root pos " << root_pos[2] - // << " curr rootz " << mRoot->getPosition()[2] - // << " pp-z " << mPelvisp->getPosition()[2] - // << " renderpos " << getRenderPosition() - // << LL_ENDL; - // } + + // correct for the fact that the pelvis is not necessarily the center + // of the agent's physical representation + root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot; + if (!isSitting() && !was_sit_ground_constrained) + { + root_pos += LLVector3d(getHoverOffset()); + if (getOverallAppearance() == AOA_JELLYDOLL) + { + F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]); + root_pos[2] += offz; + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() + // << " frame " << LLFrameTimer::getFrameCount() + // << " root adjust offz " << offz + // << " scalez " << getScale()[VZ] + // << " bsz " << mBodySize.mV[VZ] + // << LL_ENDL; + // } + } + } + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance() + // << " frame " << LLFrameTimer::getFrameCount() + // << " scalez " << getScale()[VZ] + // << " bsz " << mBodySize.mV[VZ] + // << " root pos " << root_pos[2] + // << " curr rootz " << mRoot->getPosition()[2] + // << " pp-z " << mPelvisp->getPosition()[2] + // << " renderpos " << getRenderPosition() + // << LL_ENDL; + // } LLControlAvatar *cav = dynamic_cast(this); if (cav) @@ -4504,73 +4504,73 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w else { LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); - // if (!isSelf() && !isControlAvatar()) - // { - // LL_DEBUGS("Avatar") << "av " << getFullname() - // << " frame " << LLFrameTimer::getFrameCount() - // << " newPosition " << newPosition - // << " renderpos " << getRenderPosition() - // << LL_ENDL; - // } + // if (!isSelf() && !isControlAvatar()) + // { + // LL_DEBUGS("Avatar") << "av " << getFullname() + // << " frame " << LLFrameTimer::getFrameCount() + // << " newPosition " << newPosition + // << " renderpos " << getRenderPosition() + // << LL_ENDL; + // } if (newPosition != mRoot->getXform()->getWorldPosition()) - { + { mRoot->touch(); // SL-315 - mRoot->setWorldPosition( newPosition ); // regular update + mRoot->setWorldPosition( newPosition ); // regular update } } - //-------------------------------------------------------------------- - // Propagate viewer object rotation to root of avatar - //-------------------------------------------------------------------- - if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) - { + //-------------------------------------------------------------------- + // Propagate viewer object rotation to root of avatar + //-------------------------------------------------------------------- + if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) + { // Rotation fixups for avatars in motion. // Skip for animated objects. updateOrientation(agent, speed, delta_time); - } - } - else if (mDrawable.notNull()) - { + } + } + else if (mDrawable.notNull()) + { // Sitting on an object - mRoot is slaved to mDrawable orientation. - LLVector3 pos = mDrawable->getPosition(); - pos += getHoverOffset() * mDrawable->getRotation(); - // SL-315 - mRoot->setPosition(pos); - mRoot->setRotation(mDrawable->getRotation()); - } + LLVector3 pos = mDrawable->getPosition(); + pos += getHoverOffset() * mDrawable->getRotation(); + // SL-315 + mRoot->setPosition(pos); + mRoot->setRotation(mDrawable->getRotation()); + } } //------------------------------------------------------------------------ // LLVOAvatar::computeNeedsUpdate() -// +// // Most of the logic here is to figure out when to periodically update impostors. // Non-impostors have mUpdatePeriod == 1 and will need update every frame. //------------------------------------------------------------------------ bool LLVOAvatar::computeNeedsUpdate() { - const F32 MAX_IMPOSTOR_INTERVAL = 4.0f; - computeUpdatePeriod(); + const F32 MAX_IMPOSTOR_INTERVAL = 4.0f; + computeUpdatePeriod(); - bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0); + bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0); bool needs_update_by_max_time = ((gFrameTimeSeconds-mLastImpostorUpdateFrameTime)> MAX_IMPOSTOR_INTERVAL); - bool needs_update = needs_update_by_frame_count || needs_update_by_max_time; - - if (needs_update && !isSelf()) - { - if (needs_update_by_max_time) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 11; - } - else - { - //mNeedsImpostorUpdate = TRUE; - //mLastImpostorUpdateReason = 10; - } - } - return needs_update; + bool needs_update = needs_update_by_frame_count || needs_update_by_max_time; + + if (needs_update && !isSelf()) + { + if (needs_update_by_max_time) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 11; + } + else + { + //mNeedsImpostorUpdate = TRUE; + //mLastImpostorUpdateReason = 10; + } + } + return needs_update; } // updateCharacter() @@ -4596,153 +4596,153 @@ bool LLVOAvatar::computeNeedsUpdate() // //------------------------------------------------------------------------ bool LLVOAvatar::updateCharacter(LLAgent &agent) -{ - updateDebugText(); - - if (!mIsBuilt) - { - return FALSE; - } - - BOOL visible = isVisible(); +{ + updateDebugText(); + + if (!mIsBuilt) + { + return FALSE; + } + + BOOL visible = isVisible(); bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing - bool is_attachment = false; + bool is_attachment = false; - if (is_control_avatar) - { + if (is_control_avatar) + { LLControlAvatar *cav = dynamic_cast(this); - is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects - } + is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects + } LLScopedContextString str("updateCharacter " + getFullname() + " is_control_avatar " - + boost::lexical_cast(is_control_avatar) + + boost::lexical_cast(is_control_avatar) + " is_attachment " + boost::lexical_cast(is_attachment)); - // For fading out the names above heads, only let the timer - // run if we're visible. - if (mDrawable.notNull() && !visible) - { - mTimeVisible.reset(); - } + // For fading out the names above heads, only let the timer + // run if we're visible. + if (mDrawable.notNull() && !visible) + { + mTimeVisible.reset(); + } - //-------------------------------------------------------------------- - // The rest should only be done occasionally for far away avatars. + //-------------------------------------------------------------------- + // The rest should only be done occasionally for far away avatars. // Set mUpdatePeriod and visible based on distance and other criteria, - // and flag for impostor update if needed. - //-------------------------------------------------------------------- - bool needs_update = computeNeedsUpdate(); - - //-------------------------------------------------------------------- - // Early out if does not need update and not self - // don't early out for your own avatar, as we rely on your animations playing reliably - // for example, the "turn around" animation when entering customize avatar needs to trigger - // even when your avatar is offscreen - //-------------------------------------------------------------------- - if (!needs_update && !isSelf()) - { - updateMotions(LLCharacter::HIDDEN_UPDATE); - return FALSE; - } - - //-------------------------------------------------------------------- - // Handle transitions between regular rendering, jellydoll, or invisible. - // Can trigger skeleton reset or animation changes - //-------------------------------------------------------------------- - updateOverallAppearance(); - - //-------------------------------------------------------------------- - // change animation time quanta based on avatar render load - //-------------------------------------------------------------------- + // and flag for impostor update if needed. + //-------------------------------------------------------------------- + bool needs_update = computeNeedsUpdate(); + + //-------------------------------------------------------------------- + // Early out if does not need update and not self + // don't early out for your own avatar, as we rely on your animations playing reliably + // for example, the "turn around" animation when entering customize avatar needs to trigger + // even when your avatar is offscreen + //-------------------------------------------------------------------- + if (!needs_update && !isSelf()) + { + updateMotions(LLCharacter::HIDDEN_UPDATE); + return FALSE; + } + + //-------------------------------------------------------------------- + // Handle transitions between regular rendering, jellydoll, or invisible. + // Can trigger skeleton reset or animation changes + //-------------------------------------------------------------------- + updateOverallAppearance(); + + //-------------------------------------------------------------------- + // change animation time quanta based on avatar render load + //-------------------------------------------------------------------- // SL-763 the time step quantization does not currently work. //updateTimeStep(); - - //-------------------------------------------------------------------- + + //-------------------------------------------------------------------- // Update sitting state based on parent and active animation info. - //-------------------------------------------------------------------- - if (getParent() && !isSitting()) - { - sitOnObject((LLViewerObject*)getParent()); - } - else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED)) - { + //-------------------------------------------------------------------- + if (getParent() && !isSitting()) + { + sitOnObject((LLViewerObject*)getParent()); + } + else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED)) + { // If we are starting up, motion might be loading LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED); if (!motionp || !mMotionController.isMotionLoading(motionp)) { getOffObject(); } - } - - //-------------------------------------------------------------------- - // create local variables in world coords for region position values - //-------------------------------------------------------------------- - LLVector3 xyVel = getVelocity(); - xyVel.mV[VZ] = 0.0f; - F32 speed = xyVel.length(); - // remembering the value here prevents a display glitch if the - // animation gets toggled during this update. - bool was_sit_ground_constrained = isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED); + } - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // create local variables in world coords for region position values + //-------------------------------------------------------------------- + LLVector3 xyVel = getVelocity(); + xyVel.mV[VZ] = 0.0f; + F32 speed = xyVel.length(); + // remembering the value here prevents a display glitch if the + // animation gets toggled during this update. + bool was_sit_ground_constrained = isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED); + + //-------------------------------------------------------------------- // This does a bunch of state updating, including figuring out // whether av is in the air, setting mRoot position and rotation // In some cases, calls updateOrientation() for a lot of the // work // -------------------------------------------------------------------- updateRootPositionAndRotation(agent, speed, was_sit_ground_constrained); - - //------------------------------------------------------------------------- - // Update character motions - //------------------------------------------------------------------------- - // store data relevant to motions - mSpeed = speed; - - // update animations - if (!visible && !isSelf()) // NOTE: never do a "hidden update" for self avatar as it interrupts controller processing - { - updateMotions(LLCharacter::HIDDEN_UPDATE); - } - else if (mSpecialRenderMode == 1) // Animation Preview - { - updateMotions(LLCharacter::FORCE_UPDATE); - } - else - { - // Might be better to do HIDDEN_UPDATE if cloud - updateMotions(LLCharacter::NORMAL_UPDATE); - } - - // Special handling for sitting on ground. - if (!getParent() && (isSitting() || was_sit_ground_constrained)) - { - - F32 off_z = LLVector3d(getHoverOffset()).mdV[VZ]; - if (off_z != 0.0) - { - LLVector3 pos = mRoot->getWorldPosition(); - pos.mV[VZ] += off_z; - mRoot->touch(); - // SL-315 - mRoot->setWorldPosition(pos); - } - } - - // update head position - updateHeadOffset(); - - // Generate footstep sounds when feet hit the ground + + //------------------------------------------------------------------------- + // Update character motions + //------------------------------------------------------------------------- + // store data relevant to motions + mSpeed = speed; + + // update animations + if (!visible && !isSelf()) // NOTE: never do a "hidden update" for self avatar as it interrupts controller processing + { + updateMotions(LLCharacter::HIDDEN_UPDATE); + } + else if (mSpecialRenderMode == 1) // Animation Preview + { + updateMotions(LLCharacter::FORCE_UPDATE); + } + else + { + // Might be better to do HIDDEN_UPDATE if cloud + updateMotions(LLCharacter::NORMAL_UPDATE); + } + + // Special handling for sitting on ground. + if (!getParent() && (isSitting() || was_sit_ground_constrained)) + { + + F32 off_z = LLVector3d(getHoverOffset()).mdV[VZ]; + if (off_z != 0.0) + { + LLVector3 pos = mRoot->getWorldPosition(); + pos.mV[VZ] += off_z; + mRoot->touch(); + // SL-315 + mRoot->setWorldPosition(pos); + } + } + + // update head position + updateHeadOffset(); + + // Generate footstep sounds when feet hit the ground updateFootstepSounds(); - // Update child joints as needed. - mRoot->updateWorldMatrixChildren(); + // Update child joints as needed. + mRoot->updateWorldMatrixChildren(); if (visible) { - // System avatar mesh vertices need to be reskinned. - mNeedsSkin = TRUE; + // System avatar mesh vertices need to be reskinned. + mNeedsSkin = TRUE; } - return visible; + return visible; } //----------------------------------------------------------------------------- @@ -4750,487 +4750,487 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent) //----------------------------------------------------------------------------- void LLVOAvatar::updateHeadOffset() { - // since we only care about Z, just grab one of the eyes - LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); - midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition(); - midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]); - - if (mDrawable.notNull()) - { - midEyePt = midEyePt * ~mDrawable->getWorldRotation(); - } - if (isSitting()) - { - mHeadOffset = midEyePt; - } - else - { - F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped)); - mHeadOffset = lerp(midEyePt, mHeadOffset, u); - } + // since we only care about Z, just grab one of the eyes + LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); + midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition(); + midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]); + + if (mDrawable.notNull()) + { + midEyePt = midEyePt * ~mDrawable->getWorldRotation(); + } + if (isSitting()) + { + mHeadOffset = midEyePt; + } + else + { + F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped)); + mHeadOffset = lerp(midEyePt, mHeadOffset, u); + } } void LLVOAvatar::debugBodySize() const { - LLVector3 pelvis_scale = mPelvisp->getScale(); + LLVector3 pelvis_scale = mPelvisp->getScale(); - // some of the joints have not been cached - LLVector3 skull = mSkullp->getPosition(); + // some of the joints have not been cached + LLVector3 skull = mSkullp->getPosition(); LL_DEBUGS("Avatar") << "skull pos " << skull << LL_ENDL; - //LLVector3 skull_scale = mSkullp->getScale(); + //LLVector3 skull_scale = mSkullp->getScale(); - LLVector3 neck = mNeckp->getPosition(); - LLVector3 neck_scale = mNeckp->getScale(); + LLVector3 neck = mNeckp->getPosition(); + LLVector3 neck_scale = mNeckp->getScale(); LL_DEBUGS("Avatar") << "neck pos " << neck << " neck_scale " << neck_scale << LL_ENDL; - LLVector3 chest = mChestp->getPosition(); - LLVector3 chest_scale = mChestp->getScale(); + LLVector3 chest = mChestp->getPosition(); + LLVector3 chest_scale = mChestp->getScale(); LL_DEBUGS("Avatar") << "chest pos " << chest << " chest_scale " << chest_scale << LL_ENDL; - // the rest of the joints have been cached - LLVector3 head = mHeadp->getPosition(); - LLVector3 head_scale = mHeadp->getScale(); + // the rest of the joints have been cached + LLVector3 head = mHeadp->getPosition(); + LLVector3 head_scale = mHeadp->getScale(); LL_DEBUGS("Avatar") << "head pos " << head << " head_scale " << head_scale << LL_ENDL; - LLVector3 torso = mTorsop->getPosition(); - LLVector3 torso_scale = mTorsop->getScale(); + LLVector3 torso = mTorsop->getPosition(); + LLVector3 torso_scale = mTorsop->getScale(); LL_DEBUGS("Avatar") << "torso pos " << torso << " torso_scale " << torso_scale << LL_ENDL; - LLVector3 hip = mHipLeftp->getPosition(); - LLVector3 hip_scale = mHipLeftp->getScale(); + LLVector3 hip = mHipLeftp->getPosition(); + LLVector3 hip_scale = mHipLeftp->getScale(); LL_DEBUGS("Avatar") << "hip pos " << hip << " hip_scale " << hip_scale << LL_ENDL; - LLVector3 knee = mKneeLeftp->getPosition(); - LLVector3 knee_scale = mKneeLeftp->getScale(); + LLVector3 knee = mKneeLeftp->getPosition(); + LLVector3 knee_scale = mKneeLeftp->getScale(); LL_DEBUGS("Avatar") << "knee pos " << knee << " knee_scale " << knee_scale << LL_ENDL; - LLVector3 ankle = mAnkleLeftp->getPosition(); - LLVector3 ankle_scale = mAnkleLeftp->getScale(); + LLVector3 ankle = mAnkleLeftp->getPosition(); + LLVector3 ankle_scale = mAnkleLeftp->getScale(); LL_DEBUGS("Avatar") << "ankle pos " << ankle << " ankle_scale " << ankle_scale << LL_ENDL; - LLVector3 foot = mFootLeftp->getPosition(); + LLVector3 foot = mFootLeftp->getPosition(); LL_DEBUGS("Avatar") << "foot pos " << foot << LL_ENDL; - F32 new_offset = (const_cast(this))->getVisualParamWeight(AVATAR_HOVER); + F32 new_offset = (const_cast(this))->getVisualParamWeight(AVATAR_HOVER); LL_DEBUGS("Avatar") << "new_offset " << new_offset << LL_ENDL; - F32 new_pelvis_to_foot = hip.mV[VZ] * pelvis_scale.mV[VZ] - + F32 new_pelvis_to_foot = hip.mV[VZ] * pelvis_scale.mV[VZ] - knee.mV[VZ] * hip_scale.mV[VZ] - ankle.mV[VZ] * knee_scale.mV[VZ] - foot.mV[VZ] * ankle_scale.mV[VZ]; LL_DEBUGS("Avatar") << "new_pelvis_to_foot " << new_pelvis_to_foot << LL_ENDL; - LLVector3 new_body_size; - new_body_size.mV[VZ] = new_pelvis_to_foot + - // the sqrt(2) correction below is an approximate - // correction to get to the top of the head - F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + - head.mV[VZ] * neck_scale.mV[VZ] + - neck.mV[VZ] * chest_scale.mV[VZ] + - chest.mV[VZ] * torso_scale.mV[VZ] + - torso.mV[VZ] * pelvis_scale.mV[VZ]; + LLVector3 new_body_size; + new_body_size.mV[VZ] = new_pelvis_to_foot + + // the sqrt(2) correction below is an approximate + // correction to get to the top of the head + F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + + head.mV[VZ] * neck_scale.mV[VZ] + + neck.mV[VZ] * chest_scale.mV[VZ] + + chest.mV[VZ] * torso_scale.mV[VZ] + + torso.mV[VZ] * pelvis_scale.mV[VZ]; - // TODO -- measure the real depth and width - new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; - new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; + // TODO -- measure the real depth and width + new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; + new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; LL_DEBUGS("Avatar") << "new_body_size " << new_body_size << LL_ENDL; } - + //------------------------------------------------------------------------ // postPelvisSetRecalc //------------------------------------------------------------------------ void LLVOAvatar::postPelvisSetRecalc() -{ - mRoot->updateWorldMatrixChildren(); - computeBodySize(); - dirtyMesh(2); +{ + mRoot->updateWorldMatrixChildren(); + computeBodySize(); + dirtyMesh(2); } //------------------------------------------------------------------------ // updateVisibility() //------------------------------------------------------------------------ void LLVOAvatar::updateVisibility() { - BOOL visible = FALSE; - - if (mIsDummy) - { - visible = FALSE; - } - else if (mDrawable.isNull()) - { - visible = FALSE; - } - else - { - if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible()) - { - visible = TRUE; - } - else - { - visible = FALSE; - } - - if(isSelf()) - { - if (!gAgentWearables.areWearablesLoaded()) - { - visible = FALSE; - } - } - else if( !mFirstAppearanceMessageReceived ) - { - visible = FALSE; - } - - if (sDebugInvisible) - { - LLNameValue* firstname = getNVPair("FirstName"); - if (firstname) - { - LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL; - } - else - { - LL_INFOS() << "Avatar " << this << " updating visiblity" << LL_ENDL; - } - - if (visible) - { - LL_INFOS() << "Visible" << LL_ENDL; - } - else - { - LL_INFOS() << "Not visible" << LL_ENDL; - } - - /*if (avatar_in_frustum) - { - LL_INFOS() << "Avatar in frustum" << LL_ENDL; - } - else - { - LL_INFOS() << "Avatar not in frustum" << LL_ENDL; - }*/ - - /*if (LLViewerCamera::getInstance()->sphereInFrustum(sel_pos_agent, 2.0f)) - { - LL_INFOS() << "Sel pos visible" << LL_ENDL; - } - if (LLViewerCamera::getInstance()->sphereInFrustum(wrist_right_pos_agent, 0.2f)) - { - LL_INFOS() << "Wrist pos visible" << LL_ENDL; - } - if (LLViewerCamera::getInstance()->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f)) - { - LL_INFOS() << "Agent visible" << LL_ENDL; - }*/ - LL_INFOS() << "PA: " << getPositionAgent() << LL_ENDL; - /*LL_INFOS() << "SPA: " << sel_pos_agent << LL_ENDL; - LL_INFOS() << "WPA: " << wrist_right_pos_agent << LL_ENDL;*/ - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - if (LLViewerObject *attached_object = attachment_iter->get()) - { - if(attached_object->mDrawable->isVisible()) - { - LL_INFOS() << attachment->getName() << " visible" << LL_ENDL; - } - else - { - LL_INFOS() << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << LL_ENDL; - } - } - } - } - } - } - - if (!visible && mVisible) - { - mMeshInvisibleTime.reset(); - } - - if (visible) - { - if (!mMeshValid) - { - restoreMeshData(); - } - } - else - { - if (mMeshValid && - (isControlAvatar() || mMeshInvisibleTime.getElapsedTimeF32() > TIME_BEFORE_MESH_CLEANUP)) - { - releaseMeshData(); - } - } + BOOL visible = FALSE; - if ( visible != mVisible ) + if (mIsDummy) { - LL_DEBUGS("AvatarRender") << "visible was " << mVisible << " now " << visible << LL_ENDL; + visible = FALSE; } - mVisible = visible; -} - -// private -bool LLVOAvatar::shouldAlphaMask() -{ - const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked - && !LLDrawPoolAvatar::sSkipTransparent; + else if (mDrawable.isNull()) + { + visible = FALSE; + } + else + { + if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible()) + { + visible = TRUE; + } + else + { + visible = FALSE; + } - return should_alpha_mask; + if(isSelf()) + { + if (!gAgentWearables.areWearablesLoaded()) + { + visible = FALSE; + } + } + else if( !mFirstAppearanceMessageReceived ) + { + visible = FALSE; + } -} + if (sDebugInvisible) + { + LLNameValue* firstname = getNVPair("FirstName"); + if (firstname) + { + LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL; + } + else + { + LL_INFOS() << "Avatar " << this << " updating visiblity" << LL_ENDL; + } -//----------------------------------------------------------------------------- -// renderSkinned() -//----------------------------------------------------------------------------- -U32 LLVOAvatar::renderSkinned() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + if (visible) + { + LL_INFOS() << "Visible" << LL_ENDL; + } + else + { + LL_INFOS() << "Not visible" << LL_ENDL; + } - U32 num_indices = 0; + /*if (avatar_in_frustum) + { + LL_INFOS() << "Avatar in frustum" << LL_ENDL; + } + else + { + LL_INFOS() << "Avatar not in frustum" << LL_ENDL; + }*/ - if (!mIsBuilt) - { - return num_indices; - } + /*if (LLViewerCamera::getInstance()->sphereInFrustum(sel_pos_agent, 2.0f)) + { + LL_INFOS() << "Sel pos visible" << LL_ENDL; + } + if (LLViewerCamera::getInstance()->sphereInFrustum(wrist_right_pos_agent, 0.2f)) + { + LL_INFOS() << "Wrist pos visible" << LL_ENDL; + } + if (LLViewerCamera::getInstance()->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f)) + { + LL_INFOS() << "Agent visible" << LL_ENDL; + }*/ + LL_INFOS() << "PA: " << getPositionAgent() << LL_ENDL; + /*LL_INFOS() << "SPA: " << sel_pos_agent << LL_ENDL; + LL_INFOS() << "WPA: " << wrist_right_pos_agent << LL_ENDL;*/ + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; - if (mDrawable.isNull()) - { - return num_indices; - } - - LLFace* face = mDrawable->getFace(0); - - bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); - - if (needs_rebuild || mDirtyMesh) - { //LOD changed or new mesh created, allocate new vertex buffer if needed - if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) - { - updateMeshData(); - mDirtyMesh = 0; - mNeedsSkin = TRUE; - mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); - } - } - - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) - { - if (mNeedsSkin) - { - //generate animated mesh - LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); - LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); - LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); - LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); - LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); - LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); - - if(upper_mesh) - { - upper_mesh->updateJointGeometry(); - } - if (lower_mesh) - { - lower_mesh->updateJointGeometry(); - } - - if( isWearingWearableType( LLWearableType::WT_SKIRT ) ) - { - if(skirt_mesh) - { - skirt_mesh->updateJointGeometry(); - } - } - - if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) - { - if(eyelash_mesh) - { - eyelash_mesh->updateJointGeometry(); - } - if(head_mesh) - { - head_mesh->updateJointGeometry(); - } - if(hair_mesh) - { - hair_mesh->updateJointGeometry(); - } - } - mNeedsSkin = FALSE; - mLastSkinTime = gFrameTimeSeconds; - - LLFace * face = mDrawable->getFace(0); - if (face) - { - LLVertexBuffer* vb = face->getVertexBuffer(); - if (vb) - { - vb->unmapBuffer(); - } - } - } - } - else - { - mNeedsSkin = FALSE; - } - - if (sDebugInvisible) - { - LLNameValue* firstname = getNVPair("FirstName"); - if (firstname) - { - LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL; - } - else - { - LL_INFOS() << "Avatar " << this << " in render" << LL_ENDL; - } - if (!mIsBuilt) - { - LL_INFOS() << "Not built!" << LL_ENDL; - } - else if (!gAgent.needsRenderAvatar()) - { - LL_INFOS() << "Doesn't need avatar render!" << LL_ENDL; - } - else - { - LL_INFOS() << "Rendering!" << LL_ENDL; - } - } - - if (!mIsBuilt) - { - return num_indices; - } - - if (isSelf() && !gAgent.needsRenderAvatar()) - { - return num_indices; - } - - //-------------------------------------------------------------------- - // render all geometry attached to the skeleton - //-------------------------------------------------------------------- - - BOOL first_pass = TRUE; - if (!LLDrawPoolAvatar::sSkipOpaque) - { - if (isUIAvatar() && mIsDummy) - { - LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); - if (hair_mesh) - { - num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) - { - - if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) - { - LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); - if (head_mesh) - { - num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - } - if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) - { - LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); - if (upper_mesh) - { - num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - - if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) - { - LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); - if (lower_mesh) - { - num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - } - - if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) - { - LLGLState blend(GL_BLEND, !mIsDummy); - num_indices += renderTransparent(first_pass); - } - - return num_indices; -} + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + if (LLViewerObject *attached_object = attachment_iter->get()) + { + if(attached_object->mDrawable->isVisible()) + { + LL_INFOS() << attachment->getName() << " visible" << LL_ENDL; + } + else + { + LL_INFOS() << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << LL_ENDL; + } + } + } + } + } + } + + if (!visible && mVisible) + { + mMeshInvisibleTime.reset(); + } + + if (visible) + { + if (!mMeshValid) + { + restoreMeshData(); + } + } + else + { + if (mMeshValid && + (isControlAvatar() || mMeshInvisibleTime.getElapsedTimeF32() > TIME_BEFORE_MESH_CLEANUP)) + { + releaseMeshData(); + } + } + + if ( visible != mVisible ) + { + LL_DEBUGS("AvatarRender") << "visible was " << mVisible << " now " << visible << LL_ENDL; + } + mVisible = visible; +} + +// private +bool LLVOAvatar::shouldAlphaMask() +{ + const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked + && !LLDrawPoolAvatar::sSkipTransparent; + + return should_alpha_mask; + +} + +//----------------------------------------------------------------------------- +// renderSkinned() +//----------------------------------------------------------------------------- +U32 LLVOAvatar::renderSkinned() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + + U32 num_indices = 0; + + if (!mIsBuilt) + { + return num_indices; + } + + if (mDrawable.isNull()) + { + return num_indices; + } + + LLFace* face = mDrawable->getFace(0); + + bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); + + if (needs_rebuild || mDirtyMesh) + { //LOD changed or new mesh created, allocate new vertex buffer if needed + if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) + { + updateMeshData(); + mDirtyMesh = 0; + mNeedsSkin = TRUE; + mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); + } + } + + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) + { + if (mNeedsSkin) + { + //generate animated mesh + LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); + LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); + LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); + LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); + LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + + if(upper_mesh) + { + upper_mesh->updateJointGeometry(); + } + if (lower_mesh) + { + lower_mesh->updateJointGeometry(); + } + + if( isWearingWearableType( LLWearableType::WT_SKIRT ) ) + { + if(skirt_mesh) + { + skirt_mesh->updateJointGeometry(); + } + } + + if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) + { + if(eyelash_mesh) + { + eyelash_mesh->updateJointGeometry(); + } + if(head_mesh) + { + head_mesh->updateJointGeometry(); + } + if(hair_mesh) + { + hair_mesh->updateJointGeometry(); + } + } + mNeedsSkin = FALSE; + mLastSkinTime = gFrameTimeSeconds; + + LLFace * face = mDrawable->getFace(0); + if (face) + { + LLVertexBuffer* vb = face->getVertexBuffer(); + if (vb) + { + vb->unmapBuffer(); + } + } + } + } + else + { + mNeedsSkin = FALSE; + } + + if (sDebugInvisible) + { + LLNameValue* firstname = getNVPair("FirstName"); + if (firstname) + { + LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL; + } + else + { + LL_INFOS() << "Avatar " << this << " in render" << LL_ENDL; + } + if (!mIsBuilt) + { + LL_INFOS() << "Not built!" << LL_ENDL; + } + else if (!gAgent.needsRenderAvatar()) + { + LL_INFOS() << "Doesn't need avatar render!" << LL_ENDL; + } + else + { + LL_INFOS() << "Rendering!" << LL_ENDL; + } + } + + if (!mIsBuilt) + { + return num_indices; + } + + if (isSelf() && !gAgent.needsRenderAvatar()) + { + return num_indices; + } + + //-------------------------------------------------------------------- + // render all geometry attached to the skeleton + //-------------------------------------------------------------------- + + BOOL first_pass = TRUE; + if (!LLDrawPoolAvatar::sSkipOpaque) + { + if (isUIAvatar() && mIsDummy) + { + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + if (hair_mesh) + { + num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) + { + + if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) + { + LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); + if (head_mesh) + { + num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + } + if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) + { + LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); + if (upper_mesh) + { + num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + + if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) + { + LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); + if (lower_mesh) + { + num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + } + + if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) + { + LLGLState blend(GL_BLEND, !mIsDummy); + num_indices += renderTransparent(first_pass); + } + + return num_indices; +} U32 LLVOAvatar::renderTransparent(BOOL first_pass) { - U32 num_indices = 0; - if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) ) - { + U32 num_indices = 0; + if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) ) + { gGL.flush(); - LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); - if (skirt_mesh) - { - num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE); - } - first_pass = FALSE; + LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); + if (skirt_mesh) + { + num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE); + } + first_pass = FALSE; gGL.flush(); - } + } - if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) - { - if (LLPipeline::sImpostorRender) - { + if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) + { + if (LLPipeline::sImpostorRender) + { gGL.flush(); - } - - if (isTextureVisible(TEX_HEAD_BAKED)) - { - LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); - if (eyelash_mesh) - { - num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL)) - { - LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); - if (hair_mesh) - { - num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - if (LLPipeline::sImpostorRender) - { + } + + if (isTextureVisible(TEX_HEAD_BAKED)) + { + LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); + if (eyelash_mesh) + { + num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL)) + { + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + if (hair_mesh) + { + num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } + if (LLPipeline::sImpostorRender) + { gGL.flush(); - } - } - - return num_indices; + } + } + + return num_indices; } //----------------------------------------------------------------------------- @@ -5238,399 +5238,399 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) //----------------------------------------------------------------------------- U32 LLVOAvatar::renderRigid() { - U32 num_indices = 0; + U32 num_indices = 0; - if (!mIsBuilt) - { - return 0; - } + if (!mIsBuilt) + { + return 0; + } - if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead())) - { - return 0; - } + if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead())) + { + return 0; + } - if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) - { - LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); - LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); - if (eyeball_left) - { - num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy); - } - if(eyeball_right) - { - num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy); - } - } + if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) + { + LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); + LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); + if (eyeball_left) + { + num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy); + } + if(eyeball_right) + { + num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy); + } + } - return num_indices; + return num_indices; } U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) { - if (!mImpostor.isComplete()) - { - return 0; - } - - LLVector3 pos(getRenderPosition()+mImpostorOffset); - LLVector3 at = (pos - LLViewerCamera::getInstance()->getOrigin()); - at.normalize(); - LLVector3 left = LLViewerCamera::getInstance()->getUpAxis() % at; - LLVector3 up = at%left; - - left *= mImpostorDim.mV[0]; - up *= mImpostorDim.mV[1]; - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_IMPOSTORS)) - { - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ADD); - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - - // gGL.begin(LLRender::QUADS); - // gGL.vertex3fv((pos+left-up).mV); - // gGL.vertex3fv((pos-left-up).mV); - // gGL.vertex3fv((pos-left+up).mV); - // gGL.vertex3fv((pos+left+up).mV); - // gGL.end(); - - - gGL.begin(LLRender::LINES); - gGL.color4f(1.f,1.f,1.f,1.f); - F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f); - glLineWidth(thickness); - gGL.vertex3fv((pos+left-up).mV); - gGL.vertex3fv((pos-left-up).mV); - gGL.vertex3fv((pos-left-up).mV); - gGL.vertex3fv((pos-left+up).mV); - gGL.vertex3fv((pos-left+up).mV); - gGL.vertex3fv((pos+left+up).mV); - gGL.vertex3fv((pos+left+up).mV); - gGL.vertex3fv((pos+left-up).mV); - gGL.end(); - gGL.flush(); - } - { - gGL.flush(); - - gGL.color4ubv(color.mV); - gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0,0); - gGL.vertex3fv((pos+left-up).mV); - gGL.texCoord2f(1,0); - gGL.vertex3fv((pos-left-up).mV); - gGL.texCoord2f(1,1); - gGL.vertex3fv((pos-left+up).mV); - gGL.texCoord2f(0,1); - gGL.vertex3fv((pos+left+up).mV); - gGL.end(); - gGL.flush(); - } - - return 6; + if (!mImpostor.isComplete()) + { + return 0; + } + + LLVector3 pos(getRenderPosition()+mImpostorOffset); + LLVector3 at = (pos - LLViewerCamera::getInstance()->getOrigin()); + at.normalize(); + LLVector3 left = LLViewerCamera::getInstance()->getUpAxis() % at; + LLVector3 up = at%left; + + left *= mImpostorDim.mV[0]; + up *= mImpostorDim.mV[1]; + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_IMPOSTORS)) + { + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ADD); + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + + // gGL.begin(LLRender::QUADS); + // gGL.vertex3fv((pos+left-up).mV); + // gGL.vertex3fv((pos-left-up).mV); + // gGL.vertex3fv((pos-left+up).mV); + // gGL.vertex3fv((pos+left+up).mV); + // gGL.end(); + + + gGL.begin(LLRender::LINES); + gGL.color4f(1.f,1.f,1.f,1.f); + F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f); + glLineWidth(thickness); + gGL.vertex3fv((pos+left-up).mV); + gGL.vertex3fv((pos-left-up).mV); + gGL.vertex3fv((pos-left-up).mV); + gGL.vertex3fv((pos-left+up).mV); + gGL.vertex3fv((pos-left+up).mV); + gGL.vertex3fv((pos+left+up).mV); + gGL.vertex3fv((pos+left+up).mV); + gGL.vertex3fv((pos+left-up).mV); + gGL.end(); + gGL.flush(); + } + { + gGL.flush(); + + gGL.color4ubv(color.mV); + gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0,0); + gGL.vertex3fv((pos+left-up).mV); + gGL.texCoord2f(1,0); + gGL.vertex3fv((pos-left-up).mV); + gGL.texCoord2f(1,1); + gGL.vertex3fv((pos-left+up).mV); + gGL.texCoord2f(0,1); + gGL.vertex3fv((pos+left+up).mV); + gGL.end(); + gGL.flush(); + } + + return 6; } bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set& ids) const { - for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) - { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); - if (imagep && imagep->getDiscardLevel()!=0) - { - return false; - } - } - return true; + for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); + if (imagep && imagep->getDiscardLevel()!=0) + { + return false; + } + } + return true; } bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const { - std::set local_ids; - collectLocalTextureUUIDs(local_ids); - return allTexturesCompletelyDownloaded(local_ids); + std::set local_ids; + collectLocalTextureUUIDs(local_ids); + return allTexturesCompletelyDownloaded(local_ids); } bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const { - std::set baked_ids; - collectBakedTextureUUIDs(baked_ids); - return allTexturesCompletelyDownloaded(baked_ids); + std::set baked_ids; + collectBakedTextureUUIDs(baked_ids); + return allTexturesCompletelyDownloaded(baked_ids); } std::string LLVOAvatar::bakedTextureOriginInfo() { - std::string result; - - std::set baked_ids; - collectBakedTextureUUIDs(baked_ids); - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex; - LLViewerFetchedTexture *imagep = - LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); - if (!imagep || - imagep->getID() == IMG_DEFAULT || - imagep->getID() == IMG_DEFAULT_AVATAR) - - { - result += "-"; - } - else - { - bool has_url = false, has_host = false; - if (!imagep->getUrl().empty()) - { - has_url = true; - } - if (imagep->getTargetHost().isOk()) - { - has_host = true; - } - S32 discard = imagep->getDiscardLevel(); - if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url - else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim - else if (has_host && has_url) result += discard ? "x" : "X"; // both origins? - else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin? - if (discard != 0) - { - result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel()); - } - } - - } - return result; + std::string result; + + std::set baked_ids; + collectBakedTextureUUIDs(baked_ids); + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex; + LLViewerFetchedTexture *imagep = + LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); + if (!imagep || + imagep->getID() == IMG_DEFAULT || + imagep->getID() == IMG_DEFAULT_AVATAR) + + { + result += "-"; + } + else + { + bool has_url = false, has_host = false; + if (!imagep->getUrl().empty()) + { + has_url = true; + } + if (imagep->getTargetHost().isOk()) + { + has_host = true; + } + S32 discard = imagep->getDiscardLevel(); + if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url + else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim + else if (has_host && has_url) result += discard ? "x" : "X"; // both origins? + else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin? + if (discard != 0) + { + result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel()); + } + } + + } + return result; } S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set& ids) { - S32Bytes result(0); - for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) - { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); - if (imagep) - { - result += imagep->getTextureMemory(); - } - } - return result; -} - + S32Bytes result(0); + for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); + if (imagep) + { + result += imagep->getTextureMemory(); + } + } + return result; +} + void LLVOAvatar::collectLocalTextureUUIDs(std::set& ids) const { - for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) - { - LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index); - U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); - - LLViewerFetchedTexture *imagep = NULL; - for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) - { - imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE); - if (imagep) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index); - if (texture_dict && texture_dict->mIsLocalTexture) - { - ids.insert(imagep->getID()); - } - } - } - } - ids.erase(IMG_DEFAULT); - ids.erase(IMG_DEFAULT_AVATAR); - ids.erase(IMG_INVISIBLE); + for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) + { + LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + + LLViewerFetchedTexture *imagep = NULL; + for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) + { + imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE); + if (imagep) + { + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index); + if (texture_dict && texture_dict->mIsLocalTexture) + { + ids.insert(imagep->getID()); + } + } + } + } + ids.erase(IMG_DEFAULT); + ids.erase(IMG_DEFAULT_AVATAR); + ids.erase(IMG_INVISIBLE); } void LLVOAvatar::collectBakedTextureUUIDs(std::set& ids) const { - for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) - { - LLViewerFetchedTexture *imagep = NULL; - if (isIndexBakedTexture((ETextureIndex) texture_index)) - { - imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); - if (imagep) - { - ids.insert(imagep->getID()); - } - } - } - ids.erase(IMG_DEFAULT); - ids.erase(IMG_DEFAULT_AVATAR); - ids.erase(IMG_INVISIBLE); + for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) + { + LLViewerFetchedTexture *imagep = NULL; + if (isIndexBakedTexture((ETextureIndex) texture_index)) + { + imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); + if (imagep) + { + ids.insert(imagep->getID()); + } + } + } + ids.erase(IMG_DEFAULT); + ids.erase(IMG_DEFAULT_AVATAR); + ids.erase(IMG_INVISIBLE); } void LLVOAvatar::collectTextureUUIDs(std::set& ids) { - collectLocalTextureUUIDs(ids); - collectBakedTextureUUIDs(ids); + collectLocalTextureUUIDs(ids); + collectBakedTextureUUIDs(ids); } void LLVOAvatar::releaseOldTextures() { - S32Bytes current_texture_mem; - - // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE" - std::set baked_texture_ids; - collectBakedTextureUUIDs(baked_texture_ids); - S32Bytes new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids); - - std::set local_texture_ids; - collectLocalTextureUUIDs(local_texture_ids); - //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids); - - std::set new_texture_ids; - new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end()); - new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end()); - S32Bytes new_total_mem = totalTextureMemForUUIDS(new_texture_ids); - - //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); - //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL; - if (!isSelf() && new_total_mem > new_baked_mem) - { - LL_WARNS() << "extra local textures stored for non-self av" << LL_ENDL; - } - for (std::set::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it) - { - if (new_texture_ids.find(*it) == new_texture_ids.end()) - { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); - if (imagep) - { - current_texture_mem += imagep->getTextureMemory(); - if (imagep->getTextureState() == LLGLTexture::NO_DELETE) - { - // This will allow the texture to be deleted if not in use. - imagep->forceActive(); - - // This resets the clock to texture being flagged - // as unused, preventing the texture from being - // deleted immediately. If other avatars or - // objects are using it, it can still be flagged - // no-delete by them. - imagep->forceUpdateBindStats(); - } - } - } - } - mTextureIDs = new_texture_ids; + S32Bytes current_texture_mem; + + // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE" + std::set baked_texture_ids; + collectBakedTextureUUIDs(baked_texture_ids); + S32Bytes new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids); + + std::set local_texture_ids; + collectLocalTextureUUIDs(local_texture_ids); + //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids); + + std::set new_texture_ids; + new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end()); + new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end()); + S32Bytes new_total_mem = totalTextureMemForUUIDS(new_texture_ids); + + //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); + //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL; + if (!isSelf() && new_total_mem > new_baked_mem) + { + LL_WARNS() << "extra local textures stored for non-self av" << LL_ENDL; + } + for (std::set::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it) + { + if (new_texture_ids.find(*it) == new_texture_ids.end()) + { + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); + if (imagep) + { + current_texture_mem += imagep->getTextureMemory(); + if (imagep->getTextureState() == LLGLTexture::NO_DELETE) + { + // This will allow the texture to be deleted if not in use. + imagep->forceActive(); + + // This resets the clock to texture being flagged + // as unused, preventing the texture from being + // deleted immediately. If other avatars or + // objects are using it, it can still be flagged + // no-delete by them. + imagep->forceUpdateBindStats(); + } + } + } + } + mTextureIDs = new_texture_ids; } void LLVOAvatar::updateTextures() { - releaseOldTextures(); - - BOOL render_avatar = TRUE; - - if (mIsDummy) - { - return; - } - - if( isSelf() ) - { - render_avatar = TRUE; - } - else - { - if(!isVisible()) - { - return ;//do not update for invisible avatar. - } - - render_avatar = !mCulled; //visible and not culled. - } - - std::vector layer_baked; - // GL NOT ACTIVE HERE - *TODO - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex)); - // bind the texture so that they'll be decoded slightly - // inefficient, we can short-circuit this if we have to - if (render_avatar && !gGLManager.mIsDisabled) - { - if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded) - { - gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 )); - } - } - } - - mMaxPixelArea = 0.f; - mMinPixelArea = 99999999.f; - mHasGrey = FALSE; // debug - for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) - { - LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index); - U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); - const LLTextureEntry *te = getTE(texture_index); - - // getTE can return 0. - // Not sure yet why it does, but of course it crashes when te->mScale? gets used. - // Put safeguard in place so this corner case get better handling and does not result in a crash. - F32 texel_area_ratio = 1.0f; - if( te ) - { - texel_area_ratio = fabs(te->mScaleS * te->mScaleT); - } - else - { - LL_WARNS() << "getTE( " << texture_index << " ) returned 0" <getTexture((ETextureIndex)texture_index); - const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES; - if (texture_dict && texture_dict->mIsLocalTexture) - { - addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed); - } - } - } - if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar) - { - const S32 boost_level = getAvatarBakedBoostLevel(); - imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); - addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) - { - setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea))); - } + releaseOldTextures(); + + BOOL render_avatar = TRUE; + + if (mIsDummy) + { + return; + } + + if( isSelf() ) + { + render_avatar = TRUE; + } + else + { + if(!isVisible()) + { + return ;//do not update for invisible avatar. + } + + render_avatar = !mCulled; //visible and not culled. + } + + std::vector layer_baked; + // GL NOT ACTIVE HERE - *TODO + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex)); + // bind the texture so that they'll be decoded slightly + // inefficient, we can short-circuit this if we have to + if (render_avatar && !gGLManager.mIsDisabled) + { + if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded) + { + gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 )); + } + } + } + + mMaxPixelArea = 0.f; + mMinPixelArea = 99999999.f; + mHasGrey = FALSE; // debug + for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) + { + LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + const LLTextureEntry *te = getTE(texture_index); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + LL_WARNS() << "getTE( " << texture_index << " ) returned 0" <getTexture((ETextureIndex)texture_index); + const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES; + if (texture_dict && texture_dict->mIsLocalTexture) + { + addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed); + } + } + } + if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar) + { + const S32 boost_level = getAvatarBakedBoostLevel(); + imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); + addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); + } + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea))); + } } void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep, - F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked) + F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked) { - // No local texture stats for non-self avatars - return; + // No local texture stats for non-self avatars + return; } -const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames. +const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames. const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL = S32_MAX ; //frames void LLVOAvatar::checkTextureLoading() { - static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds + static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds - BOOL pause = !isVisible() ; - if(!pause) - { - mInvisibleTimer.reset() ; - } - if(mLoadedCallbacksPaused == pause) - { + BOOL pause = !isVisible() ; + if(!pause) + { + mInvisibleTimer.reset() ; + } + if(mLoadedCallbacksPaused == pause) + { if (!pause && mFirstFullyVisible && mLoadedCallbackTextures < mCallbackTextureList.size()) { // We still need to update 'loaded' textures count to decide on 'cloud' visibility @@ -5646,120 +5646,120 @@ void LLVOAvatar::checkTextureLoading() } } } - return ; - } - - if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty. - { - mLoadedCallbacksPaused = pause ; - mLoadedCallbackTextures = 0; - return ; //nothing to check. - } - - if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME) - { - return ; //have not been invisible for enough time. - } - - mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0; - - for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin(); - iter != mCallbackTextureList.end(); ++iter) - { - LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ; - if(tex) - { - if(pause)//pause texture fetching. - { - tex->pauseLoadedCallbacks(&mCallbackTextureList) ; - - //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames. - tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL); - tex->resetMaxVirtualSizeResetCounter() ; - } - else//unpause - { - static const F32 START_AREA = 100.f ; - - tex->unpauseLoadedCallbacks(&mCallbackTextureList) ; - tex->addTextureStats(START_AREA); //jump start the fetching again - - // technically shouldn't need to account for missing, but callback might not have happened yet - if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset()) - { - mLoadedCallbackTextures++; // consider it loaded (we have at least some data) - } - } - } - } - - if(!pause) - { - updateTextures() ; //refresh texture stats. - } - mLoadedCallbacksPaused = pause ; - return ; + return ; + } + + if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty. + { + mLoadedCallbacksPaused = pause ; + mLoadedCallbackTextures = 0; + return ; //nothing to check. + } + + if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME) + { + return ; //have not been invisible for enough time. + } + + mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0; + + for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin(); + iter != mCallbackTextureList.end(); ++iter) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ; + if(tex) + { + if(pause)//pause texture fetching. + { + tex->pauseLoadedCallbacks(&mCallbackTextureList) ; + + //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames. + tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL); + tex->resetMaxVirtualSizeResetCounter() ; + } + else//unpause + { + static const F32 START_AREA = 100.f ; + + tex->unpauseLoadedCallbacks(&mCallbackTextureList) ; + tex->addTextureStats(START_AREA); //jump start the fetching again + + // technically shouldn't need to account for missing, but callback might not have happened yet + if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset()) + { + mLoadedCallbackTextures++; // consider it loaded (we have at least some data) + } + } + } + } + + if(!pause) + { + updateTextures() ; //refresh texture stats. + } + mLoadedCallbacksPaused = pause ; + return ; } const F32 SELF_ADDITIONAL_PRI = 0.75f ; void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { - //Note: - //if this function is not called for the last MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL frames, - //the texture pipeline will stop fetching this texture. + //Note: + //if this function is not called for the last MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL frames, + //the texture pipeline will stop fetching this texture. - imagep->resetTextureStats(); - imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); - imagep->resetMaxVirtualSizeResetCounter() ; + imagep->resetTextureStats(); + imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); + imagep->resetMaxVirtualSizeResetCounter() ; - mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); - mMinPixelArea = llmin(pixel_area, mMinPixelArea); - imagep->addTextureStats(pixel_area / texel_area_ratio); - imagep->setBoostLevel(boost_level); + mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); + mMinPixelArea = llmin(pixel_area, mMinPixelArea); + imagep->addTextureStats(pixel_area / texel_area_ratio); + imagep->setBoostLevel(boost_level); } -//virtual +//virtual void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep, const U32 index) { - setTEImage(te, imagep); + setTEImage(te, imagep); } -//virtual +//virtual LLViewerTexture* LLVOAvatar::getImage(const U8 te, const U32 index) const { - return getTEImage(te); + return getTEImage(te); } -//virtual +//virtual const LLTextureEntry* LLVOAvatar::getTexEntry(const U8 te_num) const { - return getTE(te_num); + return getTE(te_num); } -//virtual +//virtual void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te) { - setTE(index, te); + setTE(index, te); } const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) { - llassert(isIndexBakedTexture(ETextureIndex(te))); - std::string url = ""; - const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL(); - if (appearance_service_url.empty()) - { - // Probably a server-side issue if we get here: - LL_WARNS() << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << LL_ENDL; - return url; - } - - const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te); - if (texture_entry != NULL) - { - url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); - //LL_INFOS() << "baked texture url: " << url << LL_ENDL; - } - return url; + llassert(isIndexBakedTexture(ETextureIndex(te))); + std::string url = ""; + const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL(); + if (appearance_service_url.empty()) + { + // Probably a server-side issue if we get here: + LL_WARNS() << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << LL_ENDL; + return url; + } + + const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te); + if (texture_entry != NULL) + { + url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); + //LL_INFOS() << "baked texture url: " << url << LL_ENDL; + } + return url; } //----------------------------------------------------------------------------- @@ -5768,47 +5768,47 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) void LLVOAvatar::resolveHeightAgent(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &out_norm) { - LLVector3d in_pos_global, out_pos_global; + LLVector3d in_pos_global, out_pos_global; - in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent); - resolveHeightGlobal(in_pos_global, out_pos_global, out_norm); - out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); + in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent); + resolveHeightGlobal(in_pos_global, out_pos_global, out_norm); + out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); } void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm) { - LLViewerObject *obj; - LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj); + LLViewerObject *obj; + LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj); } void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm) { - LLVector3d zVec(0.0f, 0.0f, 0.5f); - LLVector3d p0 = inPos + zVec; - LLVector3d p1 = inPos - zVec; - LLViewerObject *obj; - LLWorld::getInstance()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj); - if (!obj) - { - mStepOnLand = TRUE; - mStepMaterial = 0; - mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f); - } - else - { - mStepOnLand = FALSE; - mStepMaterial = obj->getMaterial(); + LLVector3d zVec(0.0f, 0.0f, 0.5f); + LLVector3d p0 = inPos + zVec; + LLVector3d p1 = inPos - zVec; + LLViewerObject *obj; + LLWorld::getInstance()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj); + if (!obj) + { + mStepOnLand = TRUE; + mStepMaterial = 0; + mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f); + } + else + { + mStepOnLand = FALSE; + mStepMaterial = obj->getMaterial(); - // We want the primitive velocity, not our velocity... (which actually subtracts the - // step object velocity) - LLVector3 angularVelocity = obj->getAngularVelocity(); - LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent(); + // We want the primitive velocity, not our velocity... (which actually subtracts the + // step object velocity) + LLVector3 angularVelocity = obj->getAngularVelocity(); + LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent(); - LLVector3 linearComponent = angularVelocity % relativePos; -// LL_INFOS() << "Linear Component of Rotation Velocity " << linearComponent << LL_ENDL; - mStepObjectVelocity = obj->getVelocity() + linearComponent; - } + LLVector3 linearComponent = angularVelocity % relativePos; +// LL_INFOS() << "Linear Component of Rotation Velocity " << linearComponent << LL_ENDL; + mStepObjectVelocity = obj->getVelocity() + linearComponent; + } } @@ -5817,12 +5817,12 @@ void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos //----------------------------------------------------------------------------- const LLUUID& LLVOAvatar::getStepSound() const { - if ( mStepOnLand ) - { - return sStepSoundOnLand; - } + if ( mStepOnLand ) + { + return sStepSoundOnLand; + } - return sStepSounds[mStepMaterial]; + return sStepSounds[mStepMaterial]; } @@ -5831,106 +5831,106 @@ const LLUUID& LLVOAvatar::getStepSound() const //----------------------------------------------------------------------------- void LLVOAvatar::processAnimationStateChanges() { - if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) ) - { - startMotion(ANIM_AGENT_WALK_ADJUST); - stopMotion(ANIM_AGENT_FLY_ADJUST); - } - else if (mInAir && !isSitting()) - { - stopMotion(ANIM_AGENT_WALK_ADJUST); + if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) ) + { + startMotion(ANIM_AGENT_WALK_ADJUST); + stopMotion(ANIM_AGENT_FLY_ADJUST); + } + else if (mInAir && !isSitting()) + { + stopMotion(ANIM_AGENT_WALK_ADJUST); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_FLY_ADJUST); - } - } - else - { - stopMotion(ANIM_AGENT_WALK_ADJUST); - stopMotion(ANIM_AGENT_FLY_ADJUST); - } - - if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) ) - { + startMotion(ANIM_AGENT_FLY_ADJUST); + } + } + else + { + stopMotion(ANIM_AGENT_WALK_ADJUST); + stopMotion(ANIM_AGENT_FLY_ADJUST); + } + + if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) ) + { if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_TARGET); + startMotion(ANIM_AGENT_TARGET); } - stopMotion(ANIM_AGENT_BODY_NOISE); - } - else - { - stopMotion(ANIM_AGENT_TARGET); + stopMotion(ANIM_AGENT_BODY_NOISE); + } + else + { + stopMotion(ANIM_AGENT_TARGET); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_BODY_NOISE); - } - } - - // clear all current animations - AnimIterator anim_it; - for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();) - { - AnimIterator found_anim = mSignaledAnimations.find(anim_it->first); - - // playing, but not signaled, so stop - if (found_anim == mSignaledAnimations.end()) - { - processSingleAnimationStateChange(anim_it->first, FALSE); - mPlayingAnimations.erase(anim_it++); - continue; - } - - ++anim_it; - } - - // if jellydolled, shelve all playing animations - if (getOverallAppearance() != AOA_NORMAL) - { - mPlayingAnimations.clear(); - } - - // start up all new anims - if (getOverallAppearance() == AOA_NORMAL) - { - for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) - { - AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); - - // signaled but not playing, or different sequence id, start motion - if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) - { - if (processSingleAnimationStateChange(anim_it->first, TRUE)) - { - mPlayingAnimations[anim_it->first] = anim_it->second; - ++anim_it; - continue; - } - } - - ++anim_it; - } - } - - // clear source information for animations which have been stopped - if (isSelf()) - { - AnimSourceIterator source_it = mAnimationSources.begin(); - - for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();) - { - if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end()) - { - mAnimationSources.erase(source_it++); - } - else - { - ++source_it; - } - } - } - - stop_glerror(); + startMotion(ANIM_AGENT_BODY_NOISE); + } + } + + // clear all current animations + AnimIterator anim_it; + for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();) + { + AnimIterator found_anim = mSignaledAnimations.find(anim_it->first); + + // playing, but not signaled, so stop + if (found_anim == mSignaledAnimations.end()) + { + processSingleAnimationStateChange(anim_it->first, FALSE); + mPlayingAnimations.erase(anim_it++); + continue; + } + + ++anim_it; + } + + // if jellydolled, shelve all playing animations + if (getOverallAppearance() != AOA_NORMAL) + { + mPlayingAnimations.clear(); + } + + // start up all new anims + if (getOverallAppearance() == AOA_NORMAL) + { + for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) + { + AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); + + // signaled but not playing, or different sequence id, start motion + if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) + { + if (processSingleAnimationStateChange(anim_it->first, TRUE)) + { + mPlayingAnimations[anim_it->first] = anim_it->second; + ++anim_it; + continue; + } + } + + ++anim_it; + } + } + + // clear source information for animations which have been stopped + if (isSelf()) + { + AnimSourceIterator source_it = mAnimationSources.begin(); + + for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();) + { + if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end()) + { + mAnimationSources.erase(source_it++); + } + else + { + ++source_it; + } + } + } + + stop_glerror(); } @@ -5944,66 +5944,66 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL // cause constant jiggling of the body or camera. Possible // compromise is to do it on animation changes: computeBodySize(); - - BOOL result = FALSE; - - if ( start ) // start animation - { - if (anim_id == ANIM_AGENT_TYPE) - { - if (gAudiop) - { - LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition()); - if (LLViewerParcelMgr::getInstance()->canHearSound(char_pos_global) - && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) - { - // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed - // to support both spatialized and non-spatialized instances of the same sound - //if (isSelf()) - //{ - // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); - //} - //else - { + + BOOL result = FALSE; + + if ( start ) // start animation + { + if (anim_id == ANIM_AGENT_TYPE) + { + if (gAudiop) + { + LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition()); + if (LLViewerParcelMgr::getInstance()->canHearSound(char_pos_global) + && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) + { + // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed + // to support both spatialized and non-spatialized instances of the same sound + //if (isSelf()) + //{ + // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); + //} + //else + { static LLCachedControl ui_snd_string(gSavedSettings, "UISndTyping"); - LLUUID sound_id = LLUUID(ui_snd_string); - gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global); - } - } - } - } - else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) - { - sitDown(TRUE); - } - - - if (startMotion(anim_id)) - { - result = TRUE; - } - else - { - LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL; - } - } - else //stop animation - { - if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) - { - sitDown(FALSE); - } - if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb()) - { - // re-assert DND tag animation - gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START); - return result; - } - stopMotion(anim_id); - result = TRUE; - } - - return result; + LLUUID sound_id = LLUUID(ui_snd_string); + gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global); + } + } + } + } + else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) + { + sitDown(TRUE); + } + + + if (startMotion(anim_id)) + { + result = TRUE; + } + else + { + LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL; + } + } + else //stop animation + { + if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) + { + sitDown(FALSE); + } + if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb()) + { + // re-assert DND tag animation + gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START); + return result; + } + stopMotion(anim_id); + result = TRUE; + } + + return result; } //----------------------------------------------------------------------------- @@ -6011,14 +6011,14 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL //----------------------------------------------------------------------------- BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims) const { - for (S32 i = 0; i < num_anims; i++) - { - if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end()) - { - return TRUE; - } - } - return FALSE; + for (S32 i = 0; i < num_anims; i++) + { + if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end()) + { + return TRUE; + } + } + return FALSE; } //----------------------------------------------------------------------------- @@ -6026,8 +6026,8 @@ BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_ //----------------------------------------------------------------------------- void LLVOAvatar::resetAnimations() { - LLKeyframeMotion::flushKeyframeCache(); - flushAllMotions(); + LLKeyframeMotion::flushKeyframeCache(); + flushAllMotions(); } // Override selectively based on avatar sex and whether we're using new @@ -6035,52 +6035,52 @@ void LLVOAvatar::resetAnimations() LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) { static LLCachedControl use_new_walk_run(gSavedSettings, "UseNewWalkRun"); - LLUUID result = id; - - // start special case female walk for female avatars - if (getSex() == SEX_FEMALE) - { - if (id == ANIM_AGENT_WALK) - { - if (use_new_walk_run) - result = ANIM_AGENT_FEMALE_WALK_NEW; - else - result = ANIM_AGENT_FEMALE_WALK; - } - else if (id == ANIM_AGENT_RUN) - { - // There is no old female run animation, so only override - // in one case. - if (use_new_walk_run) - result = ANIM_AGENT_FEMALE_RUN_NEW; - } - else if (id == ANIM_AGENT_SIT) - { - result = ANIM_AGENT_SIT_FEMALE; - } - } - else - { - // Male avatar. - if (id == ANIM_AGENT_WALK) - { - if (use_new_walk_run) - result = ANIM_AGENT_WALK_NEW; - } - else if (id == ANIM_AGENT_RUN) - { - if (use_new_walk_run) - result = ANIM_AGENT_RUN_NEW; - } - // keeps in sync with setSex() related code (viewer controls sit's sex) - else if (id == ANIM_AGENT_SIT_FEMALE) - { - result = ANIM_AGENT_SIT; - } - - } - - return result; + LLUUID result = id; + + // start special case female walk for female avatars + if (getSex() == SEX_FEMALE) + { + if (id == ANIM_AGENT_WALK) + { + if (use_new_walk_run) + result = ANIM_AGENT_FEMALE_WALK_NEW; + else + result = ANIM_AGENT_FEMALE_WALK; + } + else if (id == ANIM_AGENT_RUN) + { + // There is no old female run animation, so only override + // in one case. + if (use_new_walk_run) + result = ANIM_AGENT_FEMALE_RUN_NEW; + } + else if (id == ANIM_AGENT_SIT) + { + result = ANIM_AGENT_SIT_FEMALE; + } + } + else + { + // Male avatar. + if (id == ANIM_AGENT_WALK) + { + if (use_new_walk_run) + result = ANIM_AGENT_WALK_NEW; + } + else if (id == ANIM_AGENT_RUN) + { + if (use_new_walk_run) + result = ANIM_AGENT_RUN_NEW; + } + // keeps in sync with setSex() related code (viewer controls sit's sex) + else if (id == ANIM_AGENT_SIT_FEMALE) + { + result = ANIM_AGENT_SIT; + } + + } + + return result; } @@ -6091,21 +6091,21 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) //----------------------------------------------------------------------------- BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) { - LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; + LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; - LLUUID remap_id = remapMotionID(id); + LLUUID remap_id = remapMotionID(id); - if (remap_id != id) - { - LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL; - } + if (remap_id != id) + { + LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL; + } - if (isSelf() && remap_id == ANIM_AGENT_AWAY) - { - gAgent.setAFK(); - } + if (isSelf() && remap_id == ANIM_AGENT_AWAY) + { + gAgent.setAFK(); + } - return LLCharacter::startMotion(remap_id, time_offset); + return LLCharacter::startMotion(remap_id, time_offset); } //----------------------------------------------------------------------------- @@ -6113,21 +6113,21 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) //----------------------------------------------------------------------------- BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate) { - LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; + LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; + + LLUUID remap_id = remapMotionID(id); - LLUUID remap_id = remapMotionID(id); - - if (remap_id != id) - { - LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL; - } + if (remap_id != id) + { + LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL; + } - if (isSelf()) - { - gAgent.onAnimStop(remap_id); - } + if (isSelf()) + { + gAgent.onAnimStop(remap_id); + } - return LLCharacter::stopMotion(remap_id, stop_immediate); + return LLCharacter::stopMotion(remap_id, stop_immediate); } //----------------------------------------------------------------------------- @@ -6136,7 +6136,7 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate) // virtual bool LLVOAvatar::hasMotionFromSource(const LLUUID& source_id) { - return false; + return false; } //----------------------------------------------------------------------------- @@ -6152,8 +6152,8 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id) //----------------------------------------------------------------------------- void LLVOAvatar::addDebugText(const std::string& text) { - mDebugText.append(1, '\n'); - mDebugText.append(text); + mDebugText.append(1, '\n'); + mDebugText.append(text); } //----------------------------------------------------------------------------- @@ -6161,7 +6161,7 @@ void LLVOAvatar::addDebugText(const std::string& text) //----------------------------------------------------------------------------- const LLUUID& LLVOAvatar::getID() const { - return mID; + return mID; } //----------------------------------------------------------------------------- @@ -6170,33 +6170,33 @@ const LLUUID& LLVOAvatar::getID() const // RN: avatar joints are multi-rooted to include screen-based attachments LLJoint *LLVOAvatar::getJoint( const std::string &name ) { - joint_map_t::iterator iter = mJointMap.find(name); - - LLJoint* jointp = NULL; - - if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table - if (mJointAliasMap.empty()) - { - getJointAliases(); - } - joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); - std::string canonical_name; - if (alias_iter != mJointAliasMap.end()) - { - canonical_name = alias_iter->second; - } - else - { - canonical_name = name; - } - jointp = mRoot->findJoint(canonical_name); - mJointMap[name] = jointp; - } - else - { //return cached pointer - jointp = iter->second; - } + joint_map_t::iterator iter = mJointMap.find(name); + + LLJoint* jointp = NULL; + + if (iter == mJointMap.end() || iter->second == NULL) + { //search for joint and cache found joint in lookup table + if (mJointAliasMap.empty()) + { + getJointAliases(); + } + joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); + std::string canonical_name; + if (alias_iter != mJointAliasMap.end()) + { + canonical_name = alias_iter->second; + } + else + { + canonical_name = name; + } + jointp = mRoot->findJoint(canonical_name); + mJointMap[name] = jointp; + } + else + { //return cached pointer + jointp = iter->second; + } #ifndef LL_RELEASE_FOR_DOWNLOAD if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot") @@ -6204,7 +6204,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) llassert(getJoint(jointp->getJointNum())==jointp); } #endif - return jointp; + return jointp; } LLJoint *LLVOAvatar::getJoint( S32 joint_num ) @@ -6232,8 +6232,8 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num ) } } } - - llassert(!pJoint || pJoint->getJointNum() == joint_num); + + llassert(!pJoint || pJoint->getJointNum() == joint_num); return pJoint; } @@ -6246,31 +6246,31 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num ) // static bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) { - mesh_id.setNull(); - - //If a VO has a skin that we'll reset the joint positions to their default - if ( pVO && pVO->mDrawable ) - { - LLVOVolume* pVObj = pVO->mDrawable->getVOVolume(); - if ( pVObj ) - { - const LLMeshSkinInfo* pSkinData = pVObj->getSkinInfo(); - if (pSkinData - && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig - && pSkinData->mAlternateBindMatrix.size() > 0 ) - { - mesh_id = pSkinData->mMeshID; - return true; - } - } - } - return false; + mesh_id.setNull(); + + //If a VO has a skin that we'll reset the joint positions to their default + if ( pVO && pVO->mDrawable ) + { + LLVOVolume* pVObj = pVO->mDrawable->getVOVolume(); + if ( pVObj ) + { + const LLMeshSkinInfo* pSkinData = pVObj->getSkinInfo(); + if (pSkinData + && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig + && pSkinData->mAlternateBindMatrix.size() > 0 ) + { + mesh_id = pSkinData->mMeshID; + return true; + } + } + } + return false; } bool LLVOAvatar::jointIsRiggedTo(const LLJoint *joint) const { if (joint) - { + { const LLJointRiggingInfoTab& tab = mJointRiggingInfoTab; S32 joint_num = joint->getJointNum(); if (joint_num < tab.size() && tab[joint_num].isRiggedTo()) @@ -6286,25 +6286,25 @@ void LLVOAvatar::clearAttachmentOverrides() LLScopedContextString str("clearAttachmentOverrides " + getFullname()); for (S32 i=0; iclearAttachmentPosOverrides(); - pJoint->clearAttachmentScaleOverrides(); + pJoint->clearAttachmentPosOverrides(); + pJoint->clearAttachmentScaleOverrides(); } - } + } if (mPelvisFixups.count()>0) { mPelvisFixups.clear(); LLJoint* pJointPelvis = getJoint("mPelvis"); if (pJointPelvis) - { - pJointPelvis->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); + { + pJointPelvis->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); } - postPelvisSetRecalc(); - } + postPelvisSetRecalc(); + } mActiveOverrideMeshes.clear(); onActiveOverrideMeshesChanged(); @@ -6319,32 +6319,32 @@ void LLVOAvatar::rebuildAttachmentOverrides() LL_DEBUGS("AnimatedObjects") << "rebuilding" << LL_ENDL; dumpStack("AnimatedObjectsStack"); - + clearAttachmentOverrides(); // Handle the case that we're resetting the skeleton of an animated object. LLControlAvatar *control_av = dynamic_cast(this); if (control_av) - { + { LLVOVolume *volp = control_av->mRootVolp; if (volp) { - LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count " + LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count " << (S32) (1+volp->numChildren()) << LL_ENDL; addAttachmentOverridesForObject(volp); } } // Attached objects - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment *attachment_pt = (*iter).second; + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment *attachment_pt = (*iter).second; if (attachment_pt) { for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin(); - at_it != attachment_pt->mAttachedObjects.end(); ++at_it) + at_it != attachment_pt->mAttachedObjects.end(); ++at_it) { LLViewerObject *vo = at_it->get(); // Attached animated objects affect joints in their control @@ -6372,7 +6372,7 @@ void LLVOAvatar::updateAttachmentOverrides() dumpStack("AnimatedObjectsStack"); std::set meshes_seen; - + // Handle the case that we're updating the skeleton of an animated object. LLControlAvatar *control_av = dynamic_cast(this); if (control_av) @@ -6380,22 +6380,22 @@ void LLVOAvatar::updateAttachmentOverrides() LLVOVolume *volp = control_av->mRootVolp; if (volp) { - LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count " + LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count " << (S32) (1+volp->numChildren()) << LL_ENDL; addAttachmentOverridesForObject(volp, &meshes_seen); } } // Attached objects - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment *attachment_pt = (*iter).second; + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment *attachment_pt = (*iter).second; if (attachment_pt) { for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin(); - at_it != attachment_pt->mAttachedObjects.end(); ++at_it) + at_it != attachment_pt->mAttachedObjects.end(); ++at_it) { LLViewerObject *vo = at_it->get(); // Attached animated objects affect joints in their control @@ -6409,8 +6409,8 @@ void LLVOAvatar::updateAttachmentOverrides() } // Remove meshes that are no longer present on the skeleton - // have to work with a copy because removeAttachmentOverrides() will change mActiveOverrideMeshes. - std::set active_override_meshes = mActiveOverrideMeshes; + // have to work with a copy because removeAttachmentOverrides() will change mActiveOverrideMeshes. + std::set active_override_meshes = mActiveOverrideMeshes; for (std::set::iterator it = active_override_meshes.begin(); it != active_override_meshes.end(); ++it) { if (meshes_seen.find(*it) == meshes_seen.end()) @@ -6493,63 +6493,63 @@ void LLVOAvatar::notifyAttachmentMeshLoaded() void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set* meshes_seen, bool recursive) { if (vo->getAvatar() != this && vo->getAvatarAncestor() != this) - { - LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; + { + LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; return; - } + } LLScopedContextString str("addAttachmentOverridesForObject " + getFullname()); - if (getOverallAppearance() != AOA_NORMAL) - { - return; - } - + if (getOverallAppearance() != AOA_NORMAL) + { + return; + } + LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL; dumpStack("AnimatedObjectsStack"); - - // Process all children + + // Process all children if (recursive) { - LLViewerObject::const_child_list_t& children = vo->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) - { - LLViewerObject *childp = *it; + LLViewerObject::const_child_list_t& children = vo->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; addAttachmentOverridesForObject(childp, meshes_seen, true); } - } + } - LLVOVolume *vobj = dynamic_cast(vo); - bool pelvisGotSet = false; + LLVOVolume *vobj = dynamic_cast(vo); + bool pelvisGotSet = false; - if (!vobj) - { - return; - } + if (!vobj) + { + return; + } - LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot(); + LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot(); LL_DEBUGS("AnimatedObjects") << "trying to add attachment overrides for root object " << root_object->getID() << " prim is " << vobj << LL_ENDL; - if (vobj->isMesh() && - ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) - { + if (vobj->isMesh() && + ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) + { LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " mesh asset not loaded" << LL_ENDL; - return; - } - const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo(); + return; + } + const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo(); - if ( vobj && vobj->isMesh() && pSkinData ) - { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( vobj && vobj->isMesh() && pSkinData ) + { + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); const int jointCnt = pSkinData->mJointNames.size(); if ((bindCnt > 0) && (bindCnt != jointCnt)) { LL_WARNS_ONCE() << "invalid mesh, bindCnt " << bindCnt << "!= jointCnt " << jointCnt << ", joint overrides will be ignored." << LL_ENDL; } - if ((bindCnt > 0) && (bindCnt == jointCnt)) - { - const F32 pelvisZOffset = pSkinData->mPelvisOffset; - const LLUUID& mesh_id = pSkinData->mMeshID; + if ((bindCnt > 0) && (bindCnt == jointCnt)) + { + const F32 pelvisZOffset = pSkinData->mPelvisOffset; + const LLUUID& mesh_id = pSkinData->mMeshID; if (meshes_seen) { @@ -6558,38 +6558,38 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::setgetID() << ", already loaded" << LL_ENDL; } else { - LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id + LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id << " to root object " << root_object->getID() << LL_ENDL; } - bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; - if ( fullRig && !mesh_overrides_loaded ) - { - for ( int i=0; imJointNames[i].c_str(); - LLJoint* pJoint = getJoint( lookingForJoint ); - if (pJoint) - { - const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation()); + bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; + if ( fullRig && !mesh_overrides_loaded ) + { + for ( int i=0; imJointNames[i].c_str(); + LLJoint* pJoint = getJoint( lookingForJoint ); + if (pJoint) + { + const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation()); if (pJoint->aboveJointPosThreshold(jointPos)) { bool override_changed; pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); - + if (override_changed) { //If joint is a pelvis then handle old/new pelvis to foot values if ( lookingForJoint == "mPelvis" ) - { - pelvisGotSet = true; - } + { + pelvisGotSet = true; + } } if (pSkinData->mLockScaleIfJointPosition) { @@ -6598,36 +6598,36 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::setaddAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString()); } } - } - } - if (pelvisZOffset != 0.0F) - { + } + } + if (pelvisZOffset != 0.0F) + { F32 pelvis_fixup_before; bool has_fixup_before = hasPelvisFixup(pelvis_fixup_before); - addPelvisFixup( pelvisZOffset, mesh_id ); - F32 pelvis_fixup_after; + addPelvisFixup( pelvisZOffset, mesh_id ); + F32 pelvis_fixup_after; hasPelvisFixup(pelvis_fixup_after); // Don't have to check bool here because we just added it... if (!has_fixup_before || (pelvis_fixup_before != pelvis_fixup_after)) { - pelvisGotSet = true; + pelvisGotSet = true; } - - } + + } mActiveOverrideMeshes.insert(mesh_id); onActiveOverrideMeshesChanged(); - } - } - } + } + } + } else { LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " not mesh or no pSkinData" << LL_ENDL; } - - //Rebuild body data if we altered joints/pelvis - if ( pelvisGotSet ) - { - postPelvisSetRecalc(); - } + + //Rebuild body data if we altered joints/pelvis + if ( pelvisGotSet ) + { + postPelvisSetRecalc(); + } } //----------------------------------------------------------------------------- @@ -6640,26 +6640,26 @@ void LLVOAvatar::getAttachmentOverrideNames(std::set& pos_names, st LLUUID mesh_id; // Bones - for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); + for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); iter != mSkeleton.end(); ++iter) - { - const LLJoint* pJoint = (*iter); - if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) - { + { + const LLJoint* pJoint = (*iter); + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { pos_names.insert(pJoint->getName()); - } - if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) - { + } + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { scale_names.insert(pJoint->getName()); - } - } + } + } // Attachment points - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment *attachment_pt = (*iter).second; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) { pos_names.insert(attachment_pt->getName()); @@ -6707,28 +6707,28 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const S32 count = 0; // Bones - for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); + for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); iter != mSkeleton.end(); ++iter) - { - const LLJoint* pJoint = (*iter); - if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) - { - pJoint->showAttachmentPosOverrides(getFullname()); + { + const LLJoint* pJoint = (*iter); + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { + pJoint->showAttachmentPosOverrides(getFullname()); count++; - } - if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) - { - pJoint->showAttachmentScaleOverrides(getFullname()); + } + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { + pJoint->showAttachmentScaleOverrides(getFullname()); count++; } - } + } // Attachment points - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment *attachment_pt = (*iter).second; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) { attachment_pt->showAttachmentPosOverrides(getFullname()); @@ -6749,53 +6749,53 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo) { if (vo->getAvatar() != this && vo->getAvatarAncestor() != this) - { - LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; + { + LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; return; - } - - // Process all children - LLViewerObject::const_child_list_t& children = vo->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) - { - LLViewerObject *childp = *it; - removeAttachmentOverridesForObject(childp); - } - - // Process self. - LLUUID mesh_id; - if (getRiggedMeshID(vo,mesh_id)) - { - removeAttachmentOverridesForObject(mesh_id); - } + } + + // Process all children + LLViewerObject::const_child_list_t& children = vo->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; + removeAttachmentOverridesForObject(childp); + } + + // Process self. + LLUUID mesh_id; + if (getRiggedMeshID(vo,mesh_id)) + { + removeAttachmentOverridesForObject(mesh_id); + } } //----------------------------------------------------------------------------- // removeAttachmentOverridesForObject //----------------------------------------------------------------------------- void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) -{ - LLJoint* pJointPelvis = getJoint("mPelvis"); +{ + LLJoint* pJointPelvis = getJoint("mPelvis"); const std::string av_string = avString(); for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) - { + { LLJoint *pJoint = getJoint(joint_num); - if ( pJoint ) - { + if ( pJoint ) + { bool dummy; // unused - pJoint->removeAttachmentPosOverride(mesh_id, av_string, dummy); - pJoint->removeAttachmentScaleOverride(mesh_id, av_string); - } - if ( pJoint && pJoint == pJointPelvis) - { - removePelvisFixup( mesh_id ); - // SL-315 - pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); - } - } - - postPelvisSetRecalc(); + pJoint->removeAttachmentPosOverride(mesh_id, av_string, dummy); + pJoint->removeAttachmentScaleOverride(mesh_id, av_string); + } + if ( pJoint && pJoint == pJointPelvis) + { + removePelvisFixup( mesh_id ); + // SL-315 + pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); + } + } + + postPelvisSetRecalc(); mActiveOverrideMeshes.erase(mesh_id); onActiveOverrideMeshesChanged(); @@ -6805,14 +6805,14 @@ void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) //----------------------------------------------------------------------------- LLVector3 LLVOAvatar::getCharacterPosition() { - if (mDrawable.notNull()) - { - return mDrawable->getPositionAgent(); - } - else - { - return getPositionAgent(); - } + if (mDrawable.notNull()) + { + return mDrawable->getPositionAgent(); + } + else + { + return getPositionAgent(); + } } @@ -6821,7 +6821,7 @@ LLVector3 LLVOAvatar::getCharacterPosition() //----------------------------------------------------------------------------- LLQuaternion LLVOAvatar::getCharacterRotation() { - return getRotation(); + return getRotation(); } @@ -6830,7 +6830,7 @@ LLQuaternion LLVOAvatar::getCharacterRotation() //----------------------------------------------------------------------------- LLVector3 LLVOAvatar::getCharacterVelocity() { - return getVelocity() - mStepObjectVelocity; + return getVelocity() - mStepObjectVelocity; } @@ -6839,7 +6839,7 @@ LLVector3 LLVOAvatar::getCharacterVelocity() //----------------------------------------------------------------------------- LLVector3 LLVOAvatar::getCharacterAngularVelocity() { - return getAngularVelocity(); + return getAngularVelocity(); } //----------------------------------------------------------------------------- @@ -6847,22 +6847,22 @@ LLVector3 LLVOAvatar::getCharacterAngularVelocity() //----------------------------------------------------------------------------- void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &outNorm) { - LLVector3d z_vec(0.0f, 0.0f, 1.0f); - LLVector3d p0_global, p1_global; + LLVector3d z_vec(0.0f, 0.0f, 1.0f); + LLVector3d p0_global, p1_global; + + if (isUIAvatar()) + { + outNorm.setVec(z_vec); + out_pos_agent = in_pos_agent; + return; + } - if (isUIAvatar()) - { - outNorm.setVec(z_vec); - out_pos_agent = in_pos_agent; - return; - } - - p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec; - p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec; - LLViewerObject *obj; - LLVector3d out_pos_global; - LLWorld::getInstance()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj); - out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); + p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec; + p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec; + LLViewerObject *obj; + LLVector3d out_pos_global; + LLWorld::getInstance()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj); + out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); } //----------------------------------------------------------------------------- @@ -6870,7 +6870,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age //----------------------------------------------------------------------------- F32 LLVOAvatar::getTimeDilation() { - return mRegionp ? mRegionp->getTimeDilation() : 1.f; + return mRegionp ? mRegionp->getTimeDilation() : 1.f; } @@ -6879,11 +6879,11 @@ F32 LLVOAvatar::getTimeDilation() //----------------------------------------------------------------------------- F32 LLVOAvatar::getPixelArea() const { - if (isUIAvatar()) - { - return 100000.f; - } - return mPixelArea; + if (isUIAvatar()) + { + return 100000.f; + } + return mPixelArea; } @@ -6891,17 +6891,17 @@ F32 LLVOAvatar::getPixelArea() const //----------------------------------------------------------------------------- // LLVOAvatar::getPosGlobalFromAgent() //----------------------------------------------------------------------------- -LLVector3d LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position) +LLVector3d LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position) { - return gAgent.getPosGlobalFromAgent(position); + return gAgent.getPosGlobalFromAgent(position); } //----------------------------------------------------------------------------- // getPosAgentFromGlobal() //----------------------------------------------------------------------------- -LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position) +LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position) { - return gAgent.getPosAgentFromGlobal(position); + return gAgent.getPosAgentFromGlobal(position); } @@ -6911,7 +6911,7 @@ LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position) // virtual void LLVOAvatar::requestStopMotion( LLMotion* motion ) { - // Only agent avatars should handle the stop motion notifications. + // Only agent avatars should handle the stop motion notifications. } //----------------------------------------------------------------------------- @@ -6920,31 +6920,31 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion ) //virtual BOOL LLVOAvatar::loadSkeletonNode () { - if (!LLAvatarAppearance::loadSkeletonNode()) - { - return FALSE; - } - + if (!LLAvatarAppearance::loadSkeletonNode()) + { + return FALSE; + } + bool ignore_hud_joints = false; initAttachmentPoints(ignore_hud_joints); - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- -// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml. +// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml. //----------------------------------------------------------------------------- void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) { LLAvatarXmlInfo::attachment_info_list_t::iterator iter; for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); - iter != sAvatarXmlInfo->mAttachmentInfoList.end(); + iter != sAvatarXmlInfo->mAttachmentInfoList.end(); ++iter) { LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints)) { - //don't process hud joint for other avatars. + //don't process hud joint for other avatars. continue; } @@ -6981,7 +6981,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) attachment->setOriginalPosition(info->mPosition); attachment->setDefaultPosition(info->mPosition); } - + if (info->mHasRotation) { LLQuaternion rotation; @@ -7013,7 +7013,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) if (newly_created) { mAttachmentPoints[attachmentID] = attachment; - + // now add attachment joint parent_joint->addChild(attachment); } @@ -7025,45 +7025,45 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) //----------------------------------------------------------------------------- void LLVOAvatar::updateVisualParams() { - ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE; - if (getSex() != avatar_sex) - { - if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL) - { - // In some cases of gender change server changes sit motion with motion message, - // but in case of some avatars (legacy?) there is no update from server side, - // likely because server doesn't know about difference between motions - // (female and male sit ids are same server side, so it is likely unaware that it - // need to send update) - // Make sure motion is up to date - stopMotion(ANIM_AGENT_SIT); - setSex(avatar_sex); - startMotion(ANIM_AGENT_SIT); - } - else - { - setSex(avatar_sex); - } - } - - LLCharacter::updateVisualParams(); - - if (mLastSkeletonSerialNum != mSkeletonSerialNum) - { - computeBodySize(); - mLastSkeletonSerialNum = mSkeletonSerialNum; - mRoot->updateWorldMatrixChildren(); - } - - dirtyMesh(); - updateHeadOffset(); + ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE; + if (getSex() != avatar_sex) + { + if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL) + { + // In some cases of gender change server changes sit motion with motion message, + // but in case of some avatars (legacy?) there is no update from server side, + // likely because server doesn't know about difference between motions + // (female and male sit ids are same server side, so it is likely unaware that it + // need to send update) + // Make sure motion is up to date + stopMotion(ANIM_AGENT_SIT); + setSex(avatar_sex); + startMotion(ANIM_AGENT_SIT); + } + else + { + setSex(avatar_sex); + } + } + + LLCharacter::updateVisualParams(); + + if (mLastSkeletonSerialNum != mSkeletonSerialNum) + { + computeBodySize(); + mLastSkeletonSerialNum = mSkeletonSerialNum; + mRoot->updateWorldMatrixChildren(); + } + + dirtyMesh(); + updateHeadOffset(); } //----------------------------------------------------------------------------- // isActive() //----------------------------------------------------------------------------- BOOL LLVOAvatar::isActive() const { - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -7071,39 +7071,39 @@ BOOL LLVOAvatar::isActive() const //----------------------------------------------------------------------------- void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) { - if (mDrawable.isNull()) - { - return; - } + if (mDrawable.isNull()) + { + return; + } - const LLVector4a* ext = mDrawable->getSpatialExtents(); - LLVector4a center; - center.setAdd(ext[1], ext[0]); - center.mul(0.5f); - LLVector4a size; - size.setSub(ext[1], ext[0]); - size.mul(0.5f); + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a center; + center.setAdd(ext[1], ext[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); - mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); mPixelArea = mImpostorPixelArea; - F32 range = mDrawable->mDistanceWRTCamera; + F32 range = mDrawable->mDistanceWRTCamera; - if (range < 0.001f) // range == zero - { - mAppAngle = 180.f; - } - else - { - F32 radius = size.getLength3().getF32(); - mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; - } + if (range < 0.001f) // range == zero + { + mAppAngle = 180.f; + } + else + { + F32 radius = size.getLength3().getF32(); + mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; + } - // We always want to look good to ourselves - if( isSelf() ) - { - mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) ); - } + // We always want to look good to ourselves + if( isSelf() ) + { + mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) ); + } } //----------------------------------------------------------------------------- @@ -7111,48 +7111,48 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) //----------------------------------------------------------------------------- BOOL LLVOAvatar::updateJointLODs() { - const F32 MAX_PIXEL_AREA = 100000000.f; - F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE)); - F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f); - F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor); - F32 area_scale = 0.16f; - - if (isSelf()) - { - if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook()) - { - mAdjustedPixelArea = MAX_PIXEL_AREA; - } - else - { - mAdjustedPixelArea = mPixelArea*area_scale; - } - } - else if (mIsDummy) - { - mAdjustedPixelArea = MAX_PIXEL_AREA; - } - else - { - // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars - mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; - } - - // now select meshes to render based on adjusted pixel area - LLViewerJoint* root = dynamic_cast(mRoot); - BOOL res = FALSE; - if (root) - { - res = root->updateLOD(mAdjustedPixelArea, TRUE); - } - if (res) - { - sNumLODChangesThisFrame++; - dirtyMesh(2); - return TRUE; - } - - return FALSE; + const F32 MAX_PIXEL_AREA = 100000000.f; + F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE)); + F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f); + F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor); + F32 area_scale = 0.16f; + + if (isSelf()) + { + if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook()) + { + mAdjustedPixelArea = MAX_PIXEL_AREA; + } + else + { + mAdjustedPixelArea = mPixelArea*area_scale; + } + } + else if (mIsDummy) + { + mAdjustedPixelArea = MAX_PIXEL_AREA; + } + else + { + // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars + mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; + } + + // now select meshes to render based on adjusted pixel area + LLViewerJoint* root = dynamic_cast(mRoot); + BOOL res = FALSE; + if (root) + { + res = root->updateLOD(mAdjustedPixelArea, TRUE); + } + if (res) + { + sNumLODChangesThisFrame++; + dirtyMesh(2); + return TRUE; + } + + return FALSE; } //----------------------------------------------------------------------------- @@ -7160,32 +7160,32 @@ BOOL LLVOAvatar::updateJointLODs() //----------------------------------------------------------------------------- LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - mDrawable->setLit(FALSE); + pipeline->allocDrawable(this); + mDrawable->setLit(FALSE); + + LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR); - LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR); + // Only a single face (one per avatar) + //this face will be splitted into several if its vertex buffer is too long. + mDrawable->setState(LLDrawable::ACTIVE); + mDrawable->addFace(poolp, NULL); + mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR); - // Only a single face (one per avatar) - //this face will be splitted into several if its vertex buffer is too long. - mDrawable->setState(LLDrawable::ACTIVE); - mDrawable->addFace(poolp, NULL); - mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR); - - mNumInitFaces = mDrawable->getNumFaces() ; + mNumInitFaces = mDrawable->getNumFaces() ; - dirtyMesh(2); - return mDrawable; + dirtyMesh(2); + return mDrawable; } void LLVOAvatar::updateGL() { - if (mMeshTexturesDirty) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR - updateMeshTextures(); - mMeshTexturesDirty = FALSE; - } + if (mMeshTexturesDirty) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + updateMeshTextures(); + mMeshTexturesDirty = FALSE; + } } //----------------------------------------------------------------------------- @@ -7194,22 +7194,22 @@ void LLVOAvatar::updateGL() BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))) - { - return TRUE; - } - - if (!mMeshValid) - { - return TRUE; - } + if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))) + { + return TRUE; + } - if (!drawable) - { - LL_ERRS() << "LLVOAvatar::updateGeometry() called with NULL drawable" << LL_ENDL; - } + if (!mMeshValid) + { + return TRUE; + } + + if (!drawable) + { + LL_ERRS() << "LLVOAvatar::updateGeometry() called with NULL drawable" << LL_ENDL; + } - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -7217,9 +7217,9 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) //----------------------------------------------------------------------------- void LLVOAvatar::updateSexDependentLayerSets() { - invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); - invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet); - invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet); } //----------------------------------------------------------------------------- @@ -7227,19 +7227,19 @@ void LLVOAvatar::updateSexDependentLayerSets() //----------------------------------------------------------------------------- void LLVOAvatar::dirtyMesh() { - dirtyMesh(1); + dirtyMesh(1); } void LLVOAvatar::dirtyMesh(S32 priority) { - mDirtyMesh = llmax(mDirtyMesh, priority); + mDirtyMesh = llmax(mDirtyMesh, priority); } //----------------------------------------------------------------------------- // getViewerJoint() //----------------------------------------------------------------------------- -LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx) +LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx) { - return dynamic_cast(mMeshLOD[idx]); + return dynamic_cast(mMeshLOD[idx]); } //----------------------------------------------------------------------------- @@ -7255,111 +7255,111 @@ void LLVOAvatar::hideHair() //----------------------------------------------------------------------------- void LLVOAvatar::hideSkirt() { - mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE); + mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE); } BOOL LLVOAvatar::setParent(LLViewerObject* parent) { - BOOL ret ; - if (parent == NULL) - { - getOffObject(); - ret = LLViewerObject::setParent(parent); - if (isSelf()) - { - gAgentCamera.resetCamera(); - } - } - else - { - ret = LLViewerObject::setParent(parent); - if(ret) - { - sitOnObject(parent); - } - } - return ret ; + BOOL ret ; + if (parent == NULL) + { + getOffObject(); + ret = LLViewerObject::setParent(parent); + if (isSelf()) + { + gAgentCamera.resetCamera(); + } + } + else + { + ret = LLViewerObject::setParent(parent); + if(ret) + { + sitOnObject(parent); + } + } + return ret ; } void LLVOAvatar::addChild(LLViewerObject *childp) { - childp->extractAttachmentItemID(); // find the inventory item this object is associated with. - if (isSelf()) - { - const LLUUID& item_id = childp->getAttachmentItemID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LL_DEBUGS("Avatar") << "ATT attachment child added " << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - - } - - LLViewerObject::addChild(childp); - if (childp->mDrawable) - { - if (!attachObject(childp)) - { - LL_WARNS() << "ATT addChild() failed for " - << childp->getID() - << " item " << childp->getAttachmentItemID() - << LL_ENDL; - // MAINT-3312 backout - // mPendingAttachment.push_back(childp); - } - } - else - { - mPendingAttachment.push_back(childp); - } + childp->extractAttachmentItemID(); // find the inventory item this object is associated with. + if (isSelf()) + { + const LLUUID& item_id = childp->getAttachmentItemID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT attachment child added " << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; + + } + + LLViewerObject::addChild(childp); + if (childp->mDrawable) + { + if (!attachObject(childp)) + { + LL_WARNS() << "ATT addChild() failed for " + << childp->getID() + << " item " << childp->getAttachmentItemID() + << LL_ENDL; + // MAINT-3312 backout + // mPendingAttachment.push_back(childp); + } + } + else + { + mPendingAttachment.push_back(childp); + } } void LLVOAvatar::removeChild(LLViewerObject *childp) { - LLViewerObject::removeChild(childp); - if (!detachObject(childp)) - { - LL_WARNS() << "Calling detach on non-attached object " << LL_ENDL; - } + LLViewerObject::removeChild(childp); + if (!detachObject(childp)) + { + LL_WARNS() << "Calling detach on non-attached object " << LL_ENDL; + } } LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object) { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState()); - - // This should never happen unless the server didn't process the attachment point - // correctly, but putting this check in here to be safe. - if (attachmentID & ATTACHMENT_ADD) - { - LL_WARNS() << "Got an attachment with ATTACHMENT_ADD mask, removing ( attach pt:" << attachmentID << " )" << LL_ENDL; - attachmentID &= ~ATTACHMENT_ADD; - } - - LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); - - if (!attachment) - { - LL_WARNS() << "Object attachment point invalid: " << attachmentID - << " trying to use 1 (chest)" - << LL_ENDL; - - attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest) - if (attachment) - { - LL_WARNS() << "Object attachment point invalid: " << attachmentID - << " on object " << viewer_object->getID() - << " attachment item " << viewer_object->getAttachmentItemID() - << " falling back to 1 (chest)" - << LL_ENDL; - } - else - { - LL_WARNS() << "Object attachment point invalid: " << attachmentID - << " on object " << viewer_object->getID() - << " attachment item " << viewer_object->getAttachmentItemID() - << "Unable to use fallback attachment point 1 (chest)" - << LL_ENDL; - } - } - - return attachment; + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState()); + + // This should never happen unless the server didn't process the attachment point + // correctly, but putting this check in here to be safe. + if (attachmentID & ATTACHMENT_ADD) + { + LL_WARNS() << "Got an attachment with ATTACHMENT_ADD mask, removing ( attach pt:" << attachmentID << " )" << LL_ENDL; + attachmentID &= ~ATTACHMENT_ADD; + } + + LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); + + if (!attachment) + { + LL_WARNS() << "Object attachment point invalid: " << attachmentID + << " trying to use 1 (chest)" + << LL_ENDL; + + attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest) + if (attachment) + { + LL_WARNS() << "Object attachment point invalid: " << attachmentID + << " on object " << viewer_object->getID() + << " attachment item " << viewer_object->getAttachmentItemID() + << " falling back to 1 (chest)" + << LL_ENDL; + } + else + { + LL_WARNS() << "Object attachment point invalid: " << attachmentID + << " on object " << viewer_object->getID() + << " attachment item " << viewer_object->getAttachmentItemID() + << "Unable to use fallback attachment point 1 (chest)" + << LL_ENDL; + } + } + + return attachment; } //----------------------------------------------------------------------------- @@ -7367,54 +7367,54 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi //----------------------------------------------------------------------------- const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object) { - if (isSelf()) - { - const LLUUID& item_id = viewer_object->getAttachmentItemID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LL_DEBUGS("Avatar") << "ATT attaching object " - << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - } - LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object); - - if (!attachment || !attachment->addObject(viewer_object)) - { - const LLUUID& item_id = viewer_object->getAttachmentItemID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LL_WARNS("Avatar") << "ATT attach failed " - << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - return 0; - } + if (isSelf()) + { + const LLUUID& item_id = viewer_object->getAttachmentItemID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT attaching object " + << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; + } + LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object); + + if (!attachment || !attachment->addObject(viewer_object)) + { + const LLUUID& item_id = viewer_object->getAttachmentItemID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_WARNS("Avatar") << "ATT attach failed " + << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; + return 0; + } if (!viewer_object->isAnimatedObject()) { updateAttachmentOverrides(); } - updateVisualComplexity(); + updateVisualComplexity(); - if (viewer_object->isSelected()) - { - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLSelectMgr::getInstance()->updatePointAt(); - } + if (viewer_object->isSelected()) + { + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updatePointAt(); + } - viewer_object->refreshBakeTexture(); + viewer_object->refreshBakeTexture(); - LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* objectp = *iter; - if (objectp) - { - objectp->refreshBakeTexture(); - } - } + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } - updateMeshVisibility(); + updateMeshVisibility(); - return attachment; + return attachment; } //----------------------------------------------------------------------------- @@ -7422,15 +7422,15 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o //----------------------------------------------------------------------------- U32 LLVOAvatar::getNumAttachments() const { - U32 num_attachments = 0; - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment *attachment_pt = (*iter).second; - num_attachments += attachment_pt->getNumObjects(); - } - return num_attachments; + U32 num_attachments = 0; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + num_attachments += attachment_pt->getNumObjects(); + } + return num_attachments; } //----------------------------------------------------------------------------- @@ -7438,7 +7438,7 @@ U32 LLVOAvatar::getNumAttachments() const //----------------------------------------------------------------------------- S32 LLVOAvatar::getMaxAttachments() const { - return LLAgentBenefitsMgr::current().getAttachmentLimit(); + return LLAgentBenefitsMgr::current().getAttachmentLimit(); } //----------------------------------------------------------------------------- @@ -7447,7 +7447,7 @@ S32 LLVOAvatar::getMaxAttachments() const //----------------------------------------------------------------------------- BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const { - return (getNumAttachments() + n) <= getMaxAttachments(); + return (getNumAttachments() + n) <= getMaxAttachments(); } //----------------------------------------------------------------------------- @@ -7455,15 +7455,15 @@ BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const //----------------------------------------------------------------------------- U32 LLVOAvatar::getNumAnimatedObjectAttachments() const { - U32 num_attachments = 0; - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment *attachment_pt = (*iter).second; - num_attachments += attachment_pt->getNumAnimatedObjects(); - } - return num_attachments; + U32 num_attachments = 0; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + num_attachments += attachment_pt->getNumAnimatedObjects(); + } + return num_attachments; } //----------------------------------------------------------------------------- @@ -7472,7 +7472,7 @@ U32 LLVOAvatar::getNumAnimatedObjectAttachments() const //----------------------------------------------------------------------------- S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const { - return LLAgentBenefitsMgr::current().getAnimatedObjectLimit(); + return LLAgentBenefitsMgr::current().getAnimatedObjectLimit(); } //----------------------------------------------------------------------------- @@ -7481,7 +7481,7 @@ S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const //----------------------------------------------------------------------------- BOOL LLVOAvatar::canAttachMoreAnimatedObjects(U32 n) const { - return (getNumAnimatedObjectAttachments() + n) <= getMaxAnimatedObjectAttachments(); + return (getNumAnimatedObjectAttachments() + n) <= getMaxAnimatedObjectAttachments(); } //----------------------------------------------------------------------------- @@ -7489,101 +7489,101 @@ BOOL LLVOAvatar::canAttachMoreAnimatedObjects(U32 n) const //----------------------------------------------------------------------------- void LLVOAvatar::lazyAttach() { - std::vector > still_pending; - - for (U32 i = 0; i < mPendingAttachment.size(); i++) - { - LLPointer cur_attachment = mPendingAttachment[i]; - // Object might have died while we were waiting for drawable - if (!cur_attachment->isDead()) - { - if (cur_attachment->mDrawable) - { - if (isSelf()) - { - const LLUUID& item_id = cur_attachment->getAttachmentItemID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LL_DEBUGS("Avatar") << "ATT attaching object " - << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - } - if (!attachObject(cur_attachment)) - { // Drop it - LL_WARNS() << "attachObject() failed for " - << cur_attachment->getID() - << " item " << cur_attachment->getAttachmentItemID() - << LL_ENDL; - // MAINT-3312 backout - //still_pending.push_back(cur_attachment); - } - } - else - { - still_pending.push_back(cur_attachment); - } - } - } - - mPendingAttachment = still_pending; + std::vector > still_pending; + + for (U32 i = 0; i < mPendingAttachment.size(); i++) + { + LLPointer cur_attachment = mPendingAttachment[i]; + // Object might have died while we were waiting for drawable + if (!cur_attachment->isDead()) + { + if (cur_attachment->mDrawable) + { + if (isSelf()) + { + const LLUUID& item_id = cur_attachment->getAttachmentItemID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT attaching object " + << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; + } + if (!attachObject(cur_attachment)) + { // Drop it + LL_WARNS() << "attachObject() failed for " + << cur_attachment->getID() + << " item " << cur_attachment->getAttachmentItemID() + << LL_ENDL; + // MAINT-3312 backout + //still_pending.push_back(cur_attachment); + } + } + else + { + still_pending.push_back(cur_attachment); + } + } + } + + mPendingAttachment = still_pending; } void LLVOAvatar::resetHUDAttachments() { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getIsHUDAttachment()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = attachment_iter->get(); - if (attached_object && attached_object->mDrawable.notNull()) - { - gPipeline.markMoved(attached_object->mDrawable); - } - } - } - } + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object && attached_object->mDrawable.notNull()) + { + gPipeline.markMoved(attached_object->mDrawable); + } + } + } + } } void LLVOAvatar::rebuildRiggedAttachments( void ) { - for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) - { - LLViewerJointAttachment* pAttachment = iter->second; - LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIterEnd = pAttachment->mAttachedObjects.end(); - - for ( LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIter = pAttachment->mAttachedObjects.begin(); - attachmentIter != attachmentIterEnd; ++attachmentIter) - { - const LLViewerObject* pAttachedObject = *attachmentIter; - if ( pAttachment && pAttachedObject->mDrawable.notNull() ) - { - gPipeline.markRebuild(pAttachedObject->mDrawable); - } - } - } + for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) + { + LLViewerJointAttachment* pAttachment = iter->second; + LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIterEnd = pAttachment->mAttachedObjects.end(); + + for ( LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIter = pAttachment->mAttachedObjects.begin(); + attachmentIter != attachmentIterEnd; ++attachmentIter) + { + const LLViewerObject* pAttachedObject = *attachmentIter; + if ( pAttachment && pAttachedObject->mDrawable.notNull() ) + { + gPipeline.markRebuild(pAttachedObject->mDrawable); + } + } + } } //----------------------------------------------------------------------------- // cleanupAttachedMesh() //----------------------------------------------------------------------------- void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) { - LLUUID mesh_id; - if (getRiggedMeshID(pVO, mesh_id)) - { + LLUUID mesh_id; + if (getRiggedMeshID(pVO, mesh_id)) + { // FIXME this seems like an odd place for this code. - if ( gAgentCamera.cameraCustomizeAvatar() ) - { - gAgent.unpauseAnimation(); - //Still want to refocus on head bone - gAgentCamera.changeCameraToCustomizeAvatar(); - } - } + if ( gAgentCamera.cameraCustomizeAvatar() ) + { + gAgent.unpauseAnimation(); + //Still want to refocus on head bone + gAgentCamera.changeCameraToCustomizeAvatar(); + } + } } bool LLVOAvatar::hasPendingAttachedMeshes() @@ -7670,51 +7670,51 @@ bool LLVOAvatar::hasPendingAttachedMeshes() //----------------------------------------------------------------------------- BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - if (attachment->isObjectAttached(viewer_object)) - { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + if (attachment->isObjectAttached(viewer_object)) + { updateVisualComplexity(); bool is_animated_object = viewer_object->isAnimatedObject(); - cleanupAttachedMesh(viewer_object); + cleanupAttachedMesh(viewer_object); - attachment->removeObject(viewer_object); + attachment->removeObject(viewer_object); if (!is_animated_object) { updateAttachmentOverrides(); } - viewer_object->refreshBakeTexture(); - - LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); - iter1 != child_list.end(); ++iter1) - { - LLViewerObject* objectp = *iter1; - if (objectp) + viewer_object->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) { - objectp->refreshBakeTexture(); - } + LLViewerObject* objectp = *iter1; + if (objectp) + { + objectp->refreshBakeTexture(); + } } - updateMeshVisibility(); + updateMeshVisibility(); + + LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL; + return TRUE; + } + } - LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL; - return TRUE; - } - } + std::vector >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object); + if (iter != mPendingAttachment.end()) + { + mPendingAttachment.erase(iter); + return TRUE; + } - std::vector >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object); - if (iter != mPendingAttachment.end()) - { - mPendingAttachment.erase(iter); - return TRUE; - } - - return FALSE; + return FALSE; } //----------------------------------------------------------------------------- @@ -7722,12 +7722,12 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) //----------------------------------------------------------------------------- void LLVOAvatar::sitDown(BOOL bSitting) { - mIsSitting = bSitting; - if (isSelf()) - { - // Update Movement Controls according to own Sitting mode - LLFloaterMove::setSittingMode(bSitting); - } + mIsSitting = bSitting; + if (isSelf()) + { + // Update Movement Controls according to own Sitting mode + LLFloaterMove::setSittingMode(bSitting); + } } //----------------------------------------------------------------------------- @@ -7735,22 +7735,22 @@ void LLVOAvatar::sitDown(BOOL bSitting) //----------------------------------------------------------------------------- void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) { - if (isSelf()) - { - // Might be first sit - //LLFirstUse::useSit(); - - gAgent.setFlying(FALSE); - gAgentCamera.setThirdPersonHeadOffset(LLVector3::zero); - //interpolate to new camera position - gAgentCamera.startCameraAnimation(); - // make sure we are not trying to autopilot - gAgent.stopAutoPilot(); - gAgentCamera.setupSitCamera(); - if (gAgentCamera.getForceMouselook()) - { - gAgentCamera.changeCameraToMouselook(); - } + if (isSelf()) + { + // Might be first sit + //LLFirstUse::useSit(); + + gAgent.setFlying(FALSE); + gAgentCamera.setThirdPersonHeadOffset(LLVector3::zero); + //interpolate to new camera position + gAgentCamera.startCameraAnimation(); + // make sure we are not trying to autopilot + gAgent.stopAutoPilot(); + gAgentCamera.setupSitCamera(); + if (gAgentCamera.getForceMouselook()) + { + gAgentCamera.changeCameraToMouselook(); + } if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit()) { @@ -7764,33 +7764,33 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) } } } - } + } - if (mDrawable.isNull()) - { - return; - } - LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation(); - LLVector3 obj_pos = sit_object->getRenderPosition(); + if (mDrawable.isNull()) + { + return; + } + LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation(); + LLVector3 obj_pos = sit_object->getRenderPosition(); - LLVector3 rel_pos = getRenderPosition() - obj_pos; - rel_pos.rotVec(inv_obj_rot); + LLVector3 rel_pos = getRenderPosition() - obj_pos; + rel_pos.rotVec(inv_obj_rot); - mDrawable->mXform.setPosition(rel_pos); - mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); + mDrawable->mXform.setPosition(rel_pos); + mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); - gPipeline.markMoved(mDrawable, TRUE); - // Notice that removing sitDown() from here causes avatars sitting on - // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655. - sitDown(TRUE); - mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject - // SL-315 - mRoot->setPosition(getPosition()); - mRoot->updateWorldMatrixChildren(); + gPipeline.markMoved(mDrawable, TRUE); + // Notice that removing sitDown() from here causes avatars sitting on + // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655. + sitDown(TRUE); + mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject + // SL-315 + mRoot->setPosition(getPosition()); + mRoot->updateWorldMatrixChildren(); - stopMotion(ANIM_AGENT_BODY_NOISE); - - gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion()); + stopMotion(ANIM_AGENT_BODY_NOISE); + + gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion()); } //----------------------------------------------------------------------------- @@ -7798,168 +7798,168 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) //----------------------------------------------------------------------------- void LLVOAvatar::getOffObject() { - if (mDrawable.isNull()) - { - return; - } - - LLViewerObject* sit_object = (LLViewerObject*)getParent(); - - if (sit_object) - { - stopMotionFromSource(sit_object->getID()); - LLFollowCamMgr::getInstance()->setCameraActive(sit_object->getID(), FALSE); - - LLViewerObject::const_child_list_t& child_list = sit_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* child_objectp = *iter; - - stopMotionFromSource(child_objectp->getID()); - LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE); - } - } - - // assumes that transform will not be updated with drawable still having a parent - // or that drawable had no parent from the start - LLVector3 cur_position_world = mDrawable->getWorldPosition(); - LLQuaternion cur_rotation_world = mDrawable->getWorldRotation(); - - if (mLastRootPos.length() >= MAX_STANDOFF_FROM_ORIGIN - && (cur_position_world.length() < MAX_STANDOFF_FROM_ORIGIN - || dist_vec(cur_position_world, mLastRootPos) > MAX_STANDOFF_DISTANCE_CHANGE)) - { - // Most likely drawable got updated too early or some updates were missed - we got relative position to non-existing parent - // restore coordinates from cache - cur_position_world = mLastRootPos; - } - - // set *local* position based on last *world* position, since we're unparenting the avatar - mDrawable->mXform.setPosition(cur_position_world); - mDrawable->mXform.setRotation(cur_rotation_world); - - gPipeline.markMoved(mDrawable, TRUE); - - sitDown(FALSE); - - mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject - // SL-315 - mRoot->setPosition(cur_position_world); - mRoot->setRotation(cur_rotation_world); - mRoot->getXform()->update(); + if (mDrawable.isNull()) + { + return; + } + + LLViewerObject* sit_object = (LLViewerObject*)getParent(); + + if (sit_object) + { + stopMotionFromSource(sit_object->getID()); + LLFollowCamMgr::getInstance()->setCameraActive(sit_object->getID(), FALSE); + + LLViewerObject::const_child_list_t& child_list = sit_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* child_objectp = *iter; + + stopMotionFromSource(child_objectp->getID()); + LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE); + } + } + + // assumes that transform will not be updated with drawable still having a parent + // or that drawable had no parent from the start + LLVector3 cur_position_world = mDrawable->getWorldPosition(); + LLQuaternion cur_rotation_world = mDrawable->getWorldRotation(); + + if (mLastRootPos.length() >= MAX_STANDOFF_FROM_ORIGIN + && (cur_position_world.length() < MAX_STANDOFF_FROM_ORIGIN + || dist_vec(cur_position_world, mLastRootPos) > MAX_STANDOFF_DISTANCE_CHANGE)) + { + // Most likely drawable got updated too early or some updates were missed - we got relative position to non-existing parent + // restore coordinates from cache + cur_position_world = mLastRootPos; + } + + // set *local* position based on last *world* position, since we're unparenting the avatar + mDrawable->mXform.setPosition(cur_position_world); + mDrawable->mXform.setRotation(cur_rotation_world); + + gPipeline.markMoved(mDrawable, TRUE); + + sitDown(FALSE); + + mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject + // SL-315 + mRoot->setPosition(cur_position_world); + mRoot->setRotation(cur_rotation_world); + mRoot->getXform()->update(); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_BODY_NOISE); + startMotion(ANIM_AGENT_BODY_NOISE); } - if (isSelf()) - { - LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); - LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; - av_rot = av_rot * obj_rot; - LLVector3 at_axis = LLVector3::x_axis; - at_axis = at_axis * av_rot; - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - gAgent.resetAxes(at_axis); - gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); - gAgentCamera.setSitCamera(LLUUID::null); - } + if (isSelf()) + { + LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); + LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; + av_rot = av_rot * obj_rot; + LLVector3 at_axis = LLVector3::x_axis; + at_axis = at_axis * av_rot; + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis); + gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); + gAgentCamera.setSitCamera(LLUUID::null); + } } //----------------------------------------------------------------------------- // findAvatarFromAttachment() //----------------------------------------------------------------------------- -// static +// static LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) { - if( obj->isAttachment() ) - { - do - { - obj = (LLViewerObject*) obj->getParent(); - } - while( obj && !obj->isAvatar() ); + if( obj->isAttachment() ) + { + do + { + obj = (LLViewerObject*) obj->getParent(); + } + while( obj && !obj->isAvatar() ); - if( obj && !obj->isDead() ) - { - return (LLVOAvatar*)obj; - } - } - return NULL; + if( obj && !obj->isDead() ) + { + return (LLVOAvatar*)obj; + } + } + return NULL; } S32 LLVOAvatar::getAttachmentCount() { - S32 count = mAttachmentPoints.size(); - return count; + S32 count = mAttachmentPoints.size(); + return count; } BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const { - if (mIsDummy) return TRUE; - - if (isSelf()) - { - return LLAvatarAppearance::isWearingWearableType(type); - } - - switch(type) - { - case LLWearableType::WT_SHAPE: - case LLWearableType::WT_SKIN: - case LLWearableType::WT_HAIR: - case LLWearableType::WT_EYES: - return TRUE; // everyone has all bodyparts - default: - break; // Do nothing - } - - for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); - tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end(); - ++tex_iter) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; - if (texture_dict->mWearableType == type) - { - // Thus, you must check to see if the corresponding baked texture is defined. - // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing - // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that - // gets baked into a texture that always exists (upper or lower). - if (texture_dict->mIsUsedByBakedTexture) - { - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex); - } - return FALSE; - } - } - return FALSE; -} - -LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const -{ - for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin(); - attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end(); - ++attachment_points_iter) - { - LLViewerJointAttachment* attachment = attachment_points_iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *attached_object = attachment_iter->get(); - if (attached_object && - attached_object->getID() == target_id) - { - return attached_object; - } - } - } - - return NULL; + if (mIsDummy) return TRUE; + + if (isSelf()) + { + return LLAvatarAppearance::isWearingWearableType(type); + } + + switch(type) + { + case LLWearableType::WT_SHAPE: + case LLWearableType::WT_SKIN: + case LLWearableType::WT_HAIR: + case LLWearableType::WT_EYES: + return TRUE; // everyone has all bodyparts + default: + break; // Do nothing + } + + for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); + tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end(); + ++tex_iter) + { + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; + if (texture_dict->mWearableType == type) + { + // Thus, you must check to see if the corresponding baked texture is defined. + // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing + // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that + // gets baked into a texture that always exists (upper or lower). + if (texture_dict->mIsUsedByBakedTexture) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex); + } + return FALSE; + } + } + return FALSE; +} + +LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const +{ + for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin(); + attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end(); + ++attachment_points_iter) + { + LLViewerJointAttachment* attachment = attachment_points_iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = attachment_iter->get(); + if (attached_object && + attached_object->getID() == target_id) + { + return attached_object; + } + } + } + + return NULL; } // virtual @@ -7974,40 +7974,40 @@ void LLVOAvatar::invalidateAll() // virtual void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) { - if (global_color == mTexSkinColor) - { - invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); - invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet); - invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet); - } - else if (global_color == mTexHairColor) - { - invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); - invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet); - - // ! BACKWARDS COMPATIBILITY ! - // Fix for dealing with avatars from viewers that don't bake hair. - if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex)) - { - LLColor4 color = mTexHairColor->getColor(); - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setColor( color ); - } - } - } - } - else if (global_color == mTexEyeColor) - { - // LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL; - invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet); - } - updateMeshTextures(); + if (global_color == mTexSkinColor) + { + invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet); + } + else if (global_color == mTexHairColor) + { + invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet); + invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet); + + // ! BACKWARDS COMPATIBILITY ! + // Fix for dealing with avatars from viewers that don't bake hair. + if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex)) + { + LLColor4 color = mTexHairColor->getColor(); + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor( color ); + } + } + } + } + else if (global_color == mTexEyeColor) + { + // LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL; + invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet); + } + updateMeshTextures(); } // virtual @@ -8016,12 +8016,12 @@ bool LLVOAvatar::shouldRenderRigged() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (getOverallAppearance() == AOA_NORMAL) - { - return true; - } - // TBD - render for AOA_JELLYDOLL? - return false; + if (getOverallAppearance() == AOA_NORMAL) + { + return true; + } + // TBD - render for AOA_JELLYDOLL? + return false; } // FIXME: We have an mVisible member, set in updateVisibility(), but this @@ -8032,207 +8032,207 @@ bool LLVOAvatar::shouldRenderRigged() const // Maybe better naming could make this clearer? BOOL LLVOAvatar::isVisible() const { - return mDrawable.notNull() - && (!mOrphaned || isSelf()) - && (mDrawable->isVisible() || mIsDummy); + return mDrawable.notNull() + && (!mOrphaned || isSelf()) + && (mDrawable->isVisible() || mIsDummy); } // Determine if we have enough avatar data to render bool LLVOAvatar::getIsCloud() const { - if (mIsDummy) - { - return false; - } + if (mIsDummy) + { + return false; + } - return ( ((const_cast(this))->visualParamWeightsAreDefault())// Do we have a shape? - || ( !isTextureDefined(TEX_LOWER_BAKED) - || !isTextureDefined(TEX_UPPER_BAKED) - || !isTextureDefined(TEX_HEAD_BAKED) - ) - ); + return ( ((const_cast(this))->visualParamWeightsAreDefault())// Do we have a shape? + || ( !isTextureDefined(TEX_LOWER_BAKED) + || !isTextureDefined(TEX_UPPER_BAKED) + || !isTextureDefined(TEX_HEAD_BAKED) + ) + ); } void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status) { - // State machine for rezzed status. Statuses are -1 on startup, 0 - // = cloud, 1 = gray, 2 = downloading, 3 = full. - // Purpose is to collect time data for each it takes avatar to reach - // various loading landmarks: gray, textured (partial), textured fully. - - if (rez_status != mLastRezzedStatus) - { - LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; - - if (mLastRezzedStatus == -1 && rez_status != -1) - { - // First time initialization, start all timers. - for (S32 i = 1; i < 4; i++) - { - startPhase("load_" + LLVOAvatar::rezStatusToString(i)); - startPhase("first_load_" + LLVOAvatar::rezStatusToString(i)); - } - } - if (rez_status < mLastRezzedStatus) - { - // load level has decreased. start phase timers for higher load levels. - for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) - { - startPhase("load_" + LLVOAvatar::rezStatusToString(i)); - } - } - else if (rez_status > mLastRezzedStatus) - { - // load level has increased. stop phase timers for lower and equal load levels. - for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++) - { - stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); - stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); - } - if (rez_status == 3) - { - // "fully loaded", mark any pending appearance change complete. - selfStopPhase("update_appearance_from_cof"); - selfStopPhase("wear_inventory_category", false); - selfStopPhase("process_initial_wearables_update", false); + // State machine for rezzed status. Statuses are -1 on startup, 0 + // = cloud, 1 = gray, 2 = downloading, 3 = full. + // Purpose is to collect time data for each it takes avatar to reach + // various loading landmarks: gray, textured (partial), textured fully. + + if (rez_status != mLastRezzedStatus) + { + LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; + + if (mLastRezzedStatus == -1 && rez_status != -1) + { + // First time initialization, start all timers. + for (S32 i = 1; i < 4; i++) + { + startPhase("load_" + LLVOAvatar::rezStatusToString(i)); + startPhase("first_load_" + LLVOAvatar::rezStatusToString(i)); + } + } + if (rez_status < mLastRezzedStatus) + { + // load level has decreased. start phase timers for higher load levels. + for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) + { + startPhase("load_" + LLVOAvatar::rezStatusToString(i)); + } + } + else if (rez_status > mLastRezzedStatus) + { + // load level has increased. stop phase timers for lower and equal load levels. + for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++) + { + stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); + stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); + } + if (rez_status == 3) + { + // "fully loaded", mark any pending appearance change complete. + selfStopPhase("update_appearance_from_cof"); + selfStopPhase("wear_inventory_category", false); + selfStopPhase("process_initial_wearables_update", false); updateVisualComplexity(); - } - } - mLastRezzedStatus = rez_status; - } + } + } + mLastRezzedStatus = rez_status; + } } void LLVOAvatar::clearPhases() { - getPhases().clearPhases(); + getPhases().clearPhases(); } void LLVOAvatar::startPhase(const std::string& phase_name) { - F32 elapsed = 0.0; - bool completed = false; - bool found = getPhases().getPhaseValues(phase_name, elapsed, completed); - //LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name - // << " found " << found << " elapsed " << elapsed << " completed " << completed << LL_ENDL; - if (found) - { - if (!completed) - { - LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << LL_ENDL; - return; - } - } - LL_DEBUGS("Avatar") << "started phase " << phase_name << LL_ENDL; - getPhases().startPhase(phase_name); + F32 elapsed = 0.0; + bool completed = false; + bool found = getPhases().getPhaseValues(phase_name, elapsed, completed); + //LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name + // << " found " << found << " elapsed " << elapsed << " completed " << completed << LL_ENDL; + if (found) + { + if (!completed) + { + LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << LL_ENDL; + return; + } + } + LL_DEBUGS("Avatar") << "started phase " << phase_name << LL_ENDL; + getPhases().startPhase(phase_name); } void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) { - F32 elapsed = 0.0; - bool completed = false; - if (getPhases().getPhaseValues(phase_name, elapsed, completed)) - { - if (!completed) - { - getPhases().stopPhase(phase_name); - completed = true; - logMetricsTimerRecord(phase_name, elapsed, completed); - LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << LL_ENDL; - } - else - { - if (err_check) - { - LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << LL_ENDL; - } - } - } - else - { - if (err_check) - { - LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << LL_ENDL; - } - } + F32 elapsed = 0.0; + bool completed = false; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + getPhases().stopPhase(phase_name); + completed = true; + logMetricsTimerRecord(phase_name, elapsed, completed); + LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << LL_ENDL; + } + else + { + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << LL_ENDL; + } + } + } + else + { + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << LL_ENDL; + } + } } void LLVOAvatar::logPendingPhases() { - if (!isAgentAvatarValid()) - { - return; - } - - for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); - it != getPhases().end(); - ++it) - { - const std::string& phase_name = it->first; - F32 elapsed; - bool completed; - if (getPhases().getPhaseValues(phase_name, elapsed, completed)) - { - if (!completed) - { - logMetricsTimerRecord(phase_name, elapsed, completed); - } - } - } + if (!isAgentAvatarValid()) + { + return; + } + + for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); + it != getPhases().end(); + ++it) + { + const std::string& phase_name = it->first; + F32 elapsed; + bool completed; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + logMetricsTimerRecord(phase_name, elapsed, completed); + } + } + } } //static void LLVOAvatar::logPendingPhasesAllAvatars() { - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - if( inst->isDead() ) - { - continue; - } - inst->logPendingPhases(); - } + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if( inst->isDead() ) + { + continue; + } + inst->logPendingPhases(); + } } void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) { - if (!isAgentAvatarValid()) - { - return; - } - - LLSD record; - record["timer_name"] = phase_name; - record["avatar_id"] = getID(); - record["elapsed"] = elapsed; - record["completed"] = completed; - U32 grid_x(0), grid_y(0); - if (getRegion() && LLWorld::instance().isRegionListed(getRegion())) - { - record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); - grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); - } - record["grid_x"] = LLSD::Integer(grid_x); - record["grid_y"] = LLSD::Integer(grid_y); - record["is_using_server_bakes"] = true; - record["is_self"] = isSelf(); - - if (isAgentAvatarValid()) - { - gAgentAvatarp->addMetricsTimerRecord(record); - } + if (!isAgentAvatarValid()) + { + return; + } + + LLSD record; + record["timer_name"] = phase_name; + record["avatar_id"] = getID(); + record["elapsed"] = elapsed; + record["completed"] = completed; + U32 grid_x(0), grid_y(0); + if (getRegion() && LLWorld::instance().isRegionListed(getRegion())) + { + record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); + grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); + } + record["grid_x"] = LLSD::Integer(grid_x); + record["grid_y"] = LLSD::Integer(grid_y); + record["is_using_server_bakes"] = true; + record["is_self"] = isSelf(); + + if (isAgentAvatarValid()) + { + gAgentAvatarp->addMetricsTimerRecord(record); + } } // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() { - S32 rez_status = getRezzedStatus(); - bool loading = getIsCloud(); - if (mFirstFullyVisible && !mIsControlAvatar) - { + S32 rez_status = getRezzedStatus(); + bool loading = getIsCloud(); + if (mFirstFullyVisible && !mIsControlAvatar) + { loading = ((rez_status < 2) // Wait at least 60s for unfinished textures to finish on first load, // don't wait forever, it might fail. Even if it will eventually load by @@ -8243,56 +8243,56 @@ BOOL LLVOAvatar::updateIsFullyLoaded() || (rez_status < 3 && !isFullyBaked()) || hasPendingAttachedMeshes() ); - } - updateRezzedStatusTimers(rez_status); - updateRuthTimer(loading); - return processFullyLoadedChange(loading); + } + updateRezzedStatusTimers(rez_status); + updateRuthTimer(loading); + return processFullyLoadedChange(loading); } void LLVOAvatar::updateRuthTimer(bool loading) { - if (isSelf() || !loading) - { - return; - } - - if (mPreviousFullyLoaded) - { - mRuthTimer.reset(); - debugAvatarRezTime("AvatarRezCloudNotification","became cloud"); - } - - const F32 LOADING_TIMEOUT__SECONDS = 120.f; - if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS) - { - LL_DEBUGS("Avatar") << avString() - << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " - << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " - << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " - << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " - << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." - << LL_ENDL; - - LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); - mRuthTimer.reset(); - } + if (isSelf() || !loading) + { + return; + } + + if (mPreviousFullyLoaded) + { + mRuthTimer.reset(); + debugAvatarRezTime("AvatarRezCloudNotification","became cloud"); + } + + const F32 LOADING_TIMEOUT__SECONDS = 120.f; + if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS) + { + LL_DEBUGS("Avatar") << avString() + << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " + << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " + << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " + << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " + << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." + << LL_ENDL; + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); + mRuthTimer.reset(); + } } BOOL LLVOAvatar::processFullyLoadedChange(bool loading) { - // We wait a little bit before giving the 'all clear', to let things to - // settle down (models to snap into place, textures to get first packets). + // We wait a little bit before giving the 'all clear', to let things to + // settle down (models to snap into place, textures to get first packets). // And if viewer isn't aware of some parts yet, this gives them a chance // to arrive. - const F32 LOADED_DELAY = 1.f; + const F32 LOADED_DELAY = 1.f; if (loading) { mFullyLoadedTimer.reset(); } - if (mFirstFullyVisible) - { + if (mFirstFullyVisible) + { if (!isSelf() && loading) { // Note that textures can causes 60s delay on thier own @@ -8309,31 +8309,31 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) mFirstUseDelaySeconds *= 1.25; } } - mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds); - } - else - { - mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY); - } - - if (!mPreviousFullyLoaded && !loading && mFullyLoaded) - { - debugAvatarRezTime("AvatarRezNotification","fully loaded"); - } - - // did our loading state "change" from last call? - // FIXME runway - why are we updating every 30 calls even if nothing has changed? - // This causes updateLOD() to run every 30 frames, among other things. - const S32 UPDATE_RATE = 30; - BOOL changed = - ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call - (!mFullyLoadedInitialized) || // if we've never been called before - (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change - BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded); - - mPreviousFullyLoaded = mFullyLoaded; - mFullyLoadedInitialized = TRUE; - mFullyLoadedFrameCounter++; + mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds); + } + else + { + mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY); + } + + if (!mPreviousFullyLoaded && !loading && mFullyLoaded) + { + debugAvatarRezTime("AvatarRezNotification","fully loaded"); + } + + // did our loading state "change" from last call? + // FIXME runway - why are we updating every 30 calls even if nothing has changed? + // This causes updateLOD() to run every 30 frames, among other things. + const S32 UPDATE_RATE = 30; + BOOL changed = + ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call + (!mFullyLoadedInitialized) || // if we've never been called before + (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change + BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded); + + mPreviousFullyLoaded = mFullyLoaded; + mFullyLoadedInitialized = TRUE; + mFullyLoadedFrameCounter++; if (changed && isSelf()) { @@ -8341,45 +8341,45 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) LLAvatarRenderNotifier::getInstance()->updateNotificationState(); } - if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor()) - { - // Fix for jellydoll initially invisible - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 6; - } - return changed; + if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor()) + { + // Fix for jellydoll initially invisible + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 6; + } + return changed; } BOOL LLVOAvatar::isFullyLoaded() const { - return (mRenderUnloadedAvatar || mFullyLoaded); + return (mRenderUnloadedAvatar || mFullyLoaded); } bool LLVOAvatar::isTooComplex() const { - bool too_complex; + bool too_complex; static LLCachedControl always_render_friends(gSavedSettings, "AlwaysRenderFriends"); - bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); - - if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) - { - too_complex = false; - } - else - { - // Determine if visually muted or not - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); - static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f); - // If the user has chosen unlimited max complexity, we also disregard max attachment area + bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); + + if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) + { + too_complex = false; + } + else + { + // Determine if visually muted or not + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); + static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f); + // If the user has chosen unlimited max complexity, we also disregard max attachment area // so that unlimited will completely disable the overly complex impostor rendering // yes, this leaves them vulnerable to griefing objects... their choice too_complex = ( max_render_cost > 0 && (mVisualComplexity > max_render_cost || (max_attachment_area > 0.0f && mAttachmentSurfaceArea > max_attachment_area) )); - } + } - return too_complex; + return too_complex; } bool LLVOAvatar::isTooSlow() const @@ -8387,477 +8387,477 @@ bool LLVOAvatar::isTooSlow() const static LLCachedControl always_render_friends(gSavedSettings, "AlwaysRenderFriends"); bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); - if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) + if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) + { + return false; + } + return mTooSlow; +} + +// Udpate Avatar state based on render time +void LLVOAvatar::updateTooSlow() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + static LLCachedControl alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); + static LLCachedControl allowSelfImpostor(gSavedSettings, "AllowSelfImpostor"); + const auto id = getID(); + + // mTooSlow - Is the avatar flagged as being slow (includes shadow time) + // mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed. + + // get max render time in ms + F32 max_art_ms = (F32) (LLPerfStats::renderAvatarMaxART_ns / 1000000.0); + + bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); + + bool ignore_tune = false; + if (autotune && sAVsIgnoringARTLimit.size() > 0) + { + auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID); + if (it != sAVsIgnoringARTLimit.end()) + { + S32 index = it - sAVsIgnoringARTLimit.begin(); + ignore_tune = (index < (MIN_NONTUNED_AVS - sAvatarsNearby + 1 + LLPerfStats::tunedAvatars)); + } + } + + bool exceeds_max_ART = + ((LLPerfStats::renderAvatarMaxART_ns > 0) && + (mGPURenderTime >= max_art_ms)); // NOTE: don't use getGPURenderTime accessor here to avoid "isTooSlow" feedback loop + + if (exceeds_max_ART && !ignore_tune) + { + mTooSlow = true; + + if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap + { + bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) || + ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER ); + if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception ) + { + // Note: slow rendering Friends still get their shadows zapped. + mTooSlowWithoutShadows = getGPURenderTime()*2.f >= max_art_ms; // NOTE: assumes shadow rendering doubles render time + } + } + } + else + { + mTooSlow = false; + mTooSlowWithoutShadows = false; + + if (ignore_tune) + { + return; + } + } + if(mTooSlow && !mTuned) + { + LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked. + mTuned = true; + } + else if(!mTooSlow && mTuned) + { + LLPerfStats::tunedAvatars--; + mTuned = false; + } +} + +//----------------------------------------------------------------------------- +// findMotion() +//----------------------------------------------------------------------------- +LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const +{ + return mMotionController.findMotion(id); +} + +// This is a semi-deprecated debugging tool - meshes will not show as +// colorized if using deferred rendering. +void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) +{ + if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) + { + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor(color); + } + } + } +} + + +//----------------------------------------------------------------------------- +// updateMeshVisibility() +// Hide the mesh joints if attachments are using baked textures +//----------------------------------------------------------------------------- +void LLVOAvatar::updateMeshVisibility() +{ + bool bake_flag[BAKED_NUM_INDICES]; + memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); + + if (getOverallAppearance() == AOA_NORMAL) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = attachment_iter->get(); + if (objectp) + { + for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectp->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); + } + } + + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild) + { + for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectchild->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); + } + } + } + } + } + } + } + + //LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL; + + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLAvatarJoint* joint = mMeshLOD[i]; + if (i == MESH_ID_HAIR) + { + joint->setVisible(!bake_flag[BAKED_HAIR], TRUE); + } + else if (i == MESH_ID_HEAD) + { + joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); + } + else if (i == MESH_ID_SKIRT) + { + joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE); + } + else if (i == MESH_ID_UPPER_BODY) + { + joint->setVisible(!bake_flag[BAKED_UPPER], TRUE); + } + else if (i == MESH_ID_LOWER_BODY) + { + joint->setVisible(!bake_flag[BAKED_LOWER], TRUE); + } + else if (i == MESH_ID_EYEBALL_LEFT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYEBALL_RIGHT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYELASH) + { + joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); + } + } +} + +//----------------------------------------------------------------------------- +// updateMeshTextures() +// Uses the current TE values to set the meshes' and layersets' textures. +//----------------------------------------------------------------------------- +// virtual +void LLVOAvatar::updateMeshTextures() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + static S32 update_counter = 0; + mBakedTextureDebugText.clear(); + + // if user has never specified a texture, assign the default + for (U32 i=0; i < getNumTEs(); i++) + { + const LLViewerTexture* te_image = getImage(i, 0); + if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) + { + // IMG_DEFAULT_AVATAR = a special texture that's never rendered. + const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR); + setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0); + } + } + + const BOOL other_culled = !isSelf() && mCulled; + LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; + BOOL paused = FALSE; + if(!isSelf()) + { + src_callback_list = &mCallbackTextureList ; + paused = !isVisible(); + } + + std::vector is_layer_baked; + is_layer_baked.resize(mBakedTextureDatas.size(), false); + + std::vector use_lkg_baked_layer; // lkg = "last known good" + use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false); + + mBakedTextureDebugText += llformat("%06d\n",update_counter++); + mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n"; + for (U32 i=0; i < mBakedTextureDatas.size(); i++) + { + is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); + LLViewerTexLayerSet* layerset = NULL; + bool layerset_invalid = false; + if (!other_culled) + { + // When an avatar is changing clothes and not in Appearance mode, + // use the last-known good baked texture until it finishes the first + // render of the new layerset. + layerset = getTexLayerSet(i); + layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized() + || !layerset->isLocalTextureDataAvailable() ); + use_lkg_baked_layer[i] = (!is_layer_baked[i] + && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR) + && layerset_invalid); + if (use_lkg_baked_layer[i]) + { + layerset->setUpdatesEnabled(TRUE); + } + } + else + { + use_lkg_baked_layer[i] = (!is_layer_baked[i] + && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR); + } + + std::string last_id_string; + if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR) + last_id_string = "A"; + else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT) + last_id_string = "D"; + else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE) + last_id_string = "I"; + else + last_id_string = "*"; + bool is_ltda = layerset + && layerset->getViewerComposite()->isInitialized() + && layerset->isLocalTextureDataAvailable(); + mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n", + i, + (layerset?"*":"0"), + layerset_invalid, + is_ltda, + is_layer_baked[i], + use_lkg_baked_layer[i], + last_id_string.c_str()); + } + + for (U32 i=0; i < mBakedTextureDatas.size(); i++) { - return false; - } - return mTooSlow; -} + debugColorizeSubMeshes(i, LLColor4::white); -// Udpate Avatar state based on render time -void LLVOAvatar::updateTooSlow() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - static LLCachedControl alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); - static LLCachedControl allowSelfImpostor(gSavedSettings, "AllowSelfImpostor"); - const auto id = getID(); + LLViewerTexLayerSet* layerset = getTexLayerSet(i); + if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) + { + // use last known good layer (no new one) + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID); + mBakedTextureDatas[i].mIsUsed = TRUE; - // mTooSlow - Is the avatar flagged as being slow (includes shadow time) - // mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed. - - // get max render time in ms - F32 max_art_ms = (F32) (LLPerfStats::renderAvatarMaxART_ns / 1000000.0); + debugColorizeSubMeshes(i,LLColor4::red); + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setTexture( baked_img ); + } + } + } + else if (!isUsingLocalAppearance() && is_layer_baked[i]) + { + // use new layer + LLViewerFetchedTexture* baked_img = + LLViewerTextureManager::staticCastToFetchedTexture( + getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; + if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID ) + { + // Even though the file may not be finished loading, + // we'll consider it loaded and use it (rather than + // doing compositing). + useBakedTexture( baked_img->getID() ); + mLoadedCallbacksPaused |= !isVisible(); + checkTextureLoading(); + } + else + { + mBakedTextureDatas[i].mIsLoaded = FALSE; + if ( (baked_img->getID() != IMG_INVISIBLE) && + ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) + { + baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), + src_callback_list, paused); + } + baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ), + src_callback_list, paused ); + if (baked_img->getDiscardLevel() < 0 && !paused) + { + // mLoadedCallbackTextures will be updated by checkTextureLoading() below + mLastTexCallbackAddedTime.reset(); + } - bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); + // this could add paused texture callbacks + mLoadedCallbacksPaused |= paused; + checkTextureLoading(); + } + } + else if (layerset && isUsingLocalAppearance()) + { + debugColorizeSubMeshes(i,LLColor4::yellow ); - bool ignore_tune = false; - if (autotune && sAVsIgnoringARTLimit.size() > 0) - { - auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID); - if (it != sAVsIgnoringARTLimit.end()) + layerset->createComposite(); + layerset->setUpdatesEnabled( TRUE ); + mBakedTextureDatas[i].mIsUsed = FALSE; + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setLayerSet( layerset ); + } + } + } + else { - S32 index = it - sAVsIgnoringARTLimit.begin(); - ignore_tune = (index < (MIN_NONTUNED_AVS - sAvatarsNearby + 1 + LLPerfStats::tunedAvatars)); + debugColorizeSubMeshes(i,LLColor4::blue); } } - bool exceeds_max_ART = - ((LLPerfStats::renderAvatarMaxART_ns > 0) && - (mGPURenderTime >= max_art_ms)); // NOTE: don't use getGPURenderTime accessor here to avoid "isTooSlow" feedback loop - - if (exceeds_max_ART && !ignore_tune) + // set texture and color of hair manually if we are not using a baked image. + // This can happen while loading hair for yourself, or for clients that did not + // bake a hair texture. Still needed for yourself after 1.22 is depricated. + if (!is_layer_baked[BAKED_HAIR]) { - mTooSlow = true; - - if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap + const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); + LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); + for (; iter != end; ++iter) { - bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) || - ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER ); - if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception ) + LLAvatarJointMesh* mesh = (*iter); + if (mesh) { - // Note: slow rendering Friends still get their shadows zapped. - mTooSlowWithoutShadows = getGPURenderTime()*2.f >= max_art_ms; // NOTE: assumes shadow rendering doubles render time + mesh->setColor( color ); + mesh->setTexture( hair_img ); } } } - else - { - mTooSlow = false; - mTooSlowWithoutShadows = false; - if (ignore_tune) - { - return; - } - } - if(mTooSlow && !mTuned) + + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = + LLAvatarAppearance::getDictionary()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end(); + ++baked_iter) { - LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked. - mTuned = true; + const EBakedTextureIndex baked_index = baked_iter->first; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex texture_index = *local_tex_iter; + const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled; + if (isSelf()) + { + setBakedReady(texture_index, is_baked_ready); + } + } } - else if(!mTooSlow && mTuned) + + // removeMissingBakedTextures() will call back into this rountine if something is removed, and can blow up the stack + static bool call_remove_missing = true; + if (call_remove_missing) { - LLPerfStats::tunedAvatars--; - mTuned = false; + call_remove_missing = false; + removeMissingBakedTextures(); // May call back into this function if anything is removed + call_remove_missing = true; } -} -//----------------------------------------------------------------------------- -// findMotion() -//----------------------------------------------------------------------------- -LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const -{ - return mMotionController.findMotion(id); -} + //refresh bakes on any attached objects + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; -// This is a semi-deprecated debugging tool - meshes will not show as -// colorized if using deferred rendering. -void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) -{ - if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) - { - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setColor(color); - } - } - } -} + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object && !attached_object->isDead()) + { + attached_object->refreshBakeTexture(); + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp && !objectp->isDead()) + { + objectp->refreshBakeTexture(); + } + } + } + } + } -//----------------------------------------------------------------------------- -// updateMeshVisibility() -// Hide the mesh joints if attachments are using baked textures -//----------------------------------------------------------------------------- -void LLVOAvatar::updateMeshVisibility() -{ - bool bake_flag[BAKED_NUM_INDICES]; - memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); - - if (getOverallAppearance() == AOA_NORMAL) - { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *objectp = attachment_iter->get(); - if (objectp) - { - for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = objectp->getTE(face_index); - bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); - bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); - bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); - bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); - bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); - bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); - bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); - bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); - bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); - bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); - bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); - } - } - - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); - iter1 != child_list.end(); ++iter1) - { - LLViewerObject* objectchild = *iter1; - if (objectchild) - { - for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = objectchild->getTE(face_index); - bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); - bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); - bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); - bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); - bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); - bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); - bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); - bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); - bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); - bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); - bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); - } - } - } - } - } - } - } - - //LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL; - - for (S32 i = 0; i < mMeshLOD.size(); i++) - { - LLAvatarJoint* joint = mMeshLOD[i]; - if (i == MESH_ID_HAIR) - { - joint->setVisible(!bake_flag[BAKED_HAIR], TRUE); - } - else if (i == MESH_ID_HEAD) - { - joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); - } - else if (i == MESH_ID_SKIRT) - { - joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE); - } - else if (i == MESH_ID_UPPER_BODY) - { - joint->setVisible(!bake_flag[BAKED_UPPER], TRUE); - } - else if (i == MESH_ID_LOWER_BODY) - { - joint->setVisible(!bake_flag[BAKED_LOWER], TRUE); - } - else if (i == MESH_ID_EYEBALL_LEFT) - { - joint->setVisible(!bake_flag[BAKED_EYES], TRUE); - } - else if (i == MESH_ID_EYEBALL_RIGHT) - { - joint->setVisible(!bake_flag[BAKED_EYES], TRUE); - } - else if (i == MESH_ID_EYELASH) - { - joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); - } - } -} -//----------------------------------------------------------------------------- -// updateMeshTextures() -// Uses the current TE values to set the meshes' and layersets' textures. -//----------------------------------------------------------------------------- -// virtual -void LLVOAvatar::updateMeshTextures() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR - static S32 update_counter = 0; - mBakedTextureDebugText.clear(); - - // if user has never specified a texture, assign the default - for (U32 i=0; i < getNumTEs(); i++) - { - const LLViewerTexture* te_image = getImage(i, 0); - if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) - { - // IMG_DEFAULT_AVATAR = a special texture that's never rendered. - const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR); - setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0); - } - } - - const BOOL other_culled = !isSelf() && mCulled; - LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; - BOOL paused = FALSE; - if(!isSelf()) - { - src_callback_list = &mCallbackTextureList ; - paused = !isVisible(); - } - - std::vector is_layer_baked; - is_layer_baked.resize(mBakedTextureDatas.size(), false); - - std::vector use_lkg_baked_layer; // lkg = "last known good" - use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false); - - mBakedTextureDebugText += llformat("%06d\n",update_counter++); - mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n"; - for (U32 i=0; i < mBakedTextureDatas.size(); i++) - { - is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - LLViewerTexLayerSet* layerset = NULL; - bool layerset_invalid = false; - if (!other_culled) - { - // When an avatar is changing clothes and not in Appearance mode, - // use the last-known good baked texture until it finishes the first - // render of the new layerset. - layerset = getTexLayerSet(i); - layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized() - || !layerset->isLocalTextureDataAvailable() ); - use_lkg_baked_layer[i] = (!is_layer_baked[i] - && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR) - && layerset_invalid); - if (use_lkg_baked_layer[i]) - { - layerset->setUpdatesEnabled(TRUE); - } - } - else - { - use_lkg_baked_layer[i] = (!is_layer_baked[i] - && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR); - } - - std::string last_id_string; - if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR) - last_id_string = "A"; - else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT) - last_id_string = "D"; - else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE) - last_id_string = "I"; - else - last_id_string = "*"; - bool is_ltda = layerset - && layerset->getViewerComposite()->isInitialized() - && layerset->isLocalTextureDataAvailable(); - mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n", - i, - (layerset?"*":"0"), - layerset_invalid, - is_ltda, - is_layer_baked[i], - use_lkg_baked_layer[i], - last_id_string.c_str()); - } - - for (U32 i=0; i < mBakedTextureDatas.size(); i++) - { - debugColorizeSubMeshes(i, LLColor4::white); - - LLViewerTexLayerSet* layerset = getTexLayerSet(i); - if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) - { - // use last known good layer (no new one) - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID); - mBakedTextureDatas[i].mIsUsed = TRUE; - - debugColorizeSubMeshes(i,LLColor4::red); - - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setTexture( baked_img ); - } - } - } - else if (!isUsingLocalAppearance() && is_layer_baked[i]) - { - // use new layer - LLViewerFetchedTexture* baked_img = - LLViewerTextureManager::staticCastToFetchedTexture( - getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; - if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID ) - { - // Even though the file may not be finished loading, - // we'll consider it loaded and use it (rather than - // doing compositing). - useBakedTexture( baked_img->getID() ); - mLoadedCallbacksPaused |= !isVisible(); - checkTextureLoading(); - } - else - { - mBakedTextureDatas[i].mIsLoaded = FALSE; - if ( (baked_img->getID() != IMG_INVISIBLE) && - ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) - { - baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), - src_callback_list, paused); - } - baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ), - src_callback_list, paused ); - if (baked_img->getDiscardLevel() < 0 && !paused) - { - // mLoadedCallbackTextures will be updated by checkTextureLoading() below - mLastTexCallbackAddedTime.reset(); - } - - // this could add paused texture callbacks - mLoadedCallbacksPaused |= paused; - checkTextureLoading(); - } - } - else if (layerset && isUsingLocalAppearance()) - { - debugColorizeSubMeshes(i,LLColor4::yellow ); - - layerset->createComposite(); - layerset->setUpdatesEnabled( TRUE ); - mBakedTextureDatas[i].mIsUsed = FALSE; - - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setLayerSet( layerset ); - } - } - } - else - { - debugColorizeSubMeshes(i,LLColor4::blue); - } - } - - // set texture and color of hair manually if we are not using a baked image. - // This can happen while loading hair for yourself, or for clients that did not - // bake a hair texture. Still needed for yourself after 1.22 is depricated. - if (!is_layer_baked[BAKED_HAIR]) - { - const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); - LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setColor( color ); - mesh->setTexture( hair_img ); - } - } - } - - - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = - LLAvatarAppearance::getDictionary()->getBakedTextures().begin(); - baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end(); - ++baked_iter) - { - const EBakedTextureIndex baked_index = baked_iter->first; - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; - - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex texture_index = *local_tex_iter; - const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled; - if (isSelf()) - { - setBakedReady(texture_index, is_baked_ready); - } - } - } - - // removeMissingBakedTextures() will call back into this rountine if something is removed, and can blow up the stack - static bool call_remove_missing = true; - if (call_remove_missing) - { - call_remove_missing = false; - removeMissingBakedTextures(); // May call back into this function if anything is removed - call_remove_missing = true; - } - - //refresh bakes on any attached objects - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject* attached_object = attachment_iter->get(); - if (attached_object && !attached_object->isDead()) - { - attached_object->refreshBakeTexture(); - - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* objectp = *iter; - if (objectp && !objectp->isDead()) - { - objectp->refreshBakeTexture(); - } - } - } - } - } - - } @@ -8867,92 +8867,92 @@ void LLVOAvatar::updateMeshTextures() //----------------------------------------------------------------------------- void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready, U32 index ) { - // invalid for anyone but self - llassert(0); + // invalid for anyone but self + llassert(0); } -//virtual +//virtual void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) { - // invalid for anyone but self - llassert(0); + // invalid for anyone but self + llassert(0); } void LLVOAvatar::addChat(const LLChat& chat) { - std::deque::iterator chat_iter; + std::deque::iterator chat_iter; - mChats.push_back(chat); + mChats.push_back(chat); - S32 chat_length = 0; - for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter) - { - chat_length += chat_iter->mText.size(); - } + S32 chat_length = 0; + for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter) + { + chat_length += chat_iter->mText.size(); + } - // remove any excess chat - chat_iter = mChats.begin(); - while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end()) - { - chat_length -= chat_iter->mText.size(); - mChats.pop_front(); - chat_iter = mChats.begin(); - } + // remove any excess chat + chat_iter = mChats.begin(); + while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end()) + { + chat_length -= chat_iter->mText.size(); + mChats.pop_front(); + chat_iter = mChats.begin(); + } - mChatTimer.reset(); + mChatTimer.reset(); } void LLVOAvatar::clearChat() { - mChats.clear(); + mChats.clear(); } void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index) { - if (index >= BAKED_NUM_INDICES) - { - LL_WARNS() << "invalid baked texture index passed to applyMorphMask" << LL_ENDL; - return; - } + if (index >= BAKED_NUM_INDICES) + { + LL_WARNS() << "invalid baked texture index passed to applyMorphMask" << LL_ENDL; + return; + } - for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin(); - iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) - { - const LLMaskedMorph* maskedMorph = (*iter); - LLPolyMorphTarget* morph_target = dynamic_cast(maskedMorph->mMorphTarget); - if (morph_target) - { - morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); - } - } + for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin(); + iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) + { + const LLMaskedMorph* maskedMorph = (*iter); + LLPolyMorphTarget* morph_target = dynamic_cast(maskedMorph->mMorphTarget); + if (morph_target) + { + morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); + } + } } // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index) { - if (index >= BAKED_NUM_INDICES) - { - return FALSE; - } + if (index >= BAKED_NUM_INDICES) + { + return FALSE; + } - if (!mBakedTextureDatas[index].mMaskedMorphs.empty()) - { - if (isSelf()) - { - LLViewerTexLayerSet *layer_set = getTexLayerSet(index); - if (layer_set) - { - return !layer_set->isMorphValid(); - } - } - else - { - return FALSE; - } - } + if (!mBakedTextureDatas[index].mMaskedMorphs.empty()) + { + if (isSelf()) + { + LLViewerTexLayerSet *layer_set = getTexLayerSet(index); + if (layer_set) + { + return !layer_set->isMorphValid(); + } + } + else + { + return FALSE; + } + } - return FALSE; + return FALSE; } //----------------------------------------------------------------------------- @@ -8964,66 +8964,66 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIn //----------------------------------------------------------------------------- void LLVOAvatar::releaseComponentTextures() { - // ! BACKWARDS COMPATIBILITY ! - // Detect if the baked hair texture actually wasn't sent, and if so set to default - if (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED,0)->getID() == getImage(TEX_SKIRT_BAKED,0)->getID()) - { - if (getImage(TEX_HAIR_BAKED,0)->getID() != IMG_INVISIBLE) - { - // Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default - setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR); - } - } - - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) - { - const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index); - // skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID - if (!isTextureDefined(bakedDicEntry->mTextureIndex) - && ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) )) - { - continue; - } - - for (U8 texture = 0; texture < bakedDicEntry->mLocalTextures.size(); texture++) - { - const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture]; - setTETexture(te, IMG_DEFAULT_AVATAR); - } - } + // ! BACKWARDS COMPATIBILITY ! + // Detect if the baked hair texture actually wasn't sent, and if so set to default + if (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED,0)->getID() == getImage(TEX_SKIRT_BAKED,0)->getID()) + { + if (getImage(TEX_HAIR_BAKED,0)->getID() != IMG_INVISIBLE) + { + // Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default + setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR); + } + } + + for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) + { + const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index); + // skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID + if (!isTextureDefined(bakedDicEntry->mTextureIndex) + && ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) )) + { + continue; + } + + for (U8 texture = 0; texture < bakedDicEntry->mLocalTextures.size(); texture++) + { + const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture]; + setTETexture(te, IMG_DEFAULT_AVATAR); + } + } } void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const -{ - LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL; - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); - iter != LLAvatarAppearance::getDictionary()->getTextures().end(); - ++iter) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - // TODO: MULTI-WEARABLE: handle multiple textures for self - const LLViewerTexture* te_image = getImage(iter->first,0); - if( !te_image ) - { - LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL; - } - else if( te_image->getID().isNull() ) - { - LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL; - } - else if( te_image->getID() == IMG_DEFAULT ) - { - LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL; - } - else if( te_image->getID() == IMG_DEFAULT_AVATAR ) - { - LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL; - } - else - { - LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL; - } - } +{ + LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL; + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); + iter != LLAvatarAppearance::getDictionary()->getTextures().end(); + ++iter) + { + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + // TODO: MULTI-WEARABLE: handle multiple textures for self + const LLViewerTexture* te_image = getImage(iter->first,0); + if( !te_image ) + { + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL; + } + else if( te_image->getID().isNull() ) + { + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL; + } + else if( te_image->getID() == IMG_DEFAULT ) + { + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL; + } + else if( te_image->getID() == IMG_DEFAULT_AVATAR ) + { + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL; + } + } } //----------------------------------------------------------------------------- @@ -9031,74 +9031,74 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const //----------------------------------------------------------------------------- void LLVOAvatar::clampAttachmentPositions() { - if (isDead()) - { - return; - } - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment) - { - attachment->clampObjectPosition(); - } - } + if (isDead()) + { + return; + } + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + attachment->clampObjectPosition(); + } + } } BOOL LLVOAvatar::hasHUDAttachment() const { - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0) - { - return TRUE; - } - } - return FALSE; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0) + { + return TRUE; + } + } + return FALSE; } LLBBox LLVOAvatar::getHUDBBox() const { - LLBBox bbox; - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getIsHUDAttachment()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = attachment_iter->get(); - if (attached_object == NULL) - { - LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL; - continue; - } - // initialize bounding box to contain identity orientation and center point for attached object - bbox.addPointLocal(attached_object->getPosition()); - // add rotated bounding box for attached object - bbox.addBBoxAgent(attached_object->getBoundingBoxAgent()); - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); - ++iter) - { - const LLViewerObject* child_objectp = *iter; - bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent()); - } - } - } - } - - return bbox; + LLBBox bbox; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object == NULL) + { + LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL; + continue; + } + // initialize bounding box to contain identity orientation and center point for attached object + bbox.addPointLocal(attached_object->getPosition()); + // add rotated bounding box for attached object + bbox.addBBoxAgent(attached_object->getBoundingBoxAgent()); + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); + ++iter) + { + const LLViewerObject* child_objectp = *iter; + bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent()); + } + } + } + } + + return bbox; } //----------------------------------------------------------------------------- @@ -9106,53 +9106,53 @@ LLBBox LLVOAvatar::getHUDBBox() const //----------------------------------------------------------------------------- void LLVOAvatar::onFirstTEMessageReceived() { - LL_DEBUGS("Avatar") << avString() << LL_ENDL; - if( !mFirstTEMessageReceived ) - { - mFirstTEMessageReceived = TRUE; - - LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; - BOOL paused = FALSE ; - if(!isSelf()) - { - src_callback_list = &mCallbackTextureList ; - paused = !isVisible(); - } - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - - // Use any baked textures that we have even if they haven't downloaded yet. - // (That is, don't do a transition from unbaked to baked.) - if (layer_baked) - { - LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; - mBakedTextureDatas[i].mLastTextureID = image->getID(); - // If we have more than one texture for the other baked layers, we'll want to call this for them too. - if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) - { - image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), - src_callback_list, paused); - } - LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL; - image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ), - src_callback_list, paused ); - if (image->getDiscardLevel() < 0 && !paused) - { - mLastTexCallbackAddedTime.reset(); - } + LL_DEBUGS("Avatar") << avString() << LL_ENDL; + if( !mFirstTEMessageReceived ) + { + mFirstTEMessageReceived = TRUE; + + LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; + BOOL paused = FALSE ; + if(!isSelf()) + { + src_callback_list = &mCallbackTextureList ; + paused = !isVisible(); + } + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); + + // Use any baked textures that we have even if they haven't downloaded yet. + // (That is, don't do a transition from unbaked to baked.) + if (layer_baked) + { + LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; + mBakedTextureDatas[i].mLastTextureID = image->getID(); + // If we have more than one texture for the other baked layers, we'll want to call this for them too. + if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) + { + image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), + src_callback_list, paused); + } + LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL; + image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ), + src_callback_list, paused ); + if (image->getDiscardLevel() < 0 && !paused) + { + mLastTexCallbackAddedTime.reset(); + } // this could add paused texture callbacks - mLoadedCallbacksPaused |= paused; - } - } + mLoadedCallbacksPaused |= paused; + } + } mMeshTexturesDirty = TRUE; - gPipeline.markGLRebuild(this); + gPipeline.markGLRebuild(this); mFirstAppearanceMessageTimer.reset(); mFullyLoadedTimer.reset(); - } + } } //----------------------------------------------------------------------------- @@ -9160,240 +9160,240 @@ void LLVOAvatar::onFirstTEMessageReceived() //----------------------------------------------------------------------------- bool LLVOAvatar::visualParamWeightsAreDefault() { - bool rtn = true; - - bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT); - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->isTweakable()) - { - LLViewerVisualParam* vparam = dynamic_cast(param); - llassert(vparam); - bool is_skirt_param = vparam && - LLWearableType::WT_SKIRT == vparam->getWearableType(); - if (param->getWeight() != param->getDefaultWeight() && - // we have to not care whether skirt weights are default, if we're not actually wearing a skirt - (is_wearing_skirt || !is_skirt_param)) - { - //LL_INFOS() << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << LL_ENDL; - rtn = false; - break; - } - } - } - - //LL_INFOS() << "params are default ? " << int(rtn) << LL_ENDL; - - return rtn; + bool rtn = true; + + bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT); + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isTweakable()) + { + LLViewerVisualParam* vparam = dynamic_cast(param); + llassert(vparam); + bool is_skirt_param = vparam && + LLWearableType::WT_SKIRT == vparam->getWearableType(); + if (param->getWeight() != param->getDefaultWeight() && + // we have to not care whether skirt weights are default, if we're not actually wearing a skirt + (is_wearing_skirt || !is_skirt_param)) + { + //LL_INFOS() << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << LL_ENDL; + rtn = false; + break; + } + } + } + + //LL_INFOS() << "params are default ? " << int(rtn) << LL_ENDL; + + return rtn; } void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) { - std::string type_string = "unknown"; - if (dynamic_cast(viewer_param)) - type_string = "param_alpha"; - if (dynamic_cast(viewer_param)) - type_string = "param_color"; - if (dynamic_cast(viewer_param)) - type_string = "param_driver"; - if (dynamic_cast(viewer_param)) - type_string = "param_morph"; - if (dynamic_cast(viewer_param)) - type_string = "param_skeleton"; - S32 wtype = -1; - LLViewerVisualParam *vparam = dynamic_cast(viewer_param); - if (vparam) - { - wtype = vparam->getWearableType(); - } - S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); - apr_file_printf(file, "\t\t\n", - viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(), - LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(), - viewer_param->getGroup()); - } - + std::string type_string = "unknown"; + if (dynamic_cast(viewer_param)) + type_string = "param_alpha"; + if (dynamic_cast(viewer_param)) + type_string = "param_color"; + if (dynamic_cast(viewer_param)) + type_string = "param_driver"; + if (dynamic_cast(viewer_param)) + type_string = "param_morph"; + if (dynamic_cast(viewer_param)) + type_string = "param_skeleton"; + S32 wtype = -1; + LLViewerVisualParam *vparam = dynamic_cast(viewer_param); + if (vparam) + { + wtype = vparam->getWearableType(); + } + S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); + apr_file_printf(file, "\t\t\n", + viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(), + LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(), + viewer_param->getGroup()); + } + void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, - const LLAppearanceMessageContents& contents) -{ - std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml"); - const std::vector& params_for_dump = contents.mParamWeights; - const LLTEContents& tec = contents.mTEContents; - - LLAPRFile outfile; - std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); - outfile.open(fullpath, LL_APR_WB ); - apr_file_t* file = outfile.getFileHandle(); - if (!file) - { - return; - } - else - { - LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL; - } - - apr_file_printf(file, "
\n"); - apr_file_printf(file, "\t\t\n", contents.mCOFVersion); - apr_file_printf(file, "\t\t\n", contents.mAppearanceVersion); - apr_file_printf(file, "
\n"); - - apr_file_printf(file, "\n\n"); - LLVisualParam* param = getFirstVisualParam(); - for (S32 i = 0; i < params_for_dump.size(); i++) - { - while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT - { - param = getNextVisualParam(); - } - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - F32 value = params_for_dump[i]; - dump_visual_param(file, viewer_param, value); - param = getNextVisualParam(); - } - apr_file_printf(file, "\n"); - - apr_file_printf(file, "\n\n"); - for (U32 i = 0; i < tec.face_count; i++) - { - std::string uuid_str; - ((LLUUID*)tec.image_data)[i].toString(uuid_str); - apr_file_printf( file, "\t\t\n", i, uuid_str.c_str()); - } - apr_file_printf(file, "\n"); + const LLAppearanceMessageContents& contents) +{ + std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml"); + const std::vector& params_for_dump = contents.mParamWeights; + const LLTEContents& tec = contents.mTEContents; + + LLAPRFile outfile; + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + outfile.open(fullpath, LL_APR_WB ); + apr_file_t* file = outfile.getFileHandle(); + if (!file) + { + return; + } + else + { + LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL; + } + + apr_file_printf(file, "
\n"); + apr_file_printf(file, "\t\t\n", contents.mCOFVersion); + apr_file_printf(file, "\t\t\n", contents.mAppearanceVersion); + apr_file_printf(file, "
\n"); + + apr_file_printf(file, "\n\n"); + LLVisualParam* param = getFirstVisualParam(); + for (S32 i = 0; i < params_for_dump.size(); i++) + { + while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT + { + param = getNextVisualParam(); + } + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + F32 value = params_for_dump[i]; + dump_visual_param(file, viewer_param, value); + param = getNextVisualParam(); + } + apr_file_printf(file, "\n"); + + apr_file_printf(file, "\n\n"); + for (U32 i = 0; i < tec.face_count; i++) + { + std::string uuid_str; + ((LLUUID*)tec.image_data)[i].toString(uuid_str); + apr_file_printf( file, "\t\t\n", i, uuid_str.c_str()); + } + apr_file_printf(file, "\n"); } void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents) { - parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents); - - // Parse the AppearanceData field, if any. - if (mesgsys->has(_PREHASH_AppearanceData)) - { - U8 av_u8; - mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0); - contents.mAppearanceVersion = av_u8; - //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL; - mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0); - // For future use: - //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); - } - - // Parse the AppearanceData field, if any. - contents.mHoverOffsetWasSet = false; - if (mesgsys->has(_PREHASH_AppearanceHover)) - { - LLVector3 hover; - mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover); - //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL; - contents.mHoverOffset = hover; - contents.mHoverOffsetWasSet = true; - } - - // Parse visual params, if any. - S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); + parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents); + + // Parse the AppearanceData field, if any. + if (mesgsys->has(_PREHASH_AppearanceData)) + { + U8 av_u8; + mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0); + contents.mAppearanceVersion = av_u8; + //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL; + mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0); + // For future use: + //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); + } + + // Parse the AppearanceData field, if any. + contents.mHoverOffsetWasSet = false; + if (mesgsys->has(_PREHASH_AppearanceHover)) + { + LLVector3 hover; + mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover); + //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL; + contents.mHoverOffset = hover; + contents.mHoverOffsetWasSet = true; + } + + // Parse visual params, if any. + S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); static LLCachedControl block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams"); - bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing - if( num_blocks > 1 && !drop_visual_params_debug) - { - //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; - - LLVisualParam* param = getFirstVisualParam(); - llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 - if (!param) - { - LL_WARNS() << "No visual params!" << LL_ENDL; - } - else - { - for( S32 i = 0; i < num_blocks; i++ ) - { - while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT - { - param = getNextVisualParam(); - } - - if( !param ) - { - // more visual params supplied than expected - just process what we know about - break; - } - - U8 value; - mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i); - F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); - contents.mParamWeights.push_back(newWeight); - contents.mParams.push_back(param); - - param = getNextVisualParam(); - } - } - - const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) + - getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT - if (num_blocks != expected_tweakable_count) - { - LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; - } - } - else - { - if (drop_visual_params_debug) - { - LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL; - } - else - { - LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL; - } - } - - LLVisualParam* appearance_version_param = getVisualParam(11000); - if (appearance_version_param) - { - std::vector::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param); - if (it != contents.mParams.end()) - { - S32 index = it - contents.mParams.begin(); - contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]); - //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; - } - } + bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing + if( num_blocks > 1 && !drop_visual_params_debug) + { + //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; + + LLVisualParam* param = getFirstVisualParam(); + llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 + if (!param) + { + LL_WARNS() << "No visual params!" << LL_ENDL; + } + else + { + for( S32 i = 0; i < num_blocks; i++ ) + { + while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT + { + param = getNextVisualParam(); + } + + if( !param ) + { + // more visual params supplied than expected - just process what we know about + break; + } + + U8 value; + mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i); + F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); + contents.mParamWeights.push_back(newWeight); + contents.mParams.push_back(param); + + param = getNextVisualParam(); + } + } + + const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) + + getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT + if (num_blocks != expected_tweakable_count) + { + LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; + } + } + else + { + if (drop_visual_params_debug) + { + LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL; + } + } + + LLVisualParam* appearance_version_param = getVisualParam(11000); + if (appearance_version_param) + { + std::vector::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param); + if (it != contents.mParams.end()) + { + S32 index = it - contents.mParams.begin(); + contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]); + //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; + } + } } bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version) { - appearance_version = -1; - - if ((contents.mAppearanceVersion) >= 0 && - (contents.mParamAppearanceVersion >= 0) && - (contents.mAppearanceVersion != contents.mParamAppearanceVersion)) - { - LL_WARNS() << "inconsistent appearance_version settings - field: " << - contents.mAppearanceVersion << ", param: " << contents.mParamAppearanceVersion << LL_ENDL; - return false; - } - if (contents.mParamAppearanceVersion >= 0) // use visual param if available. - { - appearance_version = contents.mParamAppearanceVersion; - } - else if (contents.mAppearanceVersion > 0) - { - appearance_version = contents.mAppearanceVersion; - } - else // still not set, go with 1. - { - appearance_version = 1; - } - //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion - // << " param: " << contents.mParamAppearanceVersion - // << " final: " << appearance_version << LL_ENDL; - return true; + appearance_version = -1; + + if ((contents.mAppearanceVersion) >= 0 && + (contents.mParamAppearanceVersion >= 0) && + (contents.mAppearanceVersion != contents.mParamAppearanceVersion)) + { + LL_WARNS() << "inconsistent appearance_version settings - field: " << + contents.mAppearanceVersion << ", param: " << contents.mParamAppearanceVersion << LL_ENDL; + return false; + } + if (contents.mParamAppearanceVersion >= 0) // use visual param if available. + { + appearance_version = contents.mParamAppearanceVersion; + } + else if (contents.mAppearanceVersion > 0) + { + appearance_version = contents.mAppearanceVersion; + } + else // still not set, go with 1. + { + appearance_version = 1; + } + //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion + // << " param: " << contents.mParamAppearanceVersion + // << " final: " << appearance_version << LL_ENDL; + return true; } //----------------------------------------------------------------------------- @@ -9401,46 +9401,46 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { - LL_DEBUGS("Avatar") << "starts" << LL_ENDL; + LL_DEBUGS("Avatar") << "starts" << LL_ENDL; static LLCachedControl enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage"); static LLCachedControl block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages"); - std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; - if (block_avatar_appearance_messages) - { - LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL; - return; - } - - mLastAppearanceMessageTimer.reset(); - - LLPointer contents(new LLAppearanceMessageContents); - parseAppearanceMessage(mesgsys, *contents); - if (enable_verbose_dumps) - { - dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents); - } - - S32 appearance_version; - if (!resolve_appearance_version(*contents, appearance_version)) - { - LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL; - return; - } - llassert(appearance_version > 0); - if (appearance_version > 1) - { - LL_WARNS() << "unsupported appearance version " << appearance_version << ", discarding appearance message" << LL_ENDL; - return; - } + std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; + if (block_avatar_appearance_messages) + { + LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL; + return; + } + + mLastAppearanceMessageTimer.reset(); + + LLPointer contents(new LLAppearanceMessageContents); + parseAppearanceMessage(mesgsys, *contents); + if (enable_verbose_dumps) + { + dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents); + } + + S32 appearance_version; + if (!resolve_appearance_version(*contents, appearance_version)) + { + LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL; + return; + } + llassert(appearance_version > 0); + if (appearance_version > 1) + { + LL_WARNS() << "unsupported appearance version " << appearance_version << ", discarding appearance message" << LL_ENDL; + return; + } S32 thisAppearanceVersion(contents->mCOFVersion); if (isSelf()) - { // In the past this was considered to be the canonical COF version, - // that is no longer the case. The canonical version is maintained + { // In the past this was considered to be the canonical COF version, + // that is no longer the case. The canonical version is maintained // by the AIS code and should match the COF version there. Even so, - // we must prevent rolling this one backwards backwards or processing + // we must prevent rolling this one backwards backwards or processing // stale versions. S32 aisCOFVersion(LLAppearanceMgr::instance().getCOFVersion()); @@ -9464,23 +9464,23 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } - // SUNSHINE CLEANUP - is this case OK now? - S32 num_params = contents->mParamWeights.size(); - if (num_params <= 1) - { - // In this case, we have no reliable basis for knowing - // appearance version, which may cause us to look for baked - // textures in the wrong place and flag them as missing - // assets. - LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << LL_ENDL; - return; - } + // SUNSHINE CLEANUP - is this case OK now? + S32 num_params = contents->mParamWeights.size(); + if (num_params <= 1) + { + // In this case, we have no reliable basis for knowing + // appearance version, which may cause us to look for baked + // textures in the wrong place and flag them as missing + // assets. + LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << LL_ENDL; + return; + } - // No backsies zone - if we get here, the message should be valid and usable, will be processed. - // Note: - // RequestAgentUpdateAppearanceResponder::onRequestRequested() - // assumes that cof version is only updated with server-bake - // appearance messages. + // No backsies zone - if we get here, the message should be valid and usable, will be processed. + // Note: + // RequestAgentUpdateAppearanceResponder::onRequestRequested() + // assumes that cof version is only updated with server-bake + // appearance messages. if (isSelf()) { LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; @@ -9492,202 +9492,202 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // Note: // locally the COF is maintained via LLInventoryModel::accountForUpdate - // which is called from various places. This should match the simhost's + // which is called from various places. This should match the simhost's // idea of what the COF version is. AIS however maintains its own version - // of the COF that should be considered canonical. + // of the COF that should be considered canonical. mLastUpdateReceivedCOFVersion = thisAppearanceVersion; mLastProcessedAppearance = contents; bool slam_params = false; - applyParsedAppearanceMessage(*contents, slam_params); - if (getOverallAppearance() != AOA_NORMAL) - { - resetSkeleton(false); - } + applyParsedAppearanceMessage(*contents, slam_params); + if (getOverallAppearance() != AOA_NORMAL) + { + resetSkeleton(false); + } } void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params) { - S32 num_params = contents.mParamWeights.size(); - ESex old_sex = getSex(); + S32 num_params = contents.mParamWeights.size(); + ESex old_sex = getSex(); if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE)) { updateVisualComplexity(); } - // prevent the overwriting of valid baked textures with invalid baked textures - for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) - { - if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) - && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT - && baked_index != BAKED_SKIRT && baked_index != BAKED_LEFT_ARM && baked_index != BAKED_LEFT_LEG && baked_index != BAKED_AUX1 && baked_index != BAKED_AUX2 && baked_index != BAKED_AUX3) - { - LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using mLastTextureID " << mBakedTextureDatas[baked_index].mLastTextureID << LL_ENDL; - setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, - LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); - } - else - { - LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using texture id " - << getTE(mBakedTextureDatas[baked_index].mTextureIndex)->getID() << LL_ENDL; - } - } - - // runway - was - // if (!is_first_appearance_message ) - // which means it would be called on second appearance message - probably wrong. - BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; - mFirstAppearanceMessageReceived = TRUE; - - //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID + // prevent the overwriting of valid baked textures with invalid baked textures + for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) + { + if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) + && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT + && baked_index != BAKED_SKIRT && baked_index != BAKED_LEFT_ARM && baked_index != BAKED_LEFT_LEG && baked_index != BAKED_AUX1 && baked_index != BAKED_AUX2 && baked_index != BAKED_AUX3) + { + LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using mLastTextureID " << mBakedTextureDatas[baked_index].mLastTextureID << LL_ENDL; + setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, + LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + } + else + { + LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using texture id " + << getTE(mBakedTextureDatas[baked_index].mTextureIndex)->getID() << LL_ENDL; + } + } + + // runway - was + // if (!is_first_appearance_message ) + // which means it would be called on second appearance message - probably wrong. + BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; + mFirstAppearanceMessageReceived = TRUE; + + //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID // << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; - if (is_first_appearance_message ) - { - onFirstTEMessageReceived(); - } - - setCompositeUpdatesEnabled( FALSE ); - gPipeline.markGLRebuild(this); - - // Apply visual params - if( num_params > 1) - { - //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; - BOOL params_changed = FALSE; - BOOL interp_params = FALSE; - S32 params_changed_count = 0; - - for( S32 i = 0; i < num_params; i++ ) - { - LLVisualParam* param = contents.mParams[i]; - F32 newWeight = contents.mParamWeights[i]; - - if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight)) - { - params_changed = TRUE; - params_changed_count++; - - if(is_first_appearance_message || slam_params) - { - //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL; - param->setWeight(newWeight); - } - else - { - interp_params = TRUE; - param->setAnimationTarget(newWeight); - } - } - } - const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) + - getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT - if (num_params != expected_tweakable_count) - { - LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; - } - - LL_DEBUGS("Avatar") << "Changed " << params_changed_count << " params" << LL_ENDL; - if (params_changed) - { - if (interp_params) - { - startAppearanceAnimation(); - } - updateVisualParams(); - - ESex new_sex = getSex(); - if( old_sex != new_sex ) - { - updateSexDependentLayerSets(); - } - } - - llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); - } - else - { - // AvatarAppearance message arrived without visual params - LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL; - - const F32 LOADING_TIMEOUT_SECONDS = 60.f; - // this isn't really a problem if we already have a non-default shape - if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS) - { - // re-request appearance, hoping that it comes back with a shape next time - LL_INFOS() << "Re-requesting AvatarAppearance for object: " << getID() << LL_ENDL; - LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); - mRuthTimer.reset(); - } - else - { - LL_INFOS() << "That's okay, we already have a non-default shape for object: " << getID() << LL_ENDL; - // we don't really care. - } - } - - if (contents.mHoverOffsetWasSet && !isSelf()) - { - // Got an update for some other avatar - // Ignore updates for self, because we have a more authoritative value in the preferences. - setHoverOffset(contents.mHoverOffset); - LL_DEBUGS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL; - } - - if (!contents.mHoverOffsetWasSet && !isSelf()) - { - // If we don't get a value at all, we are presumably in a - // region that does not support hover height. - LL_WARNS() << avString() << "zeroing hover because not defined in appearance message" << LL_ENDL; - setHoverOffset(LLVector3(0.0, 0.0, 0.0)); - } - - setCompositeUpdatesEnabled( TRUE ); - - // If all of the avatars are completely baked, release the global image caches to conserve memory. - LLVOAvatar::cullAvatarsByPixelArea(); - - if (isSelf()) - { - mUseLocalAppearance = false; - } - - updateMeshTextures(); - updateMeshVisibility(); + if (is_first_appearance_message ) + { + onFirstTEMessageReceived(); + } + + setCompositeUpdatesEnabled( FALSE ); + gPipeline.markGLRebuild(this); + + // Apply visual params + if( num_params > 1) + { + //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; + BOOL params_changed = FALSE; + BOOL interp_params = FALSE; + S32 params_changed_count = 0; + + for( S32 i = 0; i < num_params; i++ ) + { + LLVisualParam* param = contents.mParams[i]; + F32 newWeight = contents.mParamWeights[i]; + + if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight)) + { + params_changed = TRUE; + params_changed_count++; + + if(is_first_appearance_message || slam_params) + { + //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL; + param->setWeight(newWeight); + } + else + { + interp_params = TRUE; + param->setAnimationTarget(newWeight); + } + } + } + const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) + + getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT + if (num_params != expected_tweakable_count) + { + LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL; + } + + LL_DEBUGS("Avatar") << "Changed " << params_changed_count << " params" << LL_ENDL; + if (params_changed) + { + if (interp_params) + { + startAppearanceAnimation(); + } + updateVisualParams(); + + ESex new_sex = getSex(); + if( old_sex != new_sex ) + { + updateSexDependentLayerSets(); + } + } + + llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); + } + else + { + // AvatarAppearance message arrived without visual params + LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL; + + const F32 LOADING_TIMEOUT_SECONDS = 60.f; + // this isn't really a problem if we already have a non-default shape + if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS) + { + // re-request appearance, hoping that it comes back with a shape next time + LL_INFOS() << "Re-requesting AvatarAppearance for object: " << getID() << LL_ENDL; + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); + mRuthTimer.reset(); + } + else + { + LL_INFOS() << "That's okay, we already have a non-default shape for object: " << getID() << LL_ENDL; + // we don't really care. + } + } + + if (contents.mHoverOffsetWasSet && !isSelf()) + { + // Got an update for some other avatar + // Ignore updates for self, because we have a more authoritative value in the preferences. + setHoverOffset(contents.mHoverOffset); + LL_DEBUGS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL; + } + + if (!contents.mHoverOffsetWasSet && !isSelf()) + { + // If we don't get a value at all, we are presumably in a + // region that does not support hover height. + LL_WARNS() << avString() << "zeroing hover because not defined in appearance message" << LL_ENDL; + setHoverOffset(LLVector3(0.0, 0.0, 0.0)); + } + + setCompositeUpdatesEnabled( TRUE ); + + // If all of the avatars are completely baked, release the global image caches to conserve memory. + LLVOAvatar::cullAvatarsByPixelArea(); + + if (isSelf()) + { + mUseLocalAppearance = false; + } + + updateMeshTextures(); + updateMeshVisibility(); } LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te) { - if (te < 0 || te >= BAKED_NUM_INDICES) - { - return NULL; - } + if (te < 0 || te >= BAKED_NUM_INDICES) + { + return NULL; + } + + BOOL is_layer_baked = isTextureDefined(mBakedTextureDatas[te].mTextureIndex); + + LLViewerTexLayerSet* layerset = NULL; + layerset = getTexLayerSet(te); - BOOL is_layer_baked = isTextureDefined(mBakedTextureDatas[te].mTextureIndex); - - LLViewerTexLayerSet* layerset = NULL; - layerset = getTexLayerSet(te); - - if (!isEditingAppearance() && is_layer_baked) - { - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage(mBakedTextureDatas[te].mTextureIndex, 0), TRUE); - return baked_img; - } - else if (layerset && isEditingAppearance()) - { - layerset->createComposite(); - layerset->setUpdatesEnabled(TRUE); + if (!isEditingAppearance() && is_layer_baked) + { + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage(mBakedTextureDatas[te].mTextureIndex, 0), TRUE); + return baked_img; + } + else if (layerset && isEditingAppearance()) + { + layerset->createComposite(); + layerset->setUpdatesEnabled(TRUE); + + return layerset->getViewerComposite(); + } - return layerset->getViewerComposite(); - } + return NULL; - return NULL; - } const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin) @@ -9741,262 +9741,262 @@ const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(co // static void LLVOAvatar::getAnimLabels( std::vector* labels ) { - S32 i; - labels->reserve(gUserAnimStatesCount); - for( i = 0; i < gUserAnimStatesCount; i++ ) - { - labels->push_back( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) ); - } + S32 i; + labels->reserve(gUserAnimStatesCount); + for( i = 0; i < gUserAnimStatesCount; i++ ) + { + labels->push_back( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) ); + } - // Special case to trigger away (AFK) state - labels->push_back( "Away From Keyboard" ); + // Special case to trigger away (AFK) state + labels->push_back( "Away From Keyboard" ); } -// static +// static void LLVOAvatar::getAnimNames( std::vector* names ) { - S32 i; + S32 i; - names->reserve(gUserAnimStatesCount); - for( i = 0; i < gUserAnimStatesCount; i++ ) - { - names->push_back( std::string(gUserAnimStates[i].mName) ); - } + names->reserve(gUserAnimStatesCount); + for( i = 0; i < gUserAnimStatesCount; i++ ) + { + names->push_back( std::string(gUserAnimStates[i].mName) ); + } - // Special case to trigger away (AFK) state - names->push_back( "enter_away_from_keyboard_state" ); + // Special case to trigger away (AFK) state + names->push_back( "enter_away_from_keyboard_state" ); } // static void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { - if (!userdata) return; - - //LL_INFOS() << "onBakedTextureMasksLoaded: " << src_vi->getID() << LL_ENDL; - const LLUUID id = src_vi->getID(); - - LLTextureMaskData* maskData = (LLTextureMaskData*) userdata; - LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID ); - - // if discard level is 2 less than last discard level we processed, or we hit 0, - // then generate morph masks - if(self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0)) - { - if(aux_src && aux_src->getComponents() == 1) - { - if (!aux_src->getData()) - { - LL_ERRS() << "No auxiliary source (morph mask) data for image id " << id << LL_ENDL; - return; - } - - U32 gl_name; - LLImageGL::generateTextures(1, &gl_name ); - stop_glerror(); - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); - stop_glerror(); - - LLImageGL::setManualImage( - GL_TEXTURE_2D, 0, GL_ALPHA8, - aux_src->getWidth(), aux_src->getHeight(), - GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData()); - stop_glerror(); - - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - - /* if( id == head_baked->getID() ) - if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) - //LL_INFOS() << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << LL_ENDL; - self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); - maskData->mLastDiscardLevel = discard_level; */ - BOOL found_texture_id = false; - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); - iter != LLAvatarAppearance::getDictionary()->getTextures().end(); - ++iter) - { - - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - if (texture_dict->mIsUsedByBakedTexture) - { - const ETextureIndex texture_index = iter->first; - const LLViewerTexture *baked_img = self->getImage(texture_index, 0); - if (baked_img && id == baked_img->getID()) - { - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index); - maskData->mLastDiscardLevel = discard_level; - if (self->mBakedTextureDatas[baked_index].mMaskTexName) - { - LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); - } - self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name; - found_texture_id = true; - break; - } - } - } - if (!found_texture_id) - { - LL_INFOS() << "unexpected image id: " << id << LL_ENDL; - } - self->dirtyMesh(); - } - else - { - // this can happen when someone uses an old baked texture possibly provided by + if (!userdata) return; + + //LL_INFOS() << "onBakedTextureMasksLoaded: " << src_vi->getID() << LL_ENDL; + const LLUUID id = src_vi->getID(); + + LLTextureMaskData* maskData = (LLTextureMaskData*) userdata; + LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID ); + + // if discard level is 2 less than last discard level we processed, or we hit 0, + // then generate morph masks + if(self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0)) + { + if(aux_src && aux_src->getComponents() == 1) + { + if (!aux_src->getData()) + { + LL_ERRS() << "No auxiliary source (morph mask) data for image id " << id << LL_ENDL; + return; + } + + U32 gl_name; + LLImageGL::generateTextures(1, &gl_name ); + stop_glerror(); + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); + stop_glerror(); + + LLImageGL::setManualImage( + GL_TEXTURE_2D, 0, GL_ALPHA8, + aux_src->getWidth(), aux_src->getHeight(), + GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData()); + stop_glerror(); + + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + + /* if( id == head_baked->getID() ) + if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) + //LL_INFOS() << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << LL_ENDL; + self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); + maskData->mLastDiscardLevel = discard_level; */ + BOOL found_texture_id = false; + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); + iter != LLAvatarAppearance::getDictionary()->getTextures().end(); + ++iter) + { + + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + if (texture_dict->mIsUsedByBakedTexture) + { + const ETextureIndex texture_index = iter->first; + const LLViewerTexture *baked_img = self->getImage(texture_index, 0); + if (baked_img && id == baked_img->getID()) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index); + maskData->mLastDiscardLevel = discard_level; + if (self->mBakedTextureDatas[baked_index].mMaskTexName) + { + LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); + } + self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name; + found_texture_id = true; + break; + } + } + } + if (!found_texture_id) + { + LL_INFOS() << "unexpected image id: " << id << LL_ENDL; + } + self->dirtyMesh(); + } + else + { + // this can happen when someone uses an old baked texture possibly provided by // viewer-side baked texture caching - LL_WARNS() << "Masks loaded callback but NO aux source, id " << id << LL_ENDL; - } - } + LL_WARNS() << "Masks loaded callback but NO aux source, id " << id << LL_ENDL; + } + } - if (final || !success) - { - delete maskData; - } + if (final || !success) + { + delete maskData; + } } // static void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { - LLUUID *avatar_idp = (LLUUID *)userdata; - LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); + LLUUID *avatar_idp = (LLUUID *)userdata; + LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); - if (selfp) - { - //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; - } + if (selfp) + { + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; + } - if (!success && selfp) - { - selfp->removeMissingBakedTextures(); - } - if (final || !success ) - { - delete avatar_idp; - } + if (!success && selfp) + { + selfp->removeMissingBakedTextures(); + } + if (final || !success ) + { + delete avatar_idp; + } } // Static void LLVOAvatar::onBakedTextureLoaded(BOOL success, - LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, - S32 discard_level, BOOL final, void* userdata) + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, + S32 discard_level, BOOL final, void* userdata) { - //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL; + //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL; - LLUUID id = src_vi->getID(); - LLUUID *avatar_idp = (LLUUID *)userdata; - LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); - if (selfp) - { - //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; - } + LLUUID id = src_vi->getID(); + LLUUID *avatar_idp = (LLUUID *)userdata; + LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); + if (selfp) + { + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; + } - if (selfp && !success) - { - selfp->removeMissingBakedTextures(); - } + if (selfp && !success) + { + selfp->removeMissingBakedTextures(); + } - if( final || !success ) - { - delete avatar_idp; - } + if( final || !success ) + { + delete avatar_idp; + } - if( selfp && success && final ) - { - selfp->useBakedTexture( id ); - } + if( selfp && success && final ) + { + selfp->useBakedTexture( id ); + } } // Called when baked texture is loaded and also when we start up with a baked texture void LLVOAvatar::useBakedTexture( const LLUUID& id ) { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); - if (id == image_baked->getID()) - { - //LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL; - mBakedTextureDatas[i].mIsLoaded = true; - mBakedTextureDatas[i].mLastTextureID = id; - mBakedTextureDatas[i].mIsUsed = true; - - if (isUsingLocalAppearance()) - { - LL_INFOS() << "not changing to baked texture while isUsingLocalAppearance" << LL_ENDL; - } - else - { - debugColorizeSubMeshes(i,LLColor4::green); - - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setTexture( image_baked ); - } - } - } - - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = - LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i); - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - if (isSelf()) setBakedReady(*local_tex_iter, TRUE); - } - - // ! BACKWARDS COMPATIBILITY ! - // Workaround for viewing avatars from old viewers that haven't baked hair textures. - // This is paired with similar code in updateMeshTextures that sets hair mesh color. - if (i == BAKED_HAIR) - { - avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); - avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); - for (; iter != end; ++iter) - { - LLAvatarJointMesh* mesh = (*iter); - if (mesh) - { - mesh->setColor( LLColor4::white ); - } - } - } - } - } - - dirtyMesh(); + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); + if (id == image_baked->getID()) + { + //LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL; + mBakedTextureDatas[i].mIsLoaded = true; + mBakedTextureDatas[i].mLastTextureID = id; + mBakedTextureDatas[i].mIsUsed = true; + + if (isUsingLocalAppearance()) + { + LL_INFOS() << "not changing to baked texture while isUsingLocalAppearance" << LL_ENDL; + } + else + { + debugColorizeSubMeshes(i,LLColor4::green); + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setTexture( image_baked ); + } + } + } + + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = + LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i); + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + if (isSelf()) setBakedReady(*local_tex_iter, TRUE); + } + + // ! BACKWARDS COMPATIBILITY ! + // Workaround for viewing avatars from old viewers that haven't baked hair textures. + // This is paired with similar code in updateMeshTextures that sets hair mesh color. + if (i == BAKED_HAIR) + { + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor( LLColor4::white ); + } + } + } + } + } + + dirtyMesh(); } std::string get_sequential_numbered_file_name(const std::string& prefix, - const std::string& suffix) -{ - typedef std::map file_num_type; - static file_num_type file_nums; - file_num_type::iterator it = file_nums.find(prefix); - S32 num = 0; - if (it != file_nums.end()) - { - num = it->second; - } - file_nums[prefix] = num+1; - std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml"; - std::replace(outfilename.begin(),outfilename.end(),' ','_'); - return outfilename; + const std::string& suffix) +{ + typedef std::map file_num_type; + static file_num_type file_nums; + file_num_type::iterator it = file_nums.find(prefix); + S32 num = 0; + if (it != file_nums.end()) + { + num = it->second; + } + file_nums[prefix] = num+1; + std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml"; + std::replace(outfilename.begin(),outfilename.end(),' ','_'); + return outfilename; } void dump_sequential_xml(const std::string outprefix, const LLSD& content) { - std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); - std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); - llofstream ofs(fullpath.c_str(), std::ios_base::out); - ofs << LLSDOStreamer(content, LLSDFormatter::OPTIONS_PRETTY); - LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; + std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + llofstream ofs(fullpath.c_str(), std::ios_base::out); + ofs << LLSDOStreamer(content, LLSDFormatter::OPTIONS_PRETTY); + LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; } void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector& result) const @@ -10006,125 +10006,125 @@ void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector& r { avatar_joint_list_t::const_iterator iter = mSkeleton.begin(); avatar_joint_list_t::const_iterator end = mSkeleton.end(); - for (; iter != end; ++iter) - { - LLJoint* pJoint = (*iter); + for (; iter != end; ++iter) + { + LLJoint* pJoint = (*iter); + result.push_back(pJoint->getName()); + } + } + else if (joint_type==1) + { + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + LLAvatarJointCollisionVolume* pJoint = &mCollisionVolumes[i]; result.push_back(pJoint->getName()); } - } - else if (joint_type==1) - { - for (S32 i = 0; i < mNumCollisionVolumes; i++) + } + else if (joint_type==2) + { + for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ++iter) + { + LLViewerJointAttachment* pJoint = iter->second; + if (!pJoint) continue; + result.push_back(pJoint->getName()); + } + } + std::sort(result.begin(), result.end()); +} + +void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables ) +{ + std::string outprefix(prefix); + if (outprefix.empty()) + { + outprefix = getFullname() + (isSelf()?"_s":"_o"); + } + if (outprefix.empty()) + { + outprefix = std::string("new_archetype"); + } + std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); + + LLAPRFile outfile; + LLWearableType *wr_inst = LLWearableType::getInstance(); + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB )) + { + apr_file_t* file = outfile.getFileHandle(); + LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL; + + apr_file_printf( file, "\n" ); + apr_file_printf( file, "\n" ); + apr_file_printf( file, "\n\t\n" ); + + bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery(); + + if (group_by_wearables) + { + for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) + { + const std::string& wearable_name = wr_inst->getTypeName((LLWearableType::EType)type); + apr_file_printf( file, "\n\t\t\n", wearable_name.c_str() ); + + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + if( (viewer_param->getWearableType() == type) && + (viewer_param->isTweakable() ) ) + { + dump_visual_param(file, viewer_param, viewer_param->getWeight()); + } + } + + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type) + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + std::string uuid_str = LLUUID().asString(); + if (agent_is_godlike) + { + te_image->getID().toString(uuid_str); + } + apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); + } + } + } + } + } + else { - LLAvatarJointCollisionVolume* pJoint = &mCollisionVolumes[i]; - result.push_back(pJoint->getName()); - } - } - else if (joint_type==2) - { - for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ++iter) - { - LLViewerJointAttachment* pJoint = iter->second; - if (!pJoint) continue; - result.push_back(pJoint->getName()); - } - } - std::sort(result.begin(), result.end()); -} + // Just dump all params sequentially. + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + dump_visual_param(file, viewer_param, viewer_param->getWeight()); + } -void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables ) -{ - std::string outprefix(prefix); - if (outprefix.empty()) - { - outprefix = getFullname() + (isSelf()?"_s":"_o"); - } - if (outprefix.empty()) - { - outprefix = std::string("new_archetype"); - } - std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); - - LLAPRFile outfile; - LLWearableType *wr_inst = LLWearableType::getInstance(); - std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); - if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB )) - { - apr_file_t* file = outfile.getFileHandle(); - LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL; - - apr_file_printf( file, "\n" ); - apr_file_printf( file, "\n" ); - apr_file_printf( file, "\n\t\n" ); - - bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery(); - - if (group_by_wearables) - { - for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) - { - const std::string& wearable_name = wr_inst->getTypeName((LLWearableType::EType)type); - apr_file_printf( file, "\n\t\t\n", wearable_name.c_str() ); - - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) - { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type) && - (viewer_param->isTweakable() ) ) - { - dump_visual_param(file, viewer_param, viewer_param->getWeight()); - } - } - - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { - if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type) - { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) - { - std::string uuid_str = LLUUID().asString(); - if (agent_is_godlike) - { - te_image->getID().toString(uuid_str); - } - apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); - } - } - } - } - } - else - { - // Just dump all params sequentially. - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) - { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - dump_visual_param(file, viewer_param, viewer_param->getWeight()); - } - - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) - { - std::string uuid_str = LLUUID().asString(); - if (agent_is_godlike) - { - te_image->getID().toString(uuid_str); - } - apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); - } - } - } + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + std::string uuid_str = LLUUID().asString(); + if (agent_is_godlike) + { + te_image->getID().toString(uuid_str); + } + apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); + } + } + } // Root joint const LLVector3& pos = mRoot->getPosition(); const LLVector3& scale = mRoot->getScale(); - apr_file_printf( file, "\t\t\n", + apr_file_printf( file, "\t\t\n", mRoot->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); // Bones @@ -10140,10 +10140,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara name_iter != bone_names.end(); ++name_iter) { LLJoint *pJoint = getJoint(*name_iter); - const LLVector3& pos = pJoint->getPosition(); - const LLVector3& scale = pJoint->getScale(); - apr_file_printf( file, "\t\t\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + const LLVector3& pos = pJoint->getPosition(); + const LLVector3& scale = pJoint->getScale(); + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); } // Collision volumes @@ -10151,10 +10151,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara name_iter != cv_names.end(); ++name_iter) { LLJoint *pJoint = getJoint(*name_iter); - const LLVector3& pos = pJoint->getPosition(); - const LLVector3& scale = pJoint->getScale(); - apr_file_printf( file, "\t\t\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + const LLVector3& pos = pJoint->getPosition(); + const LLVector3& scale = pJoint->getScale(); + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); } // Attachment joints @@ -10162,63 +10162,63 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara name_iter != attach_names.end(); ++name_iter) { LLJoint *pJoint = getJoint(*name_iter); - if (!pJoint) continue; - const LLVector3& pos = pJoint->getPosition(); - const LLVector3& scale = pJoint->getScale(); - apr_file_printf( file, "\t\t\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + if (!pJoint) continue; + const LLVector3& pos = pJoint->getPosition(); + const LLVector3& scale = pJoint->getScale(); + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); } - + // Joint pos overrides for (std::vector::iterator name_iter = all_names.begin(); name_iter != all_names.end(); ++name_iter) { LLJoint *pJoint = getJoint(*name_iter); - - LLVector3 pos; - LLUUID mesh_id; - if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) - { + LLVector3 pos; + LLUUID mesh_id; + + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) + { S32 num_pos_overrides; std::set distinct_pos_overrides; pJoint->getAllAttachmentPosOverrides(num_pos_overrides, distinct_pos_overrides); - apr_file_printf( file, "\t\t\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(), + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(), num_pos_overrides, (S32) distinct_pos_overrides.size()); - } - } + } + } // Joint scale overrides for (std::vector::iterator name_iter = all_names.begin(); name_iter != all_names.end(); ++name_iter) { LLJoint *pJoint = getJoint(*name_iter); - - LLVector3 scale; - LLUUID mesh_id; - if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) - { + LLVector3 scale; + LLUUID mesh_id; + + if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { S32 num_scale_overrides; std::set distinct_scale_overrides; pJoint->getAllAttachmentPosOverrides(num_scale_overrides, distinct_scale_overrides); - apr_file_printf( file, "\t\t\n", - pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(), + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(), num_scale_overrides, (S32) distinct_scale_overrides.size()); - } - } - F32 pelvis_fixup; - LLUUID mesh_id; - if (hasPelvisFixup(pelvis_fixup, mesh_id)) - { - apr_file_printf( file, "\t\t\n", - pelvis_fixup, mesh_id.asString().c_str()); - } + } + } + F32 pelvis_fixup; + LLUUID mesh_id; + if (hasPelvisFixup(pelvis_fixup, mesh_id)) + { + apr_file_printf( file, "\t\t\n", + pelvis_fixup, mesh_id.asString().c_str()); + } LLVector3 rp = getRootJoint()->getWorldPosition(); LLVector4a rpv; rpv.load3(rp.mV); - + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { LLJoint *joint = getJoint(joint_num); @@ -10234,7 +10234,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara LLVector4a rrp[2]; rrp[0].setSub(new_extents[0],rpv); rrp[1].setSub(new_extents[1],rpv); - apr_file_printf( file, "\t\t\n", + apr_file_printf( file, "\t\t\n", joint_num, joint->getName().c_str(), rig_info.getRiggedExtents()[0][0], @@ -10253,134 +10253,134 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara } } - bool ultra_verbose = false; - if (isSelf() && ultra_verbose) - { - // show the cloned params inside the wearables as well. - gAgentAvatarp->dumpWearableInfo(outfile); - } + bool ultra_verbose = false; + if (isSelf() && ultra_verbose) + { + // show the cloned params inside the wearables as well. + gAgentAvatarp->dumpWearableInfo(outfile); + } - apr_file_printf( file, "\t\n" ); - apr_file_printf( file, "\n\n" ); + apr_file_printf( file, "\t\n" ); + apr_file_printf( file, "\n\n" ); - LLSD args; - args["PATH"] = fullpath; - LLNotificationsUtil::add("AppearanceToXMLSaved", args); - } - else - { - LLNotificationsUtil::add("AppearanceToXMLFailed"); - } - // File will close when handle goes out of scope + LLSD args; + args["PATH"] = fullpath; + LLNotificationsUtil::add("AppearanceToXMLSaved", args); + } + else + { + LLNotificationsUtil::add("AppearanceToXMLFailed"); + } + // File will close when handle goes out of scope } void LLVOAvatar::setVisibilityRank(U32 rank) { - if (mDrawable.isNull() || mDrawable->isDead()) - { - // do nothing - return; - } - mVisibilityRank = rank; + if (mDrawable.isNull() || mDrawable->isDead()) + { + // do nothing + return; + } + mVisibilityRank = rank; } // Assumes LLVOAvatar::sInstances has already been sorted. S32 LLVOAvatar::getUnbakedPixelAreaRank() { - S32 rank = 1; - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - if (inst == this) - { - return rank; - } - else if (!inst->isDead() && !inst->isFullyBaked()) - { - rank++; - } - } - - llassert(0); - return 0; + S32 rank = 1; + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if (inst == this) + { + return rank; + } + else if (!inst->isDead() && !inst->isFullyBaked()) + { + rank++; + } + } + + llassert(0); + return 0; } struct CompareScreenAreaGreater { - BOOL operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs) - { - return lhs->getPixelArea() > rhs->getPixelArea(); - } + BOOL operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs) + { + return lhs->getPixelArea() > rhs->getPixelArea(); + } }; // static void LLVOAvatar::cullAvatarsByPixelArea() { - std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater()); - - // Update the avatars that have changed status - U32 rank = 2; //1 is reserved for self. - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - BOOL culled; - if (inst->isSelf() || inst->isFullyBaked()) - { - culled = FALSE; - } - else - { - culled = TRUE; - } - - if (inst->mCulled != culled) - { - inst->mCulled = culled; - LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; - inst->updateMeshTextures(); - } - - if (inst->isSelf()) - { - inst->setVisibilityRank(1); - } - else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) - { - inst->setVisibilityRank(rank++); - } - } - - // runway - this doesn't really detect gray/grey state. - S32 grey_avatars = 0; - if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) - { - if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame - { - sUnbakedUpdateTime = gFrameTimeSeconds; - sUnbakedTime += gFrameIntervalSeconds.value(); - } - if (grey_avatars > 0) - { - if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame - { - sGreyUpdateTime = gFrameTimeSeconds; - sGreyTime += gFrameIntervalSeconds.value(); - } - } - } + std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater()); + + // Update the avatars that have changed status + U32 rank = 2; //1 is reserved for self. + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + BOOL culled; + if (inst->isSelf() || inst->isFullyBaked()) + { + culled = FALSE; + } + else + { + culled = TRUE; + } + + if (inst->mCulled != culled) + { + inst->mCulled = culled; + LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; + inst->updateMeshTextures(); + } + + if (inst->isSelf()) + { + inst->setVisibilityRank(1); + } + else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) + { + inst->setVisibilityRank(rank++); + } + } + + // runway - this doesn't really detect gray/grey state. + S32 grey_avatars = 0; + if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) + { + if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame + { + sUnbakedUpdateTime = gFrameTimeSeconds; + sUnbakedTime += gFrameIntervalSeconds.value(); + } + if (grey_avatars > 0) + { + if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame + { + sGreyUpdateTime = gFrameTimeSeconds; + sGreyTime += gFrameIntervalSeconds.value(); + } + } + } } void LLVOAvatar::startAppearanceAnimation() { - if(!mAppearanceAnimating) - { - mAppearanceAnimating = TRUE; - mAppearanceMorphTimer.reset(); - mLastAppearanceBlendTime = 0.f; - } + if(!mAppearanceAnimating) + { + mAppearanceAnimating = TRUE; + mAppearanceMorphTimer.reset(); + mLastAppearanceBlendTime = 0.f; + } } // virtual @@ -10391,35 +10391,35 @@ void LLVOAvatar::removeMissingBakedTextures() //virtual void LLVOAvatar::updateRegion(LLViewerRegion *regionp) { - LLViewerObject::updateRegion(regionp); + LLViewerObject::updateRegion(regionp); } // virtual std::string LLVOAvatar::getFullname() const { - std::string name; + std::string name; - LLNameValue* first = getNVPair("FirstName"); - LLNameValue* last = getNVPair("LastName"); - if (first && last) - { - name = LLCacheName::buildFullName( first->getString(), last->getString() ); - } + LLNameValue* first = getNVPair("FirstName"); + LLNameValue* last = getNVPair("LastName"); + if (first && last) + { + name = LLCacheName::buildFullName( first->getString(), last->getString() ); + } - return name; + return name; } LLHost LLVOAvatar::getObjectHost() const { - LLViewerRegion* region = getRegion(); - if (region && !isDead()) - { - return region->getHost(); - } - else - { - return LLHost(); - } + LLViewerRegion* region = getRegion(); + if (region && !isDead()) + { + return region->getHost(); + } + else + { + return LLHost(); + } } BOOL LLVOAvatar::updateLOD() @@ -10428,36 +10428,36 @@ BOOL LLVOAvatar::updateLOD() { return FALSE; } - - if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry()) - { - return TRUE; - } - BOOL res = updateJointLODs(); + if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry()) + { + return TRUE; + } + + BOOL res = updateJointLODs(); - LLFace* facep = mDrawable->getFace(0); - if (!facep || !facep->getVertexBuffer()) - { - dirtyMesh(2); - } + LLFace* facep = mDrawable->getFace(0); + if (!facep || !facep->getVertexBuffer()) + { + dirtyMesh(2); + } - if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) - { //LOD changed or new mesh created, allocate new vertex buffer if needed - updateMeshData(); - mDirtyMesh = 0; - mNeedsSkin = TRUE; - mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); - } - updateVisibility(); + if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + { //LOD changed or new mesh created, allocate new vertex buffer if needed + updateMeshData(); + mDirtyMesh = 0; + mNeedsSkin = TRUE; + mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); + } + updateVisibility(); - return res; + return res; } void LLVOAvatar::updateLODRiggedAttachments() { - updateLOD(); - rebuildRiggedAttachments(); + updateLOD(); + rebuildRiggedAttachments(); } void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& count_rigged, S32& count_box) @@ -10471,7 +10471,7 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& { count_rigged++; LLJoint *joint = avatar->getJoint(i); - LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box " + LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box " << tab[i].getRiggedExtents()[0] << ", " << tab[i].getRiggedExtents()[1] << LL_ENDL; if ((!tab[i].getRiggedExtents()[0].equals3(zero_vec)) || (!tab[i].getRiggedExtents()[1].equals3(zero_vec))) @@ -10485,15 +10485,15 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& void LLVOAvatar::getAssociatedVolumes(std::vector& volumes) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) - { - LLViewerJointAttachment* attachment = iter->second; - LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end(); - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin(); - attach_iter != attach_end; ++attach_iter) - { - LLViewerObject* attached_object = attach_iter->get(); + for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) + { + LLViewerJointAttachment* attachment = iter->second; + LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end(); + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin(); + attach_iter != attach_end; ++attach_iter) + { + LLViewerObject* attached_object = attach_iter->get(); LLVOVolume *volume = dynamic_cast(attached_object); if (volume) { @@ -10551,31 +10551,31 @@ void LLVOAvatar::updateRiggingInfo() std::vector volumes; - getAssociatedVolumes(volumes); - - std::map curr_rigging_info_key; - { - // Get current rigging info key - for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) - { - LLVOVolume *vol = *it; - if (vol->isMesh() && vol->getVolume()) - { - const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); - S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); - curr_rigging_info_key[mesh_id] = max_lod; - } - } - - // Check for key change, which indicates some change in volume composition or LOD. - if (curr_rigging_info_key == mLastRiggingInfoKey) - { - return; - } - } - - // Something changed. Update. - mLastRiggingInfoKey = curr_rigging_info_key; + getAssociatedVolumes(volumes); + + std::map curr_rigging_info_key; + { + // Get current rigging info key + for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) + { + LLVOVolume *vol = *it; + if (vol->isMesh() && vol->getVolume()) + { + const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); + S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); + curr_rigging_info_key[mesh_id] = max_lod; + } + } + + // Check for key change, which indicates some change in volume composition or LOD. + if (curr_rigging_info_key == mLastRiggingInfoKey) + { + return; + } + } + + // Something changed. Update. + mLastRiggingInfoKey = curr_rigging_info_key; mJointRiggingInfoTab.clear(); for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { @@ -10598,112 +10598,112 @@ void LLVOAvatar::onActiveOverrideMeshesChanged() } U32 LLVOAvatar::getPartitionType() const -{ - // Avatars merely exist as drawables in the bridge partition - return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR; +{ + // Avatars merely exist as drawables in the bridge partition + return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR; } //static void LLVOAvatar::updateImpostors() { - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; std::vector instances_copy = LLCharacter::sInstances; - for (std::vector::iterator iter = instances_copy.begin(); - iter != instances_copy.end(); ++iter) - { - LLVOAvatar* avatar = (LLVOAvatar*) *iter; - if (!avatar->isDead() - && avatar->isVisible() - && avatar->isImpostor() - && avatar->needsImpostorUpdate()) - { + for (std::vector::iterator iter = instances_copy.begin(); + iter != instances_copy.end(); ++iter) + { + LLVOAvatar* avatar = (LLVOAvatar*) *iter; + if (!avatar->isDead() + && avatar->isVisible() + && avatar->isImpostor() + && avatar->needsImpostorUpdate()) + { avatar->calcMutedAVColor(); - gPipeline.generateImpostor(avatar); - } - } + gPipeline.generateImpostor(avatar); + } + } - LLCharacter::sAllowInstancesChange = TRUE; + LLCharacter::sAllowInstancesChange = TRUE; } // virtual BOOL LLVOAvatar::isImpostor() { - return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1)); + return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1)); } BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor) { - if (isSelf()) - { - return false; - } - if (isVisuallyMuted()) - { - return true; - } - return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor); + if (isSelf()) + { + return false; + } + if (isVisuallyMuted()) + { + return true; + } + return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor); } BOOL LLVOAvatar::needsImpostorUpdate() const { - return mNeedsImpostorUpdate; + return mNeedsImpostorUpdate; } const LLVector3& LLVOAvatar::getImpostorOffset() const { - return mImpostorOffset; + return mImpostorOffset; } const LLVector2& LLVOAvatar::getImpostorDim() const { - return mImpostorDim; + return mImpostorDim; } void LLVOAvatar::setImpostorDim(const LLVector2& dim) { - mImpostorDim = dim; + mImpostorDim = dim; } void LLVOAvatar::cacheImpostorValues() { - getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance); + getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance); } void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const { - const LLVector4a* ext = mDrawable->getSpatialExtents(); - extents[0] = ext[0]; - extents[1] = ext[1]; + const LLVector4a* ext = mDrawable->getSpatialExtents(); + extents[0] = ext[0]; + extents[1] = ext[1]; - LLVector3 at = LLViewerCamera::getInstance()->getOrigin()-(getRenderPosition()+mImpostorOffset); - distance = at.normalize(); - F32 da = 1.f - (at*LLViewerCamera::getInstance()->getAtAxis()); - angle.mV[0] = LLViewerCamera::getInstance()->getYaw()*da; - angle.mV[1] = LLViewerCamera::getInstance()->getPitch()*da; - angle.mV[2] = da; + LLVector3 at = LLViewerCamera::getInstance()->getOrigin()-(getRenderPosition()+mImpostorOffset); + distance = at.normalize(); + F32 da = 1.f - (at*LLViewerCamera::getInstance()->getAtAxis()); + angle.mV[0] = LLViewerCamera::getInstance()->getYaw()*da; + angle.mV[1] = LLViewerCamera::getInstance()->getPitch()*da; + angle.mV[2] = da; } // static const U32 LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors - * slider in panel_preferences_graphics1.xml */ + * slider in panel_preferences_graphics1.xml */ // static void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue) { - U32 oldmax = sMaxNonImpostors; - bool oldflg = sLimitNonImpostors; - - if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue) - { - sMaxNonImpostors = 0; - } - else - { - sMaxNonImpostors = newMaxNonImpostorsValue; - } - // the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0) - sLimitNonImpostors = (0 != sMaxNonImpostors); + U32 oldmax = sMaxNonImpostors; + bool oldflg = sLimitNonImpostors; + + if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue) + { + sMaxNonImpostors = 0; + } + else + { + sMaxNonImpostors = newMaxNonImpostorsValue; + } + // the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0) + sLimitNonImpostors = (0 != sMaxNonImpostors); if ( oldflg != sLimitNonImpostors ) { LL_DEBUGS("AvatarRender") @@ -10729,9 +10729,9 @@ void LLVOAvatar::idleUpdateRenderComplexity() } // Render Complexity - calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed + calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed - bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); + bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); if (autotune && !isDead()) { static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); @@ -10764,7 +10764,7 @@ void LLVOAvatar::updateNearbyAvatarCount() { static LLFrameTimer agent_update_timer; - if (agent_update_timer.getElapsedTimeF32() > 1.0f) + if (agent_update_timer.getElapsedTimeF32() > 1.0f) { S32 avs_nearby = 0; static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); @@ -10792,90 +10792,90 @@ void LLVOAvatar::updateNearbyAvatarCount() void LLVOAvatar::idleUpdateDebugInfo() { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO)) - { - std::string info_line; - F32 red_level; - F32 green_level; - LLColor4 info_color; - LLFontGL::StyleFlags info_style; - - if ( !mText ) - { - initHudText(); - mText->setFadeDistance(20.0, 5.0); // limit clutter in large crowds - } - else - { - mText->clearString(); // clear debug text - } - - /* - * NOTE: the logic for whether or not each of the values below - * controls muting MUST match that in the isVisuallyMuted and isTooComplex methods. - */ - - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); - info_line = llformat("%d Complexity", mVisualComplexity); - - if (max_render_cost != 0) // zero means don't care, so don't bother coloring based on this - { - green_level = 1.f-llclamp(((F32) mVisualComplexity-(F32)max_render_cost)/(F32)max_render_cost, 0.f, 1.f); - red_level = llmin((F32) mVisualComplexity/(F32)max_render_cost, 1.f); - info_color.set(red_level, green_level, 0.0, 1.0); - info_style = ( mVisualComplexity > max_render_cost - ? LLFontGL::BOLD : LLFontGL::NORMAL ); - } - else - { - info_color.set(LLColor4::grey); - info_style = LLFontGL::NORMAL; - } - mText->addLine(info_line, info_color, info_style); - - // Visual rank - info_line = llformat("%d rank", mVisibilityRank); - // Use grey for imposters, white for normal rendering or no impostors - info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white)); - info_style = LLFontGL::NORMAL; - mText->addLine(info_line, info_color, info_style); + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO)) + { + std::string info_line; + F32 red_level; + F32 green_level; + LLColor4 info_color; + LLFontGL::StyleFlags info_style; + + if ( !mText ) + { + initHudText(); + mText->setFadeDistance(20.0, 5.0); // limit clutter in large crowds + } + else + { + mText->clearString(); // clear debug text + } + + /* + * NOTE: the logic for whether or not each of the values below + * controls muting MUST match that in the isVisuallyMuted and isTooComplex methods. + */ + + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + info_line = llformat("%d Complexity", mVisualComplexity); + + if (max_render_cost != 0) // zero means don't care, so don't bother coloring based on this + { + green_level = 1.f-llclamp(((F32) mVisualComplexity-(F32)max_render_cost)/(F32)max_render_cost, 0.f, 1.f); + red_level = llmin((F32) mVisualComplexity/(F32)max_render_cost, 1.f); + info_color.set(red_level, green_level, 0.0, 1.0); + info_style = ( mVisualComplexity > max_render_cost + ? LLFontGL::BOLD : LLFontGL::NORMAL ); + } + else + { + info_color.set(LLColor4::grey); + info_style = LLFontGL::NORMAL; + } + mText->addLine(info_line, info_color, info_style); + + // Visual rank + info_line = llformat("%d rank", mVisibilityRank); + // Use grey for imposters, white for normal rendering or no impostors + info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white)); + info_style = LLFontGL::NORMAL; + mText->addLine(info_line, info_color, info_style); // Triangle count - mText->addLine(std::string("VisTris ") + LLStringOps::getReadableNumber(mAttachmentVisibleTriangleCount), + mText->addLine(std::string("VisTris ") + LLStringOps::getReadableNumber(mAttachmentVisibleTriangleCount), info_color, info_style); - mText->addLine(std::string("EstMaxTris ") + LLStringOps::getReadableNumber(mAttachmentEstTriangleCount), + mText->addLine(std::string("EstMaxTris ") + LLStringOps::getReadableNumber(mAttachmentEstTriangleCount), info_color, info_style); - // Attachment Surface Area - static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f); - info_line = llformat("%.0f m^2", mAttachmentSurfaceArea); + // Attachment Surface Area + static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f); + info_line = llformat("%.0f m^2", mAttachmentSurfaceArea); - if (max_render_cost != 0 && max_attachment_area != 0) // zero means don't care, so don't bother coloring based on this - { - green_level = 1.f-llclamp((mAttachmentSurfaceArea-max_attachment_area)/max_attachment_area, 0.f, 1.f); - red_level = llmin(mAttachmentSurfaceArea/max_attachment_area, 1.f); - info_color.set(red_level, green_level, 0.0, 1.0); - info_style = ( mAttachmentSurfaceArea > max_attachment_area - ? LLFontGL::BOLD : LLFontGL::NORMAL ); + if (max_render_cost != 0 && max_attachment_area != 0) // zero means don't care, so don't bother coloring based on this + { + green_level = 1.f-llclamp((mAttachmentSurfaceArea-max_attachment_area)/max_attachment_area, 0.f, 1.f); + red_level = llmin(mAttachmentSurfaceArea/max_attachment_area, 1.f); + info_color.set(red_level, green_level, 0.0, 1.0); + info_style = ( mAttachmentSurfaceArea > max_attachment_area + ? LLFontGL::BOLD : LLFontGL::NORMAL ); - } - else - { - info_color.set(LLColor4::grey); - info_style = LLFontGL::NORMAL; - } + } + else + { + info_color.set(LLColor4::grey); + info_style = LLFontGL::NORMAL; + } - mText->addLine(info_line, info_color, info_style); + mText->addLine(info_line, info_color, info_style); - updateText(); // corrects position - } + updateText(); // corrects position + } } void LLVOAvatar::updateVisualComplexity() { - LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL; - // Set the cache time to in the past so it's updated ASAP - mVisualComplexityStale = true; + LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL; + // Set the cache time to in the past so it's updated ASAP + mVisualComplexityStale = true; } @@ -11042,7 +11042,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() * the official viewer for consideration. *****************************************************************/ if (mVisualComplexityStale) - { + { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; static const U32 COMPLEXITY_BODY_PART_COST = 200; @@ -11053,18 +11053,18 @@ void LLVOAvatar::calculateUpdateRenderComplexity() // Diagnostic list of all textures on our avatar static std::unordered_set all_textures; - U32 cost = VISUAL_COMPLEXITY_UNKNOWN; - LLVOVolume::texture_cost_t textures; - hud_complexity_list_t hud_complexity_list; + U32 cost = VISUAL_COMPLEXITY_UNKNOWN; + LLVOVolume::texture_cost_t textures; + hud_complexity_list_t hud_complexity_list; object_complexity_list_t object_complexity_list; - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict - = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index); - ETextureIndex tex_index = baked_dict->mTextureIndex; - if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) - { + for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict + = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index); + ETextureIndex tex_index = baked_dict->mTextureIndex; + if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) + { // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars if (isIndexLocalTexture(tex_index)) { @@ -11082,14 +11082,14 @@ void LLVOAvatar::calculateUpdateRenderComplexity() cost += COMPLEXITY_BODY_PART_COST; } } - } - } + } + } LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL; mAttachmentVisibleTriangleCount = 0; mAttachmentEstTriangleCount = 0.f; mAttachmentSurfaceArea = 0.f; - + // A standalone animated object needs to be accounted for // using its associated volume. Attached animated objects // will be covered by the subsequent loop over attachments. @@ -11105,20 +11105,20 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } // Account for complexity of all attachments. - for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin(); - attachment_point != mAttachmentPoints.end(); - ++attachment_point) - { - LLViewerJointAttachment* attachment = attachment_point->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { + for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin(); + attachment_point != mAttachmentPoints.end(); + ++attachment_point) + { + LLViewerJointAttachment* attachment = attachment_point->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { LLViewerObject* attached_object = attachment_iter->get(); accountRenderComplexityForObject(attached_object, max_attachment_complexity, textures, cost, hud_complexity_list, object_complexity_list); - } - } + } + } if ( cost != mVisualComplexity ) { @@ -11134,8 +11134,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity() << " reported " << mReportedVisualComplexity << LL_ENDL; } - mVisualComplexity = cost; - mVisualComplexityStale = false; + mVisualComplexity = cost; + mVisualComplexityStale = false; static LLCachedControl show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); @@ -11149,7 +11149,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } //schedule an update to ART next frame if needed - if (LLPerfStats::tunables.userAutoTuneEnabled && + if (LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY && !isVisuallyMuted()) { @@ -11169,7 +11169,7 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) { mVisuallyMuteSetting = set; mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 7; + mLastImpostorUpdateReason = 7; LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set)); } @@ -11177,51 +11177,51 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) void LLVOAvatar::setOverallAppearanceNormal() { - if (isControlAvatar()) - return; + if (isControlAvatar()) + return; LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); - resetSkeleton(false); + resetSkeleton(false); getJoint("mPelvis")->setPosition(pelvis_pos); - for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) - { - bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); - LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; - if (!is_playing) - { - // Anim was not requested for this av by sim, but may be playing locally - stopMotion(*it); - } - } - mJellyAnims.clear(); + for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) + { + bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); + LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; + if (!is_playing) + { + // Anim was not requested for this av by sim, but may be playing locally + stopMotion(*it); + } + } + mJellyAnims.clear(); - processAnimationStateChanges(); + processAnimationStateChanges(); } void LLVOAvatar::setOverallAppearanceJellyDoll() { - if (isControlAvatar()) - return; - - // stop current animations - { - for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin(); - anim_it != mPlayingAnimations.end(); - ++anim_it) - { - { - stopMotion(anim_it->first, TRUE); - } - } - } - processAnimationStateChanges(); - - // Start any needed anims for jellydoll - updateOverallAppearanceAnimations(); - + if (isControlAvatar()) + return; + + // stop current animations + { + for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin(); + anim_it != mPlayingAnimations.end(); + ++anim_it) + { + { + stopMotion(anim_it->first, TRUE); + } + } + } + processAnimationStateChanges(); + + // Start any needed anims for jellydoll + updateOverallAppearanceAnimations(); + LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); - resetSkeleton(false); + resetSkeleton(false); getJoint("mPelvis")->setPosition(pelvis_pos); } @@ -11232,114 +11232,114 @@ void LLVOAvatar::setOverallAppearanceInvisible() void LLVOAvatar::updateOverallAppearance() { - AvatarOverallAppearance new_overall = getOverallAppearance(); - if (new_overall != mOverallAppearance) - { - switch (new_overall) - { - case AOA_NORMAL: - setOverallAppearanceNormal(); - break; - case AOA_JELLYDOLL: - setOverallAppearanceJellyDoll(); - break; - case AOA_INVISIBLE: - setOverallAppearanceInvisible(); - break; - } - mOverallAppearance = new_overall; - if (!isSelf()) - { - mNeedsImpostorUpdate = TRUE; - mLastImpostorUpdateReason = 8; - } - updateMeshVisibility(); - } - - // This needs to be done even if overall appearance has not - // changed, since sit/stand status can be different. - updateOverallAppearanceAnimations(); + AvatarOverallAppearance new_overall = getOverallAppearance(); + if (new_overall != mOverallAppearance) + { + switch (new_overall) + { + case AOA_NORMAL: + setOverallAppearanceNormal(); + break; + case AOA_JELLYDOLL: + setOverallAppearanceJellyDoll(); + break; + case AOA_INVISIBLE: + setOverallAppearanceInvisible(); + break; + } + mOverallAppearance = new_overall; + if (!isSelf()) + { + mNeedsImpostorUpdate = TRUE; + mLastImpostorUpdateReason = 8; + } + updateMeshVisibility(); + } + + // This needs to be done even if overall appearance has not + // changed, since sit/stand status can be different. + updateOverallAppearanceAnimations(); } void LLVOAvatar::updateOverallAppearanceAnimations() { - if (isControlAvatar()) - return; - - if (getOverallAppearance() == AOA_JELLYDOLL) - { - LLUUID motion_id; - if (isSitting() && getParent()) // sitting on object - { - motion_id = ANIM_AGENT_SIT_FEMALE; - } - else if (isSitting()) // sitting on ground - { - motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; - } - else // standing - { - motion_id = ANIM_AGENT_STAND; - } - if (mJellyAnims.find(motion_id) == mJellyAnims.end()) - { - for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) - { - bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); - LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; - if (!is_playing) - { - // Anim was not requested for this av by sim, but may be playing locally - stopMotion(*it, TRUE); - } - } - mJellyAnims.clear(); - - startMotion(motion_id); - mJellyAnims.insert(motion_id); - - processAnimationStateChanges(); - } - } + if (isControlAvatar()) + return; + + if (getOverallAppearance() == AOA_JELLYDOLL) + { + LLUUID motion_id; + if (isSitting() && getParent()) // sitting on object + { + motion_id = ANIM_AGENT_SIT_FEMALE; + } + else if (isSitting()) // sitting on ground + { + motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; + } + else // standing + { + motion_id = ANIM_AGENT_STAND; + } + if (mJellyAnims.find(motion_id) == mJellyAnims.end()) + { + for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it) + { + bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); + LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; + if (!is_playing) + { + // Anim was not requested for this av by sim, but may be playing locally + stopMotion(*it, TRUE); + } + } + mJellyAnims.clear(); + + startMotion(motion_id); + mJellyAnims.insert(motion_id); + + processAnimationStateChanges(); + } + } } // Based on isVisuallyMuted(), but has 3 possible results. LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - AvatarOverallAppearance result = AOA_NORMAL; - - // Priority order (highest priority first) - // * own avatar is always drawn normally - // * if on the "always draw normally" list, draw them normally - // * if on the "always visually mute" list, show as jellydoll - // * if explicitly muted (blocked), show as invisible - // * check against the render cost and attachment limits - if too complex, show as jellydoll - if (isSelf()) - { - result = AOA_NORMAL; - } - else // !isSelf() - { - if (isInMuteList()) - { - result = AOA_INVISIBLE; - } - else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) - { - result = AOA_NORMAL; - } - else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) - { // Always want to see this AV as an impostor - result = AOA_JELLYDOLL; - } - else if (isTooComplex() || isTooSlow()) - { - result = AOA_JELLYDOLL; - } - } - - return result; + AvatarOverallAppearance result = AOA_NORMAL; + + // Priority order (highest priority first) + // * own avatar is always drawn normally + // * if on the "always draw normally" list, draw them normally + // * if on the "always visually mute" list, show as jellydoll + // * if explicitly muted (blocked), show as invisible + // * check against the render cost and attachment limits - if too complex, show as jellydoll + if (isSelf()) + { + result = AOA_NORMAL; + } + else // !isSelf() + { + if (isInMuteList()) + { + result = AOA_INVISIBLE; + } + else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) + { + result = AOA_NORMAL; + } + else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) + { // Always want to see this AV as an impostor + result = AOA_JELLYDOLL; + } + else if (isTooComplex() || isTooSlow()) + { + result = AOA_JELLYDOLL; + } + } + + return result; } void LLVOAvatar::calcMutedAVColor() @@ -11367,7 +11367,7 @@ void LLVOAvatar::calcMutedAVColor() } #ifdef COLORIZE_JELLYDOLLS else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 ) - { + { // select a color based on the first byte of the agents uuid so any muted agent is always the same color F32 color_value = (F32) (av_id.mData[0]); F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f @@ -11383,17 +11383,17 @@ void LLVOAvatar::calcMutedAVColor() F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1) new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); - new_color.normalize(); + new_color.normalize(); new_color *= 0.28f; // Tone it down - } + } #endif else { - new_color = LLColor4::grey4; + new_color = LLColor4::grey4; change_msg = " over limit color "; } - if (mMutedAVColor != new_color) + if (mMutedAVColor != new_color) { LL_DEBUGS("AvatarRender") << "avatar "<< av_id << change_msg << std::setprecision(3) << new_color << LL_ENDL; mMutedAVColor = new_color; @@ -11403,40 +11403,40 @@ void LLVOAvatar::calcMutedAVColor() // static BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index) { - return (index < 0 || index >= TEX_NUM_INDICES) - ? false - : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture; + return (index < 0 || index >= TEX_NUM_INDICES) + ? false + : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture; } // static BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index) { - return (index < 0 || index >= TEX_NUM_INDICES) - ? false - : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture; + return (index < 0 || index >= TEX_NUM_INDICES) + ? false + : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture; } const std::string LLVOAvatar::getBakedStatusForPrintout() const { - std::string line; + std::string line; - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); - iter != LLAvatarAppearance::getDictionary()->getTextures().end(); - ++iter) - { - const ETextureIndex index = iter->first; - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - if (texture_dict->mIsBakedTexture) - { - line += texture_dict->mName; - if (isTextureDefined(index)) - { - line += "_baked"; - } - line += " "; - } - } - return line; + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); + iter != LLAvatarAppearance::getDictionary()->getTextures().end(); + ++iter) + { + const ETextureIndex index = iter->first; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + if (texture_dict->mIsBakedTexture) + { + line += texture_dict->mName; + if (isTextureDefined(index)) + { + line += "_baked"; + } + line += " "; + } + } + return line; } @@ -11444,7 +11444,7 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const //virtual S32 LLVOAvatar::getTexImageSize() const { - return TEX_IMAGE_SIZE_OTHER; + return TEX_IMAGE_SIZE_OTHER; } //----------------------------------------------------------------------------- @@ -11453,48 +11453,48 @@ S32 LLVOAvatar::getTexImageSize() const F32 calc_bouncy_animation(F32 x) { - return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; + return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; } //virtual BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const { - if (isIndexLocalTexture(te)) - { - return FALSE; - } - - if( !getImage( te, index ) ) - { - LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL; - return FALSE; - } + if (isIndexLocalTexture(te)) + { + return FALSE; + } + + if( !getImage( te, index ) ) + { + LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL; + return FALSE; + } - return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && - getImage(te, index)->getID() != IMG_DEFAULT); + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && + getImage(te, index)->getID() != IMG_DEFAULT); } //virtual BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { - if (isIndexLocalTexture(type)) - { - return isTextureDefined(type, index); - } - else - { - // baked textures can use TE images directly - return ((isTextureDefined(type) || isSelf()) - && (getTEImage(type)->getID() != IMG_INVISIBLE - || LLDrawPoolAlpha::sShowDebugAlpha)); - } + if (isIndexLocalTexture(type)) + { + return isTextureDefined(type, index); + } + else + { + // baked textures can use TE images directly + return ((isTextureDefined(type) || isSelf()) + && (getTEImage(type)->getID() != IMG_INVISIBLE + || LLDrawPoolAlpha::sShowDebugAlpha)); + } } //virtual BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const { - // non-self avatars don't have wearables - return FALSE; + // non-self avatars don't have wearables + return FALSE; } void LLVOAvatar::placeProfileQuery() diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 01e030a300..0a13b7d309 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvoavatar.cpp * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,7 +47,7 @@ #include "lllocaltextureobject.h" #include "llnotificationsutil.h" #include "llselectmgr.h" -#include "lltoolgrab.h" // for needsRenderBeam +#include "lltoolgrab.h" // for needsRenderBeam #include "lltoolmgr.h" // for needsRenderBeam #include "lltoolmorph.h" #include "lltrans.h" @@ -80,31 +80,31 @@ LLPointer gAgentAvatarp = NULL; BOOL isAgentAvatarValid() { - return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid()); + return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid()); } void selfStartPhase(const std::string& phase_name) { - if (isAgentAvatarValid()) - { - gAgentAvatarp->startPhase(phase_name); - } + if (isAgentAvatarValid()) + { + gAgentAvatarp->startPhase(phase_name); + } } void selfStopPhase(const std::string& phase_name, bool err_check) { - if (isAgentAvatarValid()) - { - gAgentAvatarp->stopPhase(phase_name, err_check); - } + if (isAgentAvatarValid()) + { + gAgentAvatarp->stopPhase(phase_name, err_check); + } } void selfClearPhases() { - if (isAgentAvatarValid()) - { - gAgentAvatarp->clearPhases(); - } + if (isAgentAvatarValid()) + { + gAgentAvatarp->clearPhases(); + } } using namespace LLAvatarAppearanceDefines; @@ -120,18 +120,18 @@ LLSD summarize_by_buckets(std::vector in_records, std::vector struct LocalTextureData { - LocalTextureData() : - mIsBakedReady(false), - mDiscard(MAX_DISCARD_LEVEL+1), - mImage(NULL), - mWearableID(IMG_DEFAULT_AVATAR), - mTexEntry(NULL) - {} - LLPointer mImage; - bool mIsBakedReady; - S32 mDiscard; - LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself - LLTextureEntry *mTexEntry; + LocalTextureData() : + mIsBakedReady(false), + mDiscard(MAX_DISCARD_LEVEL+1), + mImage(NULL), + mWearableID(IMG_DEFAULT_AVATAR), + mTexEntry(NULL) + {} + LLPointer mImage; + bool mIsBakedReady; + S32 mDiscard; + LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself + LLTextureEntry *mTexEntry; }; //----------------------------------------------------------------------------- @@ -160,512 +160,512 @@ std::map< LLGLenum, LLGLuint*> LLVOAvatarSelf::sScratchTexNames; **/ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, - const LLPCode pcode, - LLViewerRegion* regionp) : - LLVOAvatar(id, pcode, regionp), - mScreenp(NULL), - mLastRegionHandle(0), - mRegionCrossingCount(0), - // Value outside legal range, so will always be a mismatch the - // first time through. - mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)), + const LLPCode pcode, + LLViewerRegion* regionp) : + LLVOAvatar(id, pcode, regionp), + mScreenp(NULL), + mLastRegionHandle(0), + mRegionCrossingCount(0), + // Value outside legal range, so will always be a mismatch the + // first time through. + mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)), mInitialMetric(true), mMetricSequence(0) { - mMotionController.mIsSelf = TRUE; + mMotionController.mIsSelf = TRUE; - LL_DEBUGS() << "Marking avatar as self " << id << LL_ENDL; + LL_DEBUGS() << "Marking avatar as self " << id << LL_ENDL; } // Called periodically for diagnostics, return true when done. bool output_self_av_texture_diagnostics() { - if (!isAgentAvatarValid()) - return true; // done checking + if (!isAgentAvatarValid()) + return true; // done checking - gAgentAvatarp->outputRezDiagnostics(); + gAgentAvatarp->outputRezDiagnostics(); - return false; + return false; } bool update_avatar_rez_metrics() { - if (!isAgentAvatarValid()) - return true; - - gAgentAvatarp->updateAvatarRezMetrics(false); + if (!isAgentAvatarValid()) + return true; - return false; + gAgentAvatarp->updateAvatarRezMetrics(false); + + return false; } void LLVOAvatarSelf::initInstance() { - BOOL status = TRUE; - // creates hud joint(mScreen) among other things - status &= loadAvatarSelf(); - - // adds attachment points to mScreen among other things - LLVOAvatar::initInstance(); - - LL_INFOS() << "Self avatar object created. Starting timer." << LL_ENDL; - mDebugSelfLoadTimer.reset(); - // clear all times to -1 for debugging - for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) - { - for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j) - { - mDebugTextureLoadTimes[i][j] = -1.0f; - } - } - - for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) - { - mDebugBakedTextureTimes[i][0] = -1.0f; - mDebugBakedTextureTimes[i][1] = -1.0f; - } - - status &= buildMenus(); - if (!status) - { - LL_ERRS() << "Unable to load user's avatar" << LL_ENDL; - return; - } - - setHoverIfRegionEnabled(); - - //doPeriodically(output_self_av_texture_diagnostics, 30.0); - doPeriodically(update_avatar_rez_metrics, 5.0); - doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0); + BOOL status = TRUE; + // creates hud joint(mScreen) among other things + status &= loadAvatarSelf(); + + // adds attachment points to mScreen among other things + LLVOAvatar::initInstance(); + + LL_INFOS() << "Self avatar object created. Starting timer." << LL_ENDL; + mDebugSelfLoadTimer.reset(); + // clear all times to -1 for debugging + for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) + { + for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j) + { + mDebugTextureLoadTimes[i][j] = -1.0f; + } + } + + for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) + { + mDebugBakedTextureTimes[i][0] = -1.0f; + mDebugBakedTextureTimes[i][1] = -1.0f; + } + + status &= buildMenus(); + if (!status) + { + LL_ERRS() << "Unable to load user's avatar" << LL_ENDL; + return; + } + + setHoverIfRegionEnabled(); + + //doPeriodically(output_self_av_texture_diagnostics, 30.0); + doPeriodically(update_avatar_rez_metrics, 5.0); + doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0); mInitFlags |= 1<<2; } void LLVOAvatarSelf::setHoverIfRegionEnabled() { - if (getRegion() && getRegion()->simulatorFeaturesReceived()) - { - if (getRegion()->avatarHoverHeightEnabled()) - { - F32 hover_z = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ"); - setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z))); - LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL; - } - else - { - setHoverOffset(LLVector3(0.0, 0.0, 0.0)); - LL_INFOS("Avatar") << avString() << " zeroing hover height, region does not support" << LL_ENDL; - } - } - else - { - LL_INFOS("Avatar") << avString() << " region or simulator features not known, no change on hover" << LL_ENDL; - if (getRegion()) - { - getRegion()->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1)); - } - - } + if (getRegion() && getRegion()->simulatorFeaturesReceived()) + { + if (getRegion()->avatarHoverHeightEnabled()) + { + F32 hover_z = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ"); + setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z))); + LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL; + } + else + { + setHoverOffset(LLVector3(0.0, 0.0, 0.0)); + LL_INFOS("Avatar") << avString() << " zeroing hover height, region does not support" << LL_ENDL; + } + } + else + { + LL_INFOS("Avatar") << avString() << " region or simulator features not known, no change on hover" << LL_ENDL; + if (getRegion()) + { + getRegion()->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1)); + } + + } } bool LLVOAvatarSelf::checkStuckAppearance() { - const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0; - const F32 UNCONDITIONAL_UNSTICK_INTERVAL = 600.0; - - if (gAgentWearables.isCOFChangeInProgress()) - { - LL_DEBUGS("Avatar") << "checking for stuck appearance" << LL_ENDL; - F32 change_time = gAgentWearables.getCOFChangeTime(); - LL_DEBUGS("Avatar") << "change in progress for " << change_time << " seconds" << LL_ENDL; - S32 active_hp = LLAppearanceMgr::instance().countActiveHoldingPatterns(); - LL_DEBUGS("Avatar") << "active holding patterns " << active_hp << " seconds" << LL_ENDL; - S32 active_copies = LLAppearanceMgr::instance().getActiveCopyOperations(); - LL_DEBUGS("Avatar") << "active copy operations " << active_copies << LL_ENDL; - - if ((change_time > CONDITIONAL_UNSTICK_INTERVAL && active_copies == 0) || - (change_time > UNCONDITIONAL_UNSTICK_INTERVAL)) - { - gAgentWearables.notifyLoadingFinished(); - } - } - - // Return false to continue running check periodically. - return LLApp::isExiting(); + const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0; + const F32 UNCONDITIONAL_UNSTICK_INTERVAL = 600.0; + + if (gAgentWearables.isCOFChangeInProgress()) + { + LL_DEBUGS("Avatar") << "checking for stuck appearance" << LL_ENDL; + F32 change_time = gAgentWearables.getCOFChangeTime(); + LL_DEBUGS("Avatar") << "change in progress for " << change_time << " seconds" << LL_ENDL; + S32 active_hp = LLAppearanceMgr::instance().countActiveHoldingPatterns(); + LL_DEBUGS("Avatar") << "active holding patterns " << active_hp << " seconds" << LL_ENDL; + S32 active_copies = LLAppearanceMgr::instance().getActiveCopyOperations(); + LL_DEBUGS("Avatar") << "active copy operations " << active_copies << LL_ENDL; + + if ((change_time > CONDITIONAL_UNSTICK_INTERVAL && active_copies == 0) || + (change_time > UNCONDITIONAL_UNSTICK_INTERVAL)) + { + gAgentWearables.notifyLoadingFinished(); + } + } + + // Return false to continue running check periodically. + return LLApp::isExiting(); } // virtual void LLVOAvatarSelf::markDead() { - mBeam = NULL; - LLVOAvatar::markDead(); + mBeam = NULL; + LLVOAvatar::markDead(); } /*virtual*/ BOOL LLVOAvatarSelf::loadAvatar() { - BOOL success = LLVOAvatar::loadAvatar(); + BOOL success = LLVOAvatar::loadAvatar(); - // set all parameters stored directly in the avatar to have - // the isSelfParam to be TRUE - this is used to prevent - // them from being animated or trigger accidental rebakes - // when we copy params from the wearable to the base avatar. - for (LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) getNextVisualParam()) - { - if (param->getWearableType() != LLWearableType::WT_INVALID) - { - param->setIsDummy(TRUE); - } - } + // set all parameters stored directly in the avatar to have + // the isSelfParam to be TRUE - this is used to prevent + // them from being animated or trigger accidental rebakes + // when we copy params from the wearable to the base avatar. + for (LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) getNextVisualParam()) + { + if (param->getWearableType() != LLWearableType::WT_INVALID) + { + param->setIsDummy(TRUE); + } + } - return success; + return success; } BOOL LLVOAvatarSelf::loadAvatarSelf() { - BOOL success = TRUE; - // avatar_skeleton.xml - if (!buildSkeletonSelf(sAvatarSkeletonInfo)) - { - LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL; - return FALSE; - } + BOOL success = TRUE; + // avatar_skeleton.xml + if (!buildSkeletonSelf(sAvatarSkeletonInfo)) + { + LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL; + return FALSE; + } - return success; + return success; } BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info) { - // add special-purpose "screen" joint - mScreenp = new LLViewerJoint("mScreen", NULL); - // for now, put screen at origin, as it is only used during special - // HUD rendering mode - F32 aspect = LLViewerCamera::getInstance()->getAspect(); - LLVector3 scale(1.f, aspect, 1.f); - mScreenp->setScale(scale); - // SL-315 - mScreenp->setWorldPosition(LLVector3::zero); - // need to update screen agressively when sidebar opens/closes, for example - mScreenp->mUpdateXform = TRUE; - return TRUE; + // add special-purpose "screen" joint + mScreenp = new LLViewerJoint("mScreen", NULL); + // for now, put screen at origin, as it is only used during special + // HUD rendering mode + F32 aspect = LLViewerCamera::getInstance()->getAspect(); + LLVector3 scale(1.f, aspect, 1.f); + mScreenp->setScale(scale); + // SL-315 + mScreenp->setWorldPosition(LLVector3::zero); + // need to update screen agressively when sidebar opens/closes, for example + mScreenp->mUpdateXform = TRUE; + return TRUE; } BOOL LLVOAvatarSelf::buildMenus() { - //------------------------------------------------------------------------- - // build the attach and detach menus - //------------------------------------------------------------------------- - gAttachBodyPartPieMenus[0] = NULL; - - LLContextMenu::Params params; - params.label(LLTrans::getString("BodyPartsRightArm")); - params.name(params.label); - params.visible(false); - gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsHead")); - params.name(params.label); - gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsLeftArm")); - params.name(params.label); - gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create (params); - - gAttachBodyPartPieMenus[4] = NULL; - - params.label(LLTrans::getString("BodyPartsLeftLeg")); - params.name(params.label); - gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsTorso")); - params.name(params.label); - gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsRightLeg")); - params.name(params.label); - gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); - params.name(params.label); - gAttachBodyPartPieMenus[8] = LLUICtrlFactory::create(params); - - gDetachBodyPartPieMenus[0] = NULL; - - params.label(LLTrans::getString("BodyPartsRightArm")); - params.name(params.label); - gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsHead")); - params.name(params.label); - gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsLeftArm")); - params.name(params.label); - gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create (params); - - gDetachBodyPartPieMenus[4] = NULL; - - params.label(LLTrans::getString("BodyPartsLeftLeg")); - params.name(params.label); - gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsTorso")); - params.name(params.label); - gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsRightLeg")); - params.name(params.label); - gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create (params); - - params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); - params.name(params.label); - gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create(params); - - for (S32 i = 0; i < 9; i++) - { - if (gAttachBodyPartPieMenus[i]) - { - gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] ); - } - else - { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment && attachment->getGroup() == i) - { - LLMenuItemCallGL::Params item_params; - - std::string sub_piemenu_name = attachment->getName(); - if (LLTrans::getString(sub_piemenu_name) != "") - { - item_params.label = LLTrans::getString(sub_piemenu_name); - } - else - { - item_params.label = sub_piemenu_name; - } - item_params.name =(item_params.label ); - item_params.on_click.function_name = "Object.AttachToAvatar"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Object.EnableWear"; - item_params.on_enable.parameter = iter->first; - LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); - - gAttachPieMenu->addChild(item); - - break; - - } - } - } - - if (gDetachBodyPartPieMenus[i]) - { - gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); - gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); - gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); - } - else - { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment && attachment->getGroup() == i) - { - LLMenuItemCallGL::Params item_params; - std::string sub_piemenu_name = attachment->getName(); - if (LLTrans::getString(sub_piemenu_name) != "") - { - item_params.label = LLTrans::getString(sub_piemenu_name); - } - else - { - item_params.label = sub_piemenu_name; - } - item_params.name =(item_params.label ); - item_params.on_click.function_name = "Attachment.DetachFromPoint"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Attachment.PointFilled"; - item_params.on_enable.parameter = iter->first; - LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); - - gDetachPieMenu->addChild(item); - gDetachAttSelfMenu->addChild(LLUICtrlFactory::create(item_params)); - gDetachAvatarMenu->addChild(LLUICtrlFactory::create(item_params)); - break; - } - } - } - } - - - // add screen attachments - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getGroup() == 9) - { - LLMenuItemCallGL::Params item_params; - std::string sub_piemenu_name = attachment->getName(); - if (LLTrans::getString(sub_piemenu_name) != "") - { - item_params.label = LLTrans::getString(sub_piemenu_name); - } - else - { - item_params.label = sub_piemenu_name; - } - item_params.name =(item_params.label ); - item_params.on_click.function_name = "Object.AttachToAvatar"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Object.EnableWear"; - item_params.on_enable.parameter = iter->first; - LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); - gAttachScreenPieMenu->addChild(item); - - item_params.on_click.function_name = "Attachment.DetachFromPoint"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Attachment.PointFilled"; - item_params.on_enable.parameter = iter->first; - item = LLUICtrlFactory::create(item_params); - gDetachScreenPieMenu->addChild(item); - gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create(item_params)); - gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create(item_params)); - } - } - - for (S32 pass = 0; pass < 2; pass++) - { - // *TODO: Skinning - gAttachSubMenu is an awful, awful hack - if (!gAttachSubMenu) - { - break; - } - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getIsHUDAttachment() != (pass == 1)) - { - continue; - } - LLMenuItemCallGL::Params item_params; - std::string sub_piemenu_name = attachment->getName(); - if (LLTrans::getString(sub_piemenu_name) != "") - { - item_params.label = LLTrans::getString(sub_piemenu_name); - } - else - { - item_params.label = sub_piemenu_name; - } - item_params.name =(item_params.label ); - item_params.on_click.function_name = "Object.AttachToAvatar"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Object.EnableWear"; - item_params.on_enable.parameter = iter->first; - //* TODO: Skinning: - //LLSD params; - //params["index"] = iter->first; - //params["label"] = attachment->getName(); - //item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params)); - - LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); - gAttachSubMenu->addChild(item); - - item_params.on_click.function_name = "Attachment.DetachFromPoint"; - item_params.on_click.parameter = iter->first; - item_params.on_enable.function_name = "Attachment.PointFilled"; - item_params.on_enable.parameter = iter->first; - //* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params)); - - item = LLUICtrlFactory::create(item_params); - gDetachSubMenu->addChild(item); - } - if (pass == 0) - { - // put separator between non-hud and hud attachments - gAttachSubMenu->addSeparator(); - gDetachSubMenu->addSeparator(); - } - } - - for (S32 group = 0; group < 9; group++) - { - // skip over groups that don't have sub menus - if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group]) - { - continue; - } - - std::multimap attachment_pie_menu_map; - - // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if(attachment && attachment->getGroup() == group) - { - // use multimap to provide a partial order off of the pie slice key - S32 pie_index = attachment->getPieSlice(); - attachment_pie_menu_map.insert(std::make_pair(pie_index, iter->first)); - } - } - - // add in requested order to pie menu, inserting separators as necessary - for (std::multimap::iterator attach_it = attachment_pie_menu_map.begin(); - attach_it != attachment_pie_menu_map.end(); ++attach_it) - { - S32 attach_index = attach_it->second; - - LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); - if (attachment) - { - LLMenuItemCallGL::Params item_params; - item_params.name = attachment->getName(); - item_params.label = LLTrans::getString(attachment->getName()); - item_params.on_click.function_name = "Object.AttachToAvatar"; - item_params.on_click.parameter = attach_index; - item_params.on_enable.function_name = "Object.EnableWear"; - item_params.on_enable.parameter = attach_index; - - LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); - gAttachBodyPartPieMenus[group]->addChild(item); - - item_params.on_click.function_name = "Attachment.DetachFromPoint"; - item_params.on_click.parameter = attach_index; - item_params.on_enable.function_name = "Attachment.PointFilled"; - item_params.on_enable.parameter = attach_index; - item = LLUICtrlFactory::create(item_params); - gDetachBodyPartPieMenus[group]->addChild(item); - } - } - } - return TRUE; + //------------------------------------------------------------------------- + // build the attach and detach menus + //------------------------------------------------------------------------- + gAttachBodyPartPieMenus[0] = NULL; + + LLContextMenu::Params params; + params.label(LLTrans::getString("BodyPartsRightArm")); + params.name(params.label); + params.visible(false); + gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsHead")); + params.name(params.label); + gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsLeftArm")); + params.name(params.label); + gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create (params); + + gAttachBodyPartPieMenus[4] = NULL; + + params.label(LLTrans::getString("BodyPartsLeftLeg")); + params.name(params.label); + gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsTorso")); + params.name(params.label); + gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsRightLeg")); + params.name(params.label); + gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); + params.name(params.label); + gAttachBodyPartPieMenus[8] = LLUICtrlFactory::create(params); + + gDetachBodyPartPieMenus[0] = NULL; + + params.label(LLTrans::getString("BodyPartsRightArm")); + params.name(params.label); + gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsHead")); + params.name(params.label); + gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsLeftArm")); + params.name(params.label); + gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create (params); + + gDetachBodyPartPieMenus[4] = NULL; + + params.label(LLTrans::getString("BodyPartsLeftLeg")); + params.name(params.label); + gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsTorso")); + params.name(params.label); + gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsRightLeg")); + params.name(params.label); + gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create (params); + + params.label(LLTrans::getString("BodyPartsEnhancedSkeleton")); + params.name(params.label); + gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create(params); + + for (S32 i = 0; i < 9; i++) + { + if (gAttachBodyPartPieMenus[i]) + { + gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] ); + } + else + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment && attachment->getGroup() == i) + { + LLMenuItemCallGL::Params item_params; + + std::string sub_piemenu_name = attachment->getName(); + if (LLTrans::getString(sub_piemenu_name) != "") + { + item_params.label = LLTrans::getString(sub_piemenu_name); + } + else + { + item_params.label = sub_piemenu_name; + } + item_params.name =(item_params.label ); + item_params.on_click.function_name = "Object.AttachToAvatar"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Object.EnableWear"; + item_params.on_enable.parameter = iter->first; + LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); + + gAttachPieMenu->addChild(item); + + break; + + } + } + } + + if (gDetachBodyPartPieMenus[i]) + { + gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); + gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); + gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); + } + else + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment && attachment->getGroup() == i) + { + LLMenuItemCallGL::Params item_params; + std::string sub_piemenu_name = attachment->getName(); + if (LLTrans::getString(sub_piemenu_name) != "") + { + item_params.label = LLTrans::getString(sub_piemenu_name); + } + else + { + item_params.label = sub_piemenu_name; + } + item_params.name =(item_params.label ); + item_params.on_click.function_name = "Attachment.DetachFromPoint"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Attachment.PointFilled"; + item_params.on_enable.parameter = iter->first; + LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); + + gDetachPieMenu->addChild(item); + gDetachAttSelfMenu->addChild(LLUICtrlFactory::create(item_params)); + gDetachAvatarMenu->addChild(LLUICtrlFactory::create(item_params)); + break; + } + } + } + } + + + // add screen attachments + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getGroup() == 9) + { + LLMenuItemCallGL::Params item_params; + std::string sub_piemenu_name = attachment->getName(); + if (LLTrans::getString(sub_piemenu_name) != "") + { + item_params.label = LLTrans::getString(sub_piemenu_name); + } + else + { + item_params.label = sub_piemenu_name; + } + item_params.name =(item_params.label ); + item_params.on_click.function_name = "Object.AttachToAvatar"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Object.EnableWear"; + item_params.on_enable.parameter = iter->first; + LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); + gAttachScreenPieMenu->addChild(item); + + item_params.on_click.function_name = "Attachment.DetachFromPoint"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Attachment.PointFilled"; + item_params.on_enable.parameter = iter->first; + item = LLUICtrlFactory::create(item_params); + gDetachScreenPieMenu->addChild(item); + gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create(item_params)); + gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create(item_params)); + } + } + + for (S32 pass = 0; pass < 2; pass++) + { + // *TODO: Skinning - gAttachSubMenu is an awful, awful hack + if (!gAttachSubMenu) + { + break; + } + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment() != (pass == 1)) + { + continue; + } + LLMenuItemCallGL::Params item_params; + std::string sub_piemenu_name = attachment->getName(); + if (LLTrans::getString(sub_piemenu_name) != "") + { + item_params.label = LLTrans::getString(sub_piemenu_name); + } + else + { + item_params.label = sub_piemenu_name; + } + item_params.name =(item_params.label ); + item_params.on_click.function_name = "Object.AttachToAvatar"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Object.EnableWear"; + item_params.on_enable.parameter = iter->first; + //* TODO: Skinning: + //LLSD params; + //params["index"] = iter->first; + //params["label"] = attachment->getName(); + //item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params)); + + LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); + gAttachSubMenu->addChild(item); + + item_params.on_click.function_name = "Attachment.DetachFromPoint"; + item_params.on_click.parameter = iter->first; + item_params.on_enable.function_name = "Attachment.PointFilled"; + item_params.on_enable.parameter = iter->first; + //* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params)); + + item = LLUICtrlFactory::create(item_params); + gDetachSubMenu->addChild(item); + } + if (pass == 0) + { + // put separator between non-hud and hud attachments + gAttachSubMenu->addSeparator(); + gDetachSubMenu->addSeparator(); + } + } + + for (S32 group = 0; group < 9; group++) + { + // skip over groups that don't have sub menus + if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group]) + { + continue; + } + + std::multimap attachment_pie_menu_map; + + // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if(attachment && attachment->getGroup() == group) + { + // use multimap to provide a partial order off of the pie slice key + S32 pie_index = attachment->getPieSlice(); + attachment_pie_menu_map.insert(std::make_pair(pie_index, iter->first)); + } + } + + // add in requested order to pie menu, inserting separators as necessary + for (std::multimap::iterator attach_it = attachment_pie_menu_map.begin(); + attach_it != attachment_pie_menu_map.end(); ++attach_it) + { + S32 attach_index = attach_it->second; + + LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); + if (attachment) + { + LLMenuItemCallGL::Params item_params; + item_params.name = attachment->getName(); + item_params.label = LLTrans::getString(attachment->getName()); + item_params.on_click.function_name = "Object.AttachToAvatar"; + item_params.on_click.parameter = attach_index; + item_params.on_enable.function_name = "Object.EnableWear"; + item_params.on_enable.parameter = attach_index; + + LLMenuItemCallGL* item = LLUICtrlFactory::create(item_params); + gAttachBodyPartPieMenus[group]->addChild(item); + + item_params.on_click.function_name = "Attachment.DetachFromPoint"; + item_params.on_click.parameter = attach_index; + item_params.on_enable.function_name = "Attachment.PointFilled"; + item_params.on_enable.parameter = attach_index; + item = LLUICtrlFactory::create(item_params); + gDetachBodyPartPieMenus[group]->addChild(item); + } + } + } + return TRUE; } void LLVOAvatarSelf::cleanup() { - markDead(); - delete mScreenp; - mScreenp = NULL; - mRegionp = NULL; + markDead(); + delete mScreenp; + mScreenp = NULL; + mRegionp = NULL; } LLVOAvatarSelf::~LLVOAvatarSelf() { - cleanup(); + cleanup(); } /** @@ -677,33 +677,33 @@ LLVOAvatarSelf::~LLVOAvatarSelf() // virtual bool LLVOAvatarSelf::updateCharacter(LLAgent &agent) { - // update screen joint size - if (mScreenp) - { - F32 aspect = LLViewerCamera::getInstance()->getAspect(); - LLVector3 scale(1.f, aspect, 1.f); - mScreenp->setScale(scale); - mScreenp->updateWorldMatrixChildren(); - resetHUDAttachments(); - } - - return LLVOAvatar::updateCharacter(agent); + // update screen joint size + if (mScreenp) + { + F32 aspect = LLViewerCamera::getInstance()->getAspect(); + LLVector3 scale(1.f, aspect, 1.f); + mScreenp->setScale(scale); + mScreenp->updateWorldMatrixChildren(); + resetHUDAttachments(); + } + + return LLVOAvatar::updateCharacter(agent); } // virtual BOOL LLVOAvatarSelf::isValid() const { - return ((getRegion() != NULL) && !isDead()); + return ((getRegion() != NULL) && !isDead()); } // virtual void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) { - if (isValid()) - { - LLVOAvatar::idleUpdate(agent, time); - idleUpdateTractorBeam(); - } + if (isValid()) + { + LLVOAvatar::idleUpdate(agent, time); + idleUpdateTractorBeam(); + } } // virtual @@ -711,14 +711,14 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) { LLJoint *jointp = NULL; jointp = LLVOAvatar::getJoint(name); - if (!jointp && mScreenp) - { - jointp = mScreenp->findJoint(name); + if (!jointp && mScreenp) + { + jointp = mScreenp->findJoint(name); if (jointp) { mJointMap[name] = jointp; } - } + } if (jointp && jointp != mScreenp && jointp != mRoot) { llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp); @@ -729,238 +729,238 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) { - if (!which_param) - { - return FALSE; - } - LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID()); - return setParamWeight(param,weight); + if (!which_param) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID()); + return setParamWeight(param,weight); } // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight) { - if (!param_name) - { - return FALSE; - } - LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name); - return setParamWeight(param,weight); + if (!param_name) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name); + return setParamWeight(param,weight); } // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight) { - LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index); - return setParamWeight(param,weight); + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index); + return setParamWeight(param,weight); } BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight) { - if (!param) - { - return FALSE; - } - - if (param->getCrossWearable()) - { - LLWearableType::EType type = (LLWearableType::EType)param->getWearableType(); - U32 size = gAgentWearables.getWearableCount(type); - for (U32 count = 0; count < size; ++count) - { - LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count); - if (wearable) - { - wearable->setVisualParamWeight(param->getID(), weight); - } - } - } - - return LLCharacter::setVisualParamWeight(param,weight); -} - -/*virtual*/ + if (!param) + { + return FALSE; + } + + if (param->getCrossWearable()) + { + LLWearableType::EType type = (LLWearableType::EType)param->getWearableType(); + U32 size = gAgentWearables.getWearableCount(type); + for (U32 count = 0; count < size; ++count) + { + LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count); + if (wearable) + { + wearable->setVisualParamWeight(param->getID(), weight); + } + } + } + + return LLCharacter::setVisualParamWeight(param,weight); +} + +/*virtual*/ void LLVOAvatarSelf::updateVisualParams() { - LLVOAvatar::updateVisualParams(); + LLVOAvatar::updateVisualParams(); } void LLVOAvatarSelf::writeWearablesToAvatar() { - for (U32 type = 0; type < LLWearableType::WT_COUNT; type++) - { - LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); - if (wearable) - { - wearable->writeToAvatar(this); - } - } + for (U32 type = 0; type < LLWearableType::WT_COUNT; type++) + { + LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); + if (wearable) + { + wearable->writeToAvatar(this); + } + } } /*virtual*/ void LLVOAvatarSelf::idleUpdateAppearanceAnimation() { - // Animate all top-level wearable visual parameters - gAgentWearables.animateAllWearableParams(calcMorphAmount()); + // Animate all top-level wearable visual parameters + gAgentWearables.animateAllWearableParams(calcMorphAmount()); - // Apply wearable visual params to avatar - writeWearablesToAvatar(); + // Apply wearable visual params to avatar + writeWearablesToAvatar(); - //allow avatar to process updates - LLVOAvatar::idleUpdateAppearanceAnimation(); + //allow avatar to process updates + LLVOAvatar::idleUpdateAppearanceAnimation(); } // virtual void LLVOAvatarSelf::requestStopMotion(LLMotion* motion) { - // Only agent avatars should handle the stop motion notifications. + // Only agent avatars should handle the stop motion notifications. - // Notify agent that motion has stopped - gAgent.requestStopMotion(motion); + // Notify agent that motion has stopped + gAgent.requestStopMotion(motion); } // virtual bool LLVOAvatarSelf::hasMotionFromSource(const LLUUID& source_id) { - AnimSourceIterator motion_it = mAnimationSources.find(source_id); - return motion_it != mAnimationSources.end(); + AnimSourceIterator motion_it = mAnimationSources.find(source_id); + return motion_it != mAnimationSources.end(); } // virtual void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) { - for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); ) - { - gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP); - mAnimationSources.erase(motion_it); - // Must find() after each erase() to deal with potential iterator invalidation - // This also ensures that we don't go past the end of this source's animations - // into those of another source. - motion_it = mAnimationSources.find(source_id); - } + for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); ) + { + gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP); + mAnimationSources.erase(motion_it); + // Must find() after each erase() to deal with potential iterator invalidation + // This also ensures that we don't go past the end of this source's animations + // into those of another source. + motion_it = mAnimationSources.find(source_id); + } - LLViewerObject* object = gObjectList.findObject(source_id); - if (object) - { - object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE); - } + LLViewerObject* object = gObjectList.findObject(source_id); + if (object) + { + object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE); + } } void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index) { - if (te >= TEX_NUM_INDICES) - { - llassert(0); - return; - } + if (te >= TEX_NUM_INDICES) + { + llassert(0); + return; + } - if (getTEImage(te)->getID() == image->getID()) - { - return; - } + if (getTEImage(te)->getID() == image->getID()) + { + return; + } - if (isIndexBakedTexture((ETextureIndex)te)) - { - llassert(0); - return; - } + if (isIndexBakedTexture((ETextureIndex)te)) + { + llassert(0); + return; + } - setTEImage(te, image); + setTEImage(te, image); } //virtual void LLVOAvatarSelf::removeMissingBakedTextures() -{ - BOOL removed = FALSE; - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - const S32 te = mBakedTextureDatas[i].mTextureIndex; - const LLViewerTexture* tex = getTEImage(te); - - // Replace with default if we can't find the asset, assuming the - // default is actually valid (which it should be unless something - // is seriously wrong). - if (!tex || tex->isMissingAsset()) - { - LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); - if (imagep && imagep != tex) - { - setTEImage(te, imagep); - removed = TRUE; - } - } - } - - if (removed) - { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - LLViewerTexLayerSet *layerset = getTexLayerSet(i); - layerset->setUpdatesEnabled(TRUE); - invalidateComposite(layerset); - } - updateMeshTextures(); - } +{ + BOOL removed = FALSE; + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const S32 te = mBakedTextureDatas[i].mTextureIndex; + const LLViewerTexture* tex = getTEImage(te); + + // Replace with default if we can't find the asset, assuming the + // default is actually valid (which it should be unless something + // is seriously wrong). + if (!tex || tex->isMissingAsset()) + { + LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + if (imagep && imagep != tex) + { + setTEImage(te, imagep); + removed = TRUE; + } + } + } + + if (removed) + { + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + layerset->setUpdatesEnabled(TRUE); + invalidateComposite(layerset); + } + updateMeshTextures(); + } } void LLVOAvatarSelf::onSimulatorFeaturesReceived(const LLUUID& region_id) { - LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL; - setHoverIfRegionEnabled(); + LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL; + setHoverIfRegionEnabled(); } //virtual void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) { - // Save the global position - LLVector3d global_pos_from_old_region = getPositionGlobal(); - - // Change the region - setRegion(regionp); - - if (regionp) - { // Set correct region-relative position from global coordinates - setPositionGlobal(global_pos_from_old_region); - - // Diagnostic info - //LLVector3d pos_from_new_region = getPositionGlobal(); - //LL_INFOS() << "pos_from_old_region is " << global_pos_from_old_region - // << " while pos_from_new_region is " << pos_from_new_region - // << LL_ENDL; - - // Update hover height, or schedule callback, based on whether - // it's supported in this region. - if (regionp->simulatorFeaturesReceived()) - { - setHoverIfRegionEnabled(); - } - else - { - regionp->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1)); - } - } - - if (!regionp || (regionp->getHandle() != mLastRegionHandle)) - { - if (mLastRegionHandle != 0) - { - ++mRegionCrossingCount; - F64Seconds delta(mRegionCrossingTimer.getElapsedTimeF32()); - record(LLStatViewer::REGION_CROSSING_TIME, delta); - - // Diagnostics - LL_INFOS() << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << LL_ENDL; - } - if (regionp) - { - mLastRegionHandle = regionp->getHandle(); - } - } - mRegionCrossingTimer.reset(); - LLViewerObject::updateRegion(regionp); + // Save the global position + LLVector3d global_pos_from_old_region = getPositionGlobal(); + + // Change the region + setRegion(regionp); + + if (regionp) + { // Set correct region-relative position from global coordinates + setPositionGlobal(global_pos_from_old_region); + + // Diagnostic info + //LLVector3d pos_from_new_region = getPositionGlobal(); + //LL_INFOS() << "pos_from_old_region is " << global_pos_from_old_region + // << " while pos_from_new_region is " << pos_from_new_region + // << LL_ENDL; + + // Update hover height, or schedule callback, based on whether + // it's supported in this region. + if (regionp->simulatorFeaturesReceived()) + { + setHoverIfRegionEnabled(); + } + else + { + regionp->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1)); + } + } + + if (!regionp || (regionp->getHandle() != mLastRegionHandle)) + { + if (mLastRegionHandle != 0) + { + ++mRegionCrossingCount; + F64Seconds delta(mRegionCrossingTimer.getElapsedTimeF32()); + record(LLStatViewer::REGION_CROSSING_TIME, delta); + + // Diagnostics + LL_INFOS() << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << LL_ENDL; + } + if (regionp) + { + mLastRegionHandle = regionp->getHandle(); + } + } + mRegionCrossingTimer.reset(); + LLViewerObject::updateRegion(regionp); } //-------------------------------------------------------------------- @@ -969,65 +969,65 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) //virtual void LLVOAvatarSelf::idleUpdateTractorBeam() { - // This is only done for yourself (maybe it should be in the agent?) - if (!needsRenderBeam() || !isBuilt()) - { - mBeam = NULL; - } - else if (!mBeam || mBeam->isDead()) - { - // VEFFECT: Tractor Beam - mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); - mBeam->setColor(LLColor4U(gAgent.getEffectColor())); - mBeam->setSourceObject(this); - mBeamTimer.reset(); - } - - if (!mBeam.isNull()) - { - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - if (gAgentCamera.mPointAt.notNull()) - { - // get point from pointat effect - mBeam->setPositionGlobal(gAgentCamera.mPointAt->getPointAtPosGlobal()); - mBeam->triggerLocal(); - } - else if (selection->getFirstRootObject() && - selection->getSelectType() != SELECT_TYPE_HUD) - { - LLViewerObject* objectp = selection->getFirstRootObject(); - mBeam->setTargetObject(objectp); - } - else - { - mBeam->setTargetObject(NULL); - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - if (tool->isEditing()) - { - if (tool->getEditingObject()) - { - mBeam->setTargetObject(tool->getEditingObject()); - } - else - { - mBeam->setPositionGlobal(tool->getEditingPointGlobal()); - } - } - else - { - const LLPickInfo& pick = gViewerWindow->getLastPick(); - mBeam->setPositionGlobal(pick.mPosGlobal); - } - - } - if (mBeamTimer.getElapsedTimeF32() > 0.25f) - { - mBeam->setColor(LLColor4U(gAgent.getEffectColor())); - mBeam->setNeedsSendToSim(TRUE); - mBeamTimer.reset(); - } - } + // This is only done for yourself (maybe it should be in the agent?) + if (!needsRenderBeam() || !isBuilt()) + { + mBeam = NULL; + } + else if (!mBeam || mBeam->isDead()) + { + // VEFFECT: Tractor Beam + mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); + mBeam->setColor(LLColor4U(gAgent.getEffectColor())); + mBeam->setSourceObject(this); + mBeamTimer.reset(); + } + + if (!mBeam.isNull()) + { + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + if (gAgentCamera.mPointAt.notNull()) + { + // get point from pointat effect + mBeam->setPositionGlobal(gAgentCamera.mPointAt->getPointAtPosGlobal()); + mBeam->triggerLocal(); + } + else if (selection->getFirstRootObject() && + selection->getSelectType() != SELECT_TYPE_HUD) + { + LLViewerObject* objectp = selection->getFirstRootObject(); + mBeam->setTargetObject(objectp); + } + else + { + mBeam->setTargetObject(NULL); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + if (tool->isEditing()) + { + if (tool->getEditingObject()) + { + mBeam->setTargetObject(tool->getEditingObject()); + } + else + { + mBeam->setPositionGlobal(tool->getEditingPointGlobal()); + } + } + else + { + const LLPickInfo& pick = gViewerWindow->getLastPick(); + mBeam->setPositionGlobal(pick.mPosGlobal); + } + + } + if (mBeamTimer.getElapsedTimeF32() > 0.25f) + { + mBeam->setColor(LLColor4U(gAgent.getEffectColor())); + mBeam->setNeedsSendToSim(TRUE); + mBeamTimer.reset(); + } + } } //----------------------------------------------------------------------------- @@ -1036,13 +1036,13 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() // virtual void LLVOAvatarSelf::restoreMeshData() { - //LL_INFOS() << "Restoring" << LL_ENDL; - mMeshValid = TRUE; - updateJointLODs(); - updateAttachmentVisibility(gAgentCamera.getCameraMode()); + //LL_INFOS() << "Restoring" << LL_ENDL; + mMeshValid = TRUE; + updateJointLODs(); + updateAttachmentVisibility(gAgentCamera.getCameraMode()); - // force mesh update as LOD might not have changed to trigger this - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + // force mesh update as LOD might not have changed to trigger this + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); } @@ -1052,35 +1052,35 @@ void LLVOAvatarSelf::restoreMeshData() //----------------------------------------------------------------------------- void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (attachment->getIsHUDAttachment()) - { - attachment->setAttachmentVisibility(TRUE); - } - else - { - switch (camera_mode) - { - case CAMERA_MODE_MOUSELOOK: - if ((LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) || gPipeline.mHeroProbeManager.isMirrorPass()) - { - attachment->setAttachmentVisibility(TRUE); - } - else - { - attachment->setAttachmentVisibility(FALSE); - } - break; - default: - attachment->setAttachmentVisibility(TRUE); - break; - } - } - } + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment()) + { + attachment->setAttachmentVisibility(TRUE); + } + else + { + switch (camera_mode) + { + case CAMERA_MODE_MOUSELOOK: + if ((LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) || gPipeline.mHeroProbeManager.isMirrorPass()) + { + attachment->setAttachmentVisibility(TRUE); + } + else + { + attachment->setAttachmentVisibility(FALSE); + } + break; + default: + attachment->setAttachmentVisibility(TRUE); + break; + } + } + } } //----------------------------------------------------------------------------- @@ -1090,33 +1090,33 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) //----------------------------------------------------------------------------- void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type) { - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; - const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first; - - if (baked_dict) - { - for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); - type_iter != baked_dict->mWearables.end(); - ++type_iter) - { - const LLWearableType::EType comp_type = *type_iter; - if (comp_type == type) - { - LLViewerTexLayerSet *layerset = getLayerSet(index); - if (layerset) - { - layerset->setUpdatesEnabled(true); - invalidateComposite(layerset); - } - break; - } - } - } - } + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first; + + if (baked_dict) + { + for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); + type_iter != baked_dict->mWearables.end(); + ++type_iter) + { + const LLWearableType::EType comp_type = *type_iter; + if (comp_type == type) + { + LLViewerTexLayerSet *layerset = getLayerSet(index); + if (layerset) + { + layerset->setUpdatesEnabled(true); + invalidateComposite(layerset); + } + break; + } + } + } + } } //----------------------------------------------------------------------------- @@ -1124,18 +1124,18 @@ void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type) //----------------------------------------------------------------------------- BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const { - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment* attachment = iter->second; - if (attachment->getAttachedObject(base_inv_item_id)) - { - return TRUE; - } - } - return FALSE; + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment* attachment = iter->second; + if (attachment->getAttachedObject(base_inv_item_id)) + { + return TRUE; + } + } + return FALSE; } //----------------------------------------------------------------------------- @@ -1143,113 +1143,113 @@ BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const //----------------------------------------------------------------------------- LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id) { - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id)) - { - return attached_object; - } - } - return NULL; + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id)) + { + return attached_object; + } + } + return NULL; } bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (!gInventory.getItem(inv_item_id)) - { - name = "ATTACHMENT_MISSING_ITEM"; - return false; - } - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - if (!gInventory.getItem(base_inv_item_id)) - { - name = "ATTACHMENT_MISSING_BASE_ITEM"; - return false; - } - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - const LLViewerJointAttachment* attachment = iter->second; - if (attachment->getAttachedObject(base_inv_item_id)) - { - name = attachment->getName(); - return true; - } - } - - name = "ATTACHMENT_NOT_ATTACHED"; - return false; + if (!gInventory.getItem(inv_item_id)) + { + name = "ATTACHMENT_MISSING_ITEM"; + return false; + } + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + if (!gInventory.getItem(base_inv_item_id)) + { + name = "ATTACHMENT_MISSING_BASE_ITEM"; + return false; + } + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment* attachment = iter->second; + if (attachment->getAttachedObject(base_inv_item_id)) + { + name = attachment->getName(); + return true; + } + } + + name = "ATTACHMENT_NOT_ATTACHED"; + return false; } //virtual const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object) { - const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); - if (!attachment) - { - return 0; - } + const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); + if (!attachment) + { + return 0; + } - updateAttachmentVisibility(gAgentCamera.getCameraMode()); - - // Then make sure the inventory is in sync with the avatar. + updateAttachmentVisibility(gAgentCamera.getCameraMode()); - // Should just be the last object added - if (attachment->isObjectAttached(viewer_object)) - { - const LLUUID& attachment_id = viewer_object->getAttachmentItemID(); - LLAppearanceMgr::instance().registerAttachment(attachment_id); - updateLODRiggedAttachments(); - } + // Then make sure the inventory is in sync with the avatar. - return attachment; + // Should just be the last object added + if (attachment->isObjectAttached(viewer_object)) + { + const LLUUID& attachment_id = viewer_object->getAttachmentItemID(); + LLAppearanceMgr::instance().registerAttachment(attachment_id); + updateLODRiggedAttachments(); + } + + return attachment; } //virtual BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) { - const LLUUID attachment_id = viewer_object->getAttachmentItemID(); - if ( LLVOAvatar::detachObject(viewer_object) ) - { - // the simulator should automatically handle permission revocation - - stopMotionFromSource(attachment_id); - LLFollowCamMgr::getInstance()->setCameraActive(viewer_object->getID(), FALSE); - - LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); - ++iter) - { - LLViewerObject* child_objectp = *iter; - // the simulator should automatically handle - // permissions revocation - - stopMotionFromSource(child_objectp->getID()); - LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE); - } - - // Make sure the inventory is in sync with the avatar. - - // Update COF contents, don't trigger appearance update. - if (!isValid()) - { - LL_INFOS() << "removeItemLinks skipped, avatar is under destruction" << LL_ENDL; - } - else - { - LLAppearanceMgr::instance().unregisterAttachment(attachment_id); - } - - return TRUE; - } - return FALSE; + const LLUUID attachment_id = viewer_object->getAttachmentItemID(); + if ( LLVOAvatar::detachObject(viewer_object) ) + { + // the simulator should automatically handle permission revocation + + stopMotionFromSource(attachment_id); + LLFollowCamMgr::getInstance()->setCameraActive(viewer_object->getID(), FALSE); + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); + ++iter) + { + LLViewerObject* child_objectp = *iter; + // the simulator should automatically handle + // permissions revocation + + stopMotionFromSource(child_objectp->getID()); + LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE); + } + + // Make sure the inventory is in sync with the avatar. + + // Update COF contents, don't trigger appearance update. + if (!isValid()) + { + LL_INFOS() << "removeItemLinks skipped, avatar is under destruction" << LL_ENDL; + } + else + { + LLAppearanceMgr::instance().unregisterAttachment(attachment_id); + } + + return TRUE; + } + return FALSE; } bool LLVOAvatarSelf::hasAttachmentsInTrash() @@ -1276,140 +1276,140 @@ bool LLVOAvatarSelf::hasAttachmentsInTrash() // static BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) { - LLInventoryItem* item = gInventory.getItem(item_id); - if (item) - { - gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - // This object might have been selected, so let the selection manager know it's gone now - LLViewerObject *found_obj = gObjectList.findObject(item_id); - if (found_obj) - { - LLSelectMgr::getInstance()->remove(found_obj); - } - - // Error checking in case this object was attached to an invalid point - // In that case, just remove the item from COF preemptively since detach - // will fail. - if (isAgentAvatarValid()) - { - const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id); - if (!attached_obj) - { - LLAppearanceMgr::instance().removeCOFItemLinks(item_id); - } - } - return TRUE; - } - return FALSE; + LLInventoryItem* item = gInventory.getItem(item_id); + if (item) + { + gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); + gMessageSystem->sendReliable(gAgent.getRegionHost()); + + // This object might have been selected, so let the selection manager know it's gone now + LLViewerObject *found_obj = gObjectList.findObject(item_id); + if (found_obj) + { + LLSelectMgr::getInstance()->remove(found_obj); + } + + // Error checking in case this object was attached to an invalid point + // In that case, just remove the item from COF preemptively since detach + // will fail. + if (isAgentAvatarValid()) + { + const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id); + if (!attached_obj) + { + LLAppearanceMgr::instance().removeCOFItemLinks(item_id); + } + } + return TRUE; + } + return FALSE; } U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const { - LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i); - return gAgentWearables.getWearableCount(type); + LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i); + return gAgentWearables.getWearableCount(type); } // virtual void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) -{ - - const LLUUID& src_id = src_vi->getID(); - LLAvatarTexData *data = (LLAvatarTexData *)userdata; - ETextureIndex index = data->mIndex; - if (!isIndexLocalTexture(index)) return; - - LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0); - - // fix for EXT-268. Preventing using of NULL pointer - if(NULL == local_tex_obj) - { - LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index - << ", final: " << final - << LL_ENDL; - return; - } - if (success) - { - if (!local_tex_obj->getBakedReady() && - local_tex_obj->getImage() != NULL && - (local_tex_obj->getID() == src_id) && - discard_level < local_tex_obj->getDiscard()) - { - local_tex_obj->setDiscard(discard_level); - requestLayerSetUpdate(index); - if (isEditingAppearance()) - { - LLVisualParamHint::requestHintUpdates(); - } - updateMeshTextures(); - } - } - else if (final) - { - // Failed: asset is missing - if (!local_tex_obj->getBakedReady() && - local_tex_obj->getImage() != NULL && - local_tex_obj->getImage()->getID() == src_id) - { - local_tex_obj->setDiscard(0); - requestLayerSetUpdate(index); - updateMeshTextures(); - } - } +{ + + const LLUUID& src_id = src_vi->getID(); + LLAvatarTexData *data = (LLAvatarTexData *)userdata; + ETextureIndex index = data->mIndex; + if (!isIndexLocalTexture(index)) return; + + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0); + + // fix for EXT-268. Preventing using of NULL pointer + if(NULL == local_tex_obj) + { + LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index + << ", final: " << final + << LL_ENDL; + return; + } + if (success) + { + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + (local_tex_obj->getID() == src_id) && + discard_level < local_tex_obj->getDiscard()) + { + local_tex_obj->setDiscard(discard_level); + requestLayerSetUpdate(index); + if (isEditingAppearance()) + { + LLVisualParamHint::requestHintUpdates(); + } + updateMeshTextures(); + } + } + else if (final) + { + // Failed: asset is missing + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + local_tex_obj->getImage()->getID() == src_id) + { + local_tex_obj->setDiscard(0); + requestLayerSetUpdate(index); + updateMeshTextures(); + } + } } // virtual BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const { - *tex_pp = NULL; + *tex_pp = NULL; - if (!isIndexLocalTexture(type)) return FALSE; - if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE; + if (!isIndexLocalTexture(type)) return FALSE; + if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE; - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); - if (!local_tex_obj) - { - return FALSE; - } - *tex_pp = dynamic_cast (local_tex_obj->getImage()); - return TRUE; + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (!local_tex_obj) + { + return FALSE; + } + *tex_pp = dynamic_cast (local_tex_obj->getImage()); + return TRUE; } LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { - if (!isIndexLocalTexture(type)) - { - return NULL; - } + if (!isIndexLocalTexture(type)) + { + return NULL; + } - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); - if (!local_tex_obj) - { - return NULL; - } - if (local_tex_obj->getID() == IMG_DEFAULT_AVATAR) - { - return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); - } - return dynamic_cast (local_tex_obj->getImage()); + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (!local_tex_obj) + { + return NULL; + } + if (local_tex_obj->getID() == IMG_DEFAULT_AVATAR) + { + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + } + return dynamic_cast (local_tex_obj->getImage()); } const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const { - if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; + if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); - if (local_tex_obj && local_tex_obj->getImage() != NULL) - { - return local_tex_obj->getImage()->getID(); - } - return IMG_DEFAULT_AVATAR; -} + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (local_tex_obj && local_tex_obj->getImage() != NULL) + { + return local_tex_obj->getImage()->getID(); + } + return IMG_DEFAULT_AVATAR; +} //----------------------------------------------------------------------------- @@ -1419,35 +1419,35 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c //----------------------------------------------------------------------------- BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const { - /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) - return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const EBakedTextureIndex baked_index = baked_iter->first; - if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) - { - BOOL ret = true; - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0); - ret &= tex_avail; - } - } - return ret; - } - } - llassert(0); - return FALSE; + /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) + return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const EBakedTextureIndex baked_index = baked_iter->first; + if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) + { + BOOL ret = true; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0); + ret &= tex_avail; + } + } + return ret; + } + } + llassert(0); + return FALSE; } //----------------------------------------------------------------------------- @@ -1458,159 +1458,159 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye //----------------------------------------------------------------------------- BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const { - const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); - // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels. - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (layerset == mBakedTextureDatas[i].mTexLayerSet) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); - if ((local_discard_level > (S32)(desired_tex_discard_level)) || - (local_discard_level < 0 )) - { - return FALSE; - } - } - } - return TRUE; - } - } - llassert(0); - return FALSE; + const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); + // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels. + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (layerset == mBakedTextureDatas[i].mTexLayerSet) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); + if ((local_discard_level > (S32)(desired_tex_discard_level)) || + (local_discard_level < 0 )) + { + return FALSE; + } + } + } + return TRUE; + } + } + llassert(0); + return FALSE; } BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const { - const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); - // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); - if ((local_discard_level > (S32)(desired_tex_discard_level)) || - (local_discard_level < 0 )) - { - return FALSE; - } - } - } - } - return TRUE; + const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); + // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); + if ((local_discard_level > (S32)(desired_tex_discard_level)) || + (local_discard_level < 0 )) + { + return FALSE; + } + } + } + } + return TRUE; } BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { - LLUUID id; - BOOL isDefined = TRUE; - if (isIndexLocalTexture(type)) - { - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - if (index >= wearable_count) - { - // invalid index passed in. check all textures of a given type - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - id = getLocalTextureID(type, wearable_index); - isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); - } - } - else - { - id = getLocalTextureID(type, index); - isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); - } - } - else - { - id = getTEImage(type)->getID(); - isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); - } - - return isDefined; + LLUUID id; + BOOL isDefined = TRUE; + if (isIndexLocalTexture(type)) + { + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + if (index >= wearable_count) + { + // invalid index passed in. check all textures of a given type + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + id = getLocalTextureID(type, wearable_index); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); + } + } + else + { + id = getLocalTextureID(type, index); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); + } + } + else + { + id = getTEImage(type)->getID(); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); + } + + return isDefined; } //virtual BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { - if (isIndexBakedTexture(type)) - { - return LLVOAvatar::isTextureVisible(type, (U32)0); - } + if (isIndexBakedTexture(type)) + { + return LLVOAvatar::isTextureVisible(type, (U32)0); + } - LLUUID tex_id = getLocalTextureID(type,index); - return (tex_id != IMG_INVISIBLE) - || (LLDrawPoolAlpha::sShowDebugAlpha); + LLUUID tex_id = getLocalTextureID(type,index); + return (tex_id != IMG_INVISIBLE) + || (LLDrawPoolAlpha::sShowDebugAlpha); } //virtual BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const { - if (isIndexBakedTexture(type)) - { - return LLVOAvatar::isTextureVisible(type); - } + if (isIndexBakedTexture(type)) + { + return LLVOAvatar::isTextureVisible(type); + } - U32 index; - if (gAgentWearables.getWearableIndex(wearable,index)) - { - return isTextureVisible(type,index); - } - else - { - LL_WARNS() << "Wearable not found" << LL_ENDL; - return FALSE; - } + U32 index; + if (gAgentWearables.getWearableIndex(wearable,index)) + { + return isTextureVisible(type,index); + } + else + { + LL_WARNS() << "Wearable not found" << LL_ENDL; + return FALSE; + } } bool LLVOAvatarSelf::areTexturesCurrent() const { - return gAgentWearables.areWearablesLoaded(); + return gAgentWearables.areWearablesLoaded(); } void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset) { - LLViewerTexLayerSet *layer_set = dynamic_cast(layerset); - if( !layer_set || !layer_set->getUpdatesEnabled() ) - { - return; - } - // LL_INFOS() << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << LL_ENDL; + LLViewerTexLayerSet *layer_set = dynamic_cast(layerset); + if( !layer_set || !layer_set->getUpdatesEnabled() ) + { + return; + } + // LL_INFOS() << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << LL_ENDL; - layer_set->requestUpdate(); - layer_set->invalidateMorphMasks(); + layer_set->requestUpdate(); + layer_set->invalidateMorphMasks(); } void LLVOAvatarSelf::invalidateAll() { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - LLViewerTexLayerSet *layerset = getTexLayerSet(i); - invalidateComposite(layerset); - } - //mDebugSelfLoadTimer.reset(); + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + invalidateComposite(layerset); + } + //mDebugSelfLoadTimer.reset(); } //----------------------------------------------------------------------------- @@ -1618,593 +1618,593 @@ void LLVOAvatarSelf::invalidateAll() //----------------------------------------------------------------------------- void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b ) { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - setCompositeUpdatesEnabled(i, b); - } + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + setCompositeUpdatesEnabled(i, b); + } } void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b) { - LLViewerTexLayerSet *layerset = getTexLayerSet(index); - if (layerset ) - { - layerset->setUpdatesEnabled( b ); - } + LLViewerTexLayerSet *layerset = getTexLayerSet(index); + if (layerset ) + { + layerset->setUpdatesEnabled( b ); + } } bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index) { - LLViewerTexLayerSet *layerset = getTexLayerSet(index); - if (layerset) - { - return layerset->getUpdatesEnabled(); - } - return false; + LLViewerTexLayerSet *layerset = getTexLayerSet(index); + if (layerset) + { + return layerset->getUpdatesEnabled(); + } + return false; } void LLVOAvatarSelf::setupComposites() { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; - BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); - LLViewerTexLayerSet *layerset = getTexLayerSet(i); - if (layerset) - { - layerset->setUpdatesEnabled(!layer_baked); - } - } + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; + BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + if (layerset) + { + layerset->setUpdatesEnabled(!layer_baked); + } + } } void LLVOAvatarSelf::updateComposites() { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - LLViewerTexLayerSet *layerset = getTexLayerSet(i); - if (layerset - && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))) - { - layerset->updateComposite(); - } - } + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + if (layerset + && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))) + { + layerset->updateComposite(); + } + } } // virtual S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index) const { - if (!isIndexLocalTexture(type)) return FALSE; - - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index); - if (local_tex_obj) - { - const LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); - if (type >= 0 - && local_tex_obj->getID() != IMG_DEFAULT_AVATAR - && !image->isMissingAsset()) - { - return image->getDiscardLevel(); - } - else - { - // We don't care about this (no image associated with the layer) treat as fully loaded. - return 0; - } - } - return 0; + if (!isIndexLocalTexture(type)) return FALSE; + + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index); + if (local_tex_obj) + { + const LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); + if (type >= 0 + && local_tex_obj->getID() != IMG_DEFAULT_AVATAR + && !image->isMissingAsset()) + { + return image->getDiscardLevel(); + } + else + { + // We don't care about this (no image associated with the layer) treat as fully loaded. + return 0; + } + } + return 0; } // virtual // Counts the memory footprint of local textures. void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const { - *gl_bytes = 0; - for (S32 type = 0; type < TEX_NUM_INDICES; type++) - { - if (!isIndexLocalTexture((ETextureIndex)type)) continue; - U32 max_tex = getNumWearables((ETextureIndex) type); - for (U32 num = 0; num < max_tex; num++) - { - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num); - if (local_tex_obj) - { - const LLViewerFetchedTexture* image_gl = dynamic_cast( local_tex_obj->getImage() ); - if (image_gl) - { - S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); - - if (image_gl->hasGLTexture()) - { - *gl_bytes += bytes; - } - } - } - } - } -} - -// virtual + *gl_bytes = 0; + for (S32 type = 0; type < TEX_NUM_INDICES; type++) + { + if (!isIndexLocalTexture((ETextureIndex)type)) continue; + U32 max_tex = getNumWearables((ETextureIndex) type); + for (U32 num = 0; num < max_tex; num++) + { + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num); + if (local_tex_obj) + { + const LLViewerFetchedTexture* image_gl = dynamic_cast( local_tex_obj->getImage() ); + if (image_gl) + { + S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + + if (image_gl->hasGLTexture()) + { + *gl_bytes += bytes; + } + } + } + } + } +} + +// virtual void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready, U32 index) { - if (!isIndexLocalTexture(type)) return; - - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ; - if(!tex) - { - return ; - } - - S32 desired_discard = isSelf() ? 0 : 2; - LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); - if (!local_tex_obj) - { - if (type >= TEX_NUM_INDICES) - { - LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL; - return; - } - LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type); - if (!gAgentWearables.getViewerWearable(wearable_type,index)) - { - // no wearable is loaded, cannot set the texture. - return; - } - gAgentWearables.addLocalTextureObject(wearable_type,type,index); - local_tex_obj = getLocalTextureObject(type,index); - if (!local_tex_obj) - { - LL_ERRS() << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << LL_ENDL; - return; - } - - LLViewerTexLayerSet *layer_set = getLayerSet(type); - if (layer_set) - { - layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index)); - } - - } - if (!baked_version_ready) - { - if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady()) - { - local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1); - } - if (tex->getID() != IMG_DEFAULT_AVATAR) - { - if (local_tex_obj->getDiscard() > desired_discard) - { - S32 tex_discard = tex->getDiscardLevel(); - if (tex_discard >= 0 && tex_discard <= desired_discard) - { - local_tex_obj->setDiscard(tex_discard); - if (isSelf()) - { - requestLayerSetUpdate(type); - if (isEditingAppearance()) - { - LLVisualParamHint::requestHintUpdates(); - } - } - } - else - { - tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL); - } - } - tex->setMinDiscardLevel(desired_discard); - } - } - local_tex_obj->setImage(tex); - local_tex_obj->setID(tex->getID()); - setBakedReady(type,baked_version_ready,index); + if (!isIndexLocalTexture(type)) return; + + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ; + if(!tex) + { + return ; + } + + S32 desired_discard = isSelf() ? 0 : 2; + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + if (type >= TEX_NUM_INDICES) + { + LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL; + return; + } + LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type); + if (!gAgentWearables.getViewerWearable(wearable_type,index)) + { + // no wearable is loaded, cannot set the texture. + return; + } + gAgentWearables.addLocalTextureObject(wearable_type,type,index); + local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + LL_ERRS() << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << LL_ENDL; + return; + } + + LLViewerTexLayerSet *layer_set = getLayerSet(type); + if (layer_set) + { + layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index)); + } + + } + if (!baked_version_ready) + { + if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady()) + { + local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1); + } + if (tex->getID() != IMG_DEFAULT_AVATAR) + { + if (local_tex_obj->getDiscard() > desired_discard) + { + S32 tex_discard = tex->getDiscardLevel(); + if (tex_discard >= 0 && tex_discard <= desired_discard) + { + local_tex_obj->setDiscard(tex_discard); + if (isSelf()) + { + requestLayerSetUpdate(type); + if (isEditingAppearance()) + { + LLVisualParamHint::requestHintUpdates(); + } + } + } + else + { + tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL); + } + } + tex->setMinDiscardLevel(desired_discard); + } + } + local_tex_obj->setImage(tex); + local_tex_obj->setID(tex->getID()); + setBakedReady(type,baked_version_ready,index); } //virtual void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) { - if (!isIndexLocalTexture(type)) return; - LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); - if (local_tex_obj) - { - local_tex_obj->setBakedReady( baked_version_exists ); - } + if (!isIndexLocalTexture(type)) return; + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); + if (local_tex_obj) + { + local_tex_obj->setBakedReady( baked_version_exists ); + } } // virtual void LLVOAvatarSelf::dumpLocalTextures() const { - LL_INFOS() << "Local Textures:" << LL_ENDL; - - /* ETextureIndex baked_equiv[] = { - TEX_UPPER_BAKED, - if (isTextureDefined(baked_equiv[i])) */ - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); - iter != sAvatarDictionary->getTextures().end(); - ++iter) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) - continue; - - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex; - - const std::string &name = texture_dict->mName; - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); - // index is baked texture - index is not relevant. putting in 0 as placeholder - if (isTextureDefined(baked_equiv, 0)) - { + LL_INFOS() << "Local Textures:" << LL_ENDL; + + /* ETextureIndex baked_equiv[] = { + TEX_UPPER_BAKED, + if (isTextureDefined(baked_equiv[i])) */ + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); + iter != sAvatarDictionary->getTextures().end(); + ++iter) + { + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) + continue; + + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex; + + const std::string &name = texture_dict->mName; + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); + // index is baked texture - index is not relevant. putting in 0 as placeholder + if (isTextureDefined(baked_equiv, 0)) + { #if LL_RELEASE_FOR_DOWNLOAD - // End users don't get to trivially see avatar texture IDs, makes textures - // easier to steal. JC - LL_INFOS() << "LocTex " << name << ": Baked " << LL_ENDL; + // End users don't get to trivially see avatar texture IDs, makes textures + // easier to steal. JC + LL_INFOS() << "LocTex " << name << ": Baked " << LL_ENDL; #else - LL_INFOS() << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << LL_ENDL; + LL_INFOS() << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << LL_ENDL; #endif - } - else if (local_tex_obj && local_tex_obj->getImage() != NULL) - { - if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR) - { - LL_INFOS() << "LocTex " << name << ": None" << LL_ENDL; - } - else - { - LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); - - LL_INFOS() << "LocTex " << name << ": " - << "Discard " << image->getDiscardLevel() << ", " - << "(" << image->getWidth() << ", " << image->getHeight() << ") " + } + else if (local_tex_obj && local_tex_obj->getImage() != NULL) + { + if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR) + { + LL_INFOS() << "LocTex " << name << ": None" << LL_ENDL; + } + else + { + LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); + + LL_INFOS() << "LocTex " << name << ": " + << "Discard " << image->getDiscardLevel() << ", " + << "(" << image->getWidth() << ", " << image->getHeight() << ") " #if !LL_RELEASE_FOR_DOWNLOAD - // End users don't get to trivially see avatar texture IDs, - // makes textures easier to steal - << image->getID() << " " + // End users don't get to trivially see avatar texture IDs, + // makes textures easier to steal + << image->getID() << " " #endif - << "Priority: " << image->getMaxVirtualSize() - << LL_ENDL; - } - } - else - { - LL_INFOS() << "LocTex " << name << ": No LLViewerTexture" << LL_ENDL; - } - } + << "Priority: " << image->getMaxVirtualSize() + << LL_ENDL; + } + } + else + { + LL_INFOS() << "LocTex " << name << ": No LLViewerTexture" << LL_ENDL; + } + } } //----------------------------------------------------------------------------- -// static +// static // onLocalTextureLoaded() //----------------------------------------------------------------------------- void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - LLAvatarTexData *data = (LLAvatarTexData *)userdata; - LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID); - if (self) - { - // We should only be handling local textures for ourself - self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata); - } - // ensure data is cleaned up - if (final || !success) - { - delete data; - } + LLAvatarTexData *data = (LLAvatarTexData *)userdata; + LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID); + if (self) + { + // We should only be handling local textures for ourself + self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata); + } + // ensure data is cleaned up + if (final || !success) + { + delete data; + } } -/*virtual*/ void LLVOAvatarSelf::setImage(const U8 te, LLViewerTexture *imagep, const U32 index) +/*virtual*/ void LLVOAvatarSelf::setImage(const U8 te, LLViewerTexture *imagep, const U32 index) { - if (isIndexLocalTexture((ETextureIndex)te)) - { - setLocalTexture((ETextureIndex)te, imagep, FALSE ,index); - } - else - { - setTEImage(te,imagep); - } + if (isIndexLocalTexture((ETextureIndex)te)) + { + setLocalTexture((ETextureIndex)te, imagep, FALSE ,index); + } + else + { + setTEImage(te,imagep); + } } /*virtual*/ LLViewerTexture* LLVOAvatarSelf::getImage(const U8 te, const U32 index) const { - if (isIndexLocalTexture((ETextureIndex)te)) - { - return getLocalTextureGL((ETextureIndex)te,index); - } - else - { - return getTEImage(te); - } + if (isIndexLocalTexture((ETextureIndex)te)) + { + return getLocalTextureGL((ETextureIndex)te,index); + } + else + { + return getTEImage(te); + } } // static void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() { - S32 gl_bytes = 0; - gAgentAvatarp->getLocalTextureByteCount(&gl_bytes); - LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL; + S32 gl_bytes = 0; + gAgentAvatarp->getLocalTextureByteCount(&gl_bytes); + LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL; } bool LLVOAvatarSelf::getIsCloud() const { - // Let people know why they're clouded without spamming them into oblivion. - bool do_warn = false; - static LLTimer time_since_notice; - F32 update_freq = 30.0; - if (time_since_notice.getElapsedTimeF32() > update_freq) - { - time_since_notice.reset(); - do_warn = true; - } - - // do we have our body parts? - S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE); - S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR); - S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES); - S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN); - if (!shape_count || !hair_count || !eye_count || !skin_count) - { - if (do_warn) - { - LL_INFOS() << "Self is clouded due to missing one or more required body parts: " - << (shape_count ? "" : "SHAPE ") - << (hair_count ? "" : "HAIR ") - << (eye_count ? "" : "EYES ") - << (skin_count ? "" : "SKIN ") - << LL_ENDL; - } - return true; - } - - if (!isTextureDefined(TEX_HAIR, 0)) - { - if (do_warn) - { - LL_INFOS() << "Self is clouded because of no hair texture" << LL_ENDL; - } - return true; - } - - if (!mPreviousFullyLoaded) - { - if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) && - (!isTextureDefined(TEX_LOWER_BAKED, 0))) - { - if (do_warn) - { - LL_INFOS() << "Self is clouded because lower textures not baked" << LL_ENDL; - } - return true; - } - - if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) && - (!isTextureDefined(TEX_UPPER_BAKED, 0))) - { - if (do_warn) - { - LL_INFOS() << "Self is clouded because upper textures not baked" << LL_ENDL; - } - return true; - } - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (i == BAKED_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) - continue; - - const BakedTextureData& texture_data = mBakedTextureDatas[i]; - if (!isTextureDefined(texture_data.mTextureIndex, 0)) - continue; - - // Check for the case that texture is defined but not sufficiently loaded to display anything. - const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 ); - if (!baked_img || !baked_img->hasGLTexture()) - { - if (do_warn) - { - LL_INFOS() << "Self is clouded because texture at index " << i - << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << LL_ENDL; - } - return true; - } - } - - LL_DEBUGS() << "Avatar de-clouded" << LL_ENDL; - } - return false; + // Let people know why they're clouded without spamming them into oblivion. + bool do_warn = false; + static LLTimer time_since_notice; + F32 update_freq = 30.0; + if (time_since_notice.getElapsedTimeF32() > update_freq) + { + time_since_notice.reset(); + do_warn = true; + } + + // do we have our body parts? + S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE); + S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR); + S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES); + S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN); + if (!shape_count || !hair_count || !eye_count || !skin_count) + { + if (do_warn) + { + LL_INFOS() << "Self is clouded due to missing one or more required body parts: " + << (shape_count ? "" : "SHAPE ") + << (hair_count ? "" : "HAIR ") + << (eye_count ? "" : "EYES ") + << (skin_count ? "" : "SKIN ") + << LL_ENDL; + } + return true; + } + + if (!isTextureDefined(TEX_HAIR, 0)) + { + if (do_warn) + { + LL_INFOS() << "Self is clouded because of no hair texture" << LL_ENDL; + } + return true; + } + + if (!mPreviousFullyLoaded) + { + if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) && + (!isTextureDefined(TEX_LOWER_BAKED, 0))) + { + if (do_warn) + { + LL_INFOS() << "Self is clouded because lower textures not baked" << LL_ENDL; + } + return true; + } + + if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) && + (!isTextureDefined(TEX_UPPER_BAKED, 0))) + { + if (do_warn) + { + LL_INFOS() << "Self is clouded because upper textures not baked" << LL_ENDL; + } + return true; + } + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (i == BAKED_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) + continue; + + const BakedTextureData& texture_data = mBakedTextureDatas[i]; + if (!isTextureDefined(texture_data.mTextureIndex, 0)) + continue; + + // Check for the case that texture is defined but not sufficiently loaded to display anything. + const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 ); + if (!baked_img || !baked_img->hasGLTexture()) + { + if (do_warn) + { + LL_INFOS() << "Self is clouded because texture at index " << i + << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << LL_ENDL; + } + return true; + } + } + + LL_DEBUGS() << "Avatar de-clouded" << LL_ENDL; + } + return false; } /*static*/ void LLVOAvatarSelf::debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - if (gAgentAvatarp.notNull()) - { - gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); - } + if (gAgentAvatarp.notNull()) + { + gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); + } } void LLVOAvatarSelf::debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - LLAvatarTexData *data = (LLAvatarTexData *)userdata; - if (!data) - { - return; - } - - ETextureIndex index = data->mIndex; - - if (index < 0 || index >= TEX_NUM_INDICES) - { - return; - } - - if (discard_level >=0 && discard_level <= MAX_DISCARD_LEVEL) // ignore discard level -1, as it means we have no data. - { - mDebugTextureLoadTimes[(U32)index][(U32)discard_level] = mDebugSelfLoadTimer.getElapsedTimeF32(); - } - if (final) - { - delete data; - } + LLAvatarTexData *data = (LLAvatarTexData *)userdata; + if (!data) + { + return; + } + + ETextureIndex index = data->mIndex; + + if (index < 0 || index >= TEX_NUM_INDICES) + { + return; + } + + if (discard_level >=0 && discard_level <= MAX_DISCARD_LEVEL) // ignore discard level -1, as it means we have no data. + { + mDebugTextureLoadTimes[(U32)index][(U32)discard_level] = mDebugSelfLoadTimer.getElapsedTimeF32(); + } + if (final) + { + delete data; + } } void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL finished) { - U32 done = 0; - if (finished) - { - done = 1; - } - mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32(); + U32 done = 0; + if (finished) + { + done = 1; + } + mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32(); } const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const { - std::ostringstream outbuf; + std::ostringstream outbuf; LLWearableType *wr_inst = LLWearableType::getInstance(); - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = - sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const EBakedTextureIndex baked_index = baked_iter->first; - if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) - { - outbuf << "baked_index: " << baked_index << "\n"; - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName; - outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n"; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - if (wearable_count > 0) - { - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - outbuf << " " << wr_inst->getTypeName(wearable_type) << " " << wearable_index << ":"; - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index); - if (local_tex_obj) - { - LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); - if (tex_index >= 0 - && local_tex_obj->getID() != IMG_DEFAULT_AVATAR - && !image->isMissingAsset()) - { - outbuf << " id: " << image->getID() - << " refs: " << image->getNumRefs() - << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index) - << " discard: " << image->getDiscardLevel() - << " desired: " << image->getDesiredDiscardLevel() - << " vsize: " << image->getMaxVirtualSize() - << " ts: " << image->getTextureState() - << " bl: " << image->getBoostLevel() - << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there. - << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded" - << " mvs: " << image->getMaxVirtualSize() - << " mvsc: " << image->getMaxVirtualSizeResetCounter() - << " mem: " << image->getTextureMemory(); - } - } - outbuf << "\n"; - } - } - } - break; - } - } - return outbuf.str(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = + sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const EBakedTextureIndex baked_index = baked_iter->first; + if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) + { + outbuf << "baked_index: " << baked_index << "\n"; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName; + outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n"; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + if (wearable_count > 0) + { + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + outbuf << " " << wr_inst->getTypeName(wearable_type) << " " << wearable_index << ":"; + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index); + if (local_tex_obj) + { + LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); + if (tex_index >= 0 + && local_tex_obj->getID() != IMG_DEFAULT_AVATAR + && !image->isMissingAsset()) + { + outbuf << " id: " << image->getID() + << " refs: " << image->getNumRefs() + << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index) + << " discard: " << image->getDiscardLevel() + << " desired: " << image->getDesiredDiscardLevel() + << " vsize: " << image->getMaxVirtualSize() + << " ts: " << image->getTextureState() + << " bl: " << image->getBoostLevel() + << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there. + << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded" + << " mvs: " << image->getMaxVirtualSize() + << " mvsc: " << image->getMaxVirtualSizeResetCounter() + << " mem: " << image->getTextureMemory(); + } + } + outbuf << "\n"; + } + } + } + break; + } + } + return outbuf.str(); } void LLVOAvatarSelf::dumpAllTextures() const { - std::string vd_text = "Local textures per baked index and wearable:\n"; - for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; - const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); - if (!layerset) continue; - const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); - if (!layerset_buffer) continue; - vd_text += verboseDebugDumpLocalTextureDataInfo(layerset); - } - LL_DEBUGS("Avatar") << vd_text << LL_ENDL; + std::string vd_text = "Local textures per baked index and wearable:\n"; + for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; + const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); + if (!layerset) continue; + const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); + if (!layerset_buffer) continue; + vd_text += verboseDebugDumpLocalTextureDataInfo(layerset); + } + LL_DEBUGS("Avatar") << vd_text << LL_ENDL; } const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const { - std::string text=""; + std::string text=""; LLWearableType *wr_inst = LLWearableType::getInstance(); - text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset)); - - /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) - return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ - for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const EBakedTextureIndex baked_index = baked_iter->first; - if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; - text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str()); - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - if (wearable_count > 0) - { - text += wr_inst->getTypeName(wearable_type) + ":"; - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index); - std::string discard_str = llformat("%d ",discard_level); - text += llformat("%d ",discard_level); - } - } - } - text += ")"; - break; - } - } - return text; + text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset)); + + /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) + return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const EBakedTextureIndex baked_index = baked_iter->first; + if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str()); + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + if (wearable_count > 0) + { + text += wr_inst->getTypeName(wearable_type) + ":"; + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index); + std::string discard_str = llformat("%d ",discard_level); + text += llformat("%d ",discard_level); + } + } + } + text += ")"; + break; + } + } + return text; } const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const { - std::string text; - const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); - BOOL is_texture_final = TRUE; - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - ++local_tex_iter) - { - const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); - const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); - for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) - { - is_texture_final &= (getLocalDiscardLevel(*local_tex_iter, wearable_index) <= (S32)(override_tex_discard_level)); - } - } - text += llformat("%s:%d ",baked_dict->mName.c_str(),is_texture_final); - } - return text; + std::string text; + const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i); + BOOL is_texture_final = TRUE; + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + const ETextureIndex tex_index = *local_tex_iter; + const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + is_texture_final &= (getLocalDiscardLevel(*local_tex_iter, wearable_index) <= (S32)(override_tex_discard_level)); + } + } + text += llformat("%s:%d ",baked_dict->mName.c_str(),is_texture_final); + } + return text; } void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url) @@ -2241,7 +2241,7 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url) msg["nearby"][rez_status_name] = rez_counts[rez_stat]; } - // std::vector bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake"); + // std::vector bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake"); std::vector by_fields; by_fields.push_back("timer_name"); by_fields.push_back("completed"); @@ -2280,233 +2280,233 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url) bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send) { - const F32 AV_METRICS_INTERVAL_QA = 30.0; - F32 send_period = 300.0; + const F32 AV_METRICS_INTERVAL_QA = 30.0; + F32 send_period = 300.0; + + static LLCachedControl qa_mode_metrics(gSavedSettings,"QAModeMetrics"); + if (qa_mode_metrics) + { + send_period = AV_METRICS_INTERVAL_QA; + } - static LLCachedControl qa_mode_metrics(gSavedSettings,"QAModeMetrics"); - if (qa_mode_metrics) - { - send_period = AV_METRICS_INTERVAL_QA; - } + if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) + { + // Stats for completed phases have been getting logged as they + // complete. This will give us stats for any timers that + // haven't finished as of the metric's being sent. - if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) - { - // Stats for completed phases have been getting logged as they - // complete. This will give us stats for any timers that - // haven't finished as of the metric's being sent. - - if (force_send) - { - LLVOAvatar::logPendingPhasesAllAvatars(); - } - sendViewerAppearanceChangeMetrics(); - } + if (force_send) + { + LLVOAvatar::logPendingPhasesAllAvatars(); + } + sendViewerAppearanceChangeMetrics(); + } - return false; + return false; } void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record) { - mPendingTimerRecords.push_back(record); + mPendingTimerRecords.push_back(record); } bool operator<(const LLSD& a, const LLSD& b) { - std::ostringstream aout, bout; - aout << LLSDNotationStreamer(a); - bout << LLSDNotationStreamer(b); - std::string astring = aout.str(); - std::string bstring = bout.str(); + std::ostringstream aout, bout; + aout << LLSDNotationStreamer(a); + bout << LLSDNotationStreamer(b); + std::string astring = aout.str(); + std::string bstring = bout.str(); - return astring < bstring; + return astring < bstring; } // Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field. LLSD summarize_by_buckets(std::vector in_records, - std::vector by_fields, - std::string val_field) -{ - LLSD result = LLSD::emptyArray(); - std::map accum; - for (std::vector::iterator in_record_iter = in_records.begin(); - in_record_iter != in_records.end(); ++in_record_iter) - { - LLSD& record = *in_record_iter; - LLSD key; - for (std::vector::iterator field_iter = by_fields.begin(); - field_iter != by_fields.end(); ++field_iter) - { - const std::string& field = *field_iter; - key[field] = record[field]; - } - LLViewerStats::StatsAccumulator& stats = accum[key]; - F32 value = record[val_field].asReal(); - stats.push(value); - } - for (std::map::iterator accum_it = accum.begin(); - accum_it != accum.end(); ++accum_it) - { - LLSD out_record = accum_it->first; - out_record["stats"] = accum_it->second.asLLSD(); - result.append(out_record); - } - return result; + std::vector by_fields, + std::string val_field) +{ + LLSD result = LLSD::emptyArray(); + std::map accum; + for (std::vector::iterator in_record_iter = in_records.begin(); + in_record_iter != in_records.end(); ++in_record_iter) + { + LLSD& record = *in_record_iter; + LLSD key; + for (std::vector::iterator field_iter = by_fields.begin(); + field_iter != by_fields.end(); ++field_iter) + { + const std::string& field = *field_iter; + key[field] = record[field]; + } + LLViewerStats::StatsAccumulator& stats = accum[key]; + F32 value = record[val_field].asReal(); + stats.push(value); + } + for (std::map::iterator accum_it = accum.begin(); + accum_it != accum.end(); ++accum_it) + { + LLSD out_record = accum_it->first; + out_record["stats"] = accum_it->second.asLLSD(); + result.append(out_record); + } + return result; } void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics() { - std::string caps_url; - if (getRegion()) - { - // runway - change here to activate. - caps_url = getRegion()->getCapability("ViewerMetrics"); - } - if (!caps_url.empty()) - { + std::string caps_url; + if (getRegion()) + { + // runway - change here to activate. + caps_url = getRegion()->getCapability("ViewerMetrics"); + } + if (!caps_url.empty()) + { LLCoros::instance().launch("LLVOAvatarSelf::appearanceChangeMetricsCoro", boost::bind(&LLVOAvatarSelf::appearanceChangeMetricsCoro, this, caps_url)); - mTimeSinceLastRezMessage.reset(); - } + mTimeSinceLastRezMessage.reset(); + } } const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const { - if (canGrabBakedTexture(baked_index)) - { - ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index); - if (tex_index == TEX_NUM_INDICES) - { - return LLUUID::null; - } - return getTEImage( tex_index )->getID(); - } - return LLUUID::null; + if (canGrabBakedTexture(baked_index)) + { + ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return LLUUID::null; + } + return getTEImage( tex_index )->getID(); + } + return LLUUID::null; } BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const { - ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index); - if (tex_index == TEX_NUM_INDICES) - { - return FALSE; - } - // Check if the texture hasn't been baked yet. - if (!isTextureDefined(tex_index, 0)) - { - LL_DEBUGS() << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << LL_ENDL; - return FALSE; - } - - if (gAgent.isGodlikeWithoutAdminMenuFakery()) - return TRUE; - - // Check permissions of textures that show up in the - // baked texture. We don't want people copying people's - // work via baked textures. - - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index); - for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); - iter != baked_dict->mLocalTextures.end(); - ++iter) - { - const ETextureIndex t_index = (*iter); - LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index); - U32 count = gAgentWearables.getWearableCount(wearable_type); - LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL; - - for (U32 wearable_index = 0; wearable_index < count; ++wearable_index) - { - LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index); - if (wearable) - { - const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index); - const LLUUID& texture_id = texture->getID(); - if (texture_id != IMG_DEFAULT_AVATAR) - { - // Search inventory for this texture. - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(texture_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - BOOL can_grab = FALSE; - LL_DEBUGS() << "item count for asset " << texture_id << ": " << items.size() << LL_ENDL; - if (items.size()) - { - // search for full permissions version - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp->getIsFullPerm()) - { - can_grab = TRUE; - break; - } - } - } - if (!can_grab) return FALSE; - } - } - } - } - - return TRUE; + ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return FALSE; + } + // Check if the texture hasn't been baked yet. + if (!isTextureDefined(tex_index, 0)) + { + LL_DEBUGS() << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << LL_ENDL; + return FALSE; + } + + if (gAgent.isGodlikeWithoutAdminMenuFakery()) + return TRUE; + + // Check permissions of textures that show up in the + // baked texture. We don't want people copying people's + // work via baked textures. + + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index); + for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); + iter != baked_dict->mLocalTextures.end(); + ++iter) + { + const ETextureIndex t_index = (*iter); + LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index); + U32 count = gAgentWearables.getWearableCount(wearable_type); + LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL; + + for (U32 wearable_index = 0; wearable_index < count; ++wearable_index) + { + LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index); + if (wearable) + { + const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index); + const LLUUID& texture_id = texture->getID(); + if (texture_id != IMG_DEFAULT_AVATAR) + { + // Search inventory for this texture. + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(texture_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + BOOL can_grab = FALSE; + LL_DEBUGS() << "item count for asset " << texture_id << ": " << items.size() << LL_ENDL; + if (items.size()) + { + // search for full permissions version + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp->getIsFullPerm()) + { + can_grab = TRUE; + break; + } + } + } + if (!can_grab) return FALSE; + } + } + } + } + + return TRUE; } void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep, - F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked) -{ - if (!isIndexLocalTexture(type)) return; - - // Sunshine - ignoring covered_by_baked will force local textures - // to always load. Fix for SH-4001 and many related issues. Do - // not restore this without some more targetted fix for the local - // textures failing to load issue. - //if (!covered_by_baked) - { - if (imagep->getID() != IMG_DEFAULT_AVATAR) - { - imagep->setNoDelete(); - if (imagep->getDiscardLevel() != 0) - { - F32 desired_pixels; - desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); - - imagep->setBoostLevel(getAvatarBoostLevel()); - imagep->resetTextureStats(); - imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); - imagep->addTextureStats( desired_pixels / texel_area_ratio ); - imagep->forceUpdateBindStats() ; - if (imagep->getDiscardLevel() < 0) - { - mHasGrey = TRUE; // for statistics gathering - } - } - } - else - { - // texture asset is missing - mHasGrey = TRUE; // for statistics gathering - } - } + F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked) +{ + if (!isIndexLocalTexture(type)) return; + + // Sunshine - ignoring covered_by_baked will force local textures + // to always load. Fix for SH-4001 and many related issues. Do + // not restore this without some more targetted fix for the local + // textures failing to load issue. + //if (!covered_by_baked) + { + if (imagep->getID() != IMG_DEFAULT_AVATAR) + { + imagep->setNoDelete(); + if (imagep->getDiscardLevel() != 0) + { + F32 desired_pixels; + desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); + + imagep->setBoostLevel(getAvatarBoostLevel()); + imagep->resetTextureStats(); + imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); + imagep->addTextureStats( desired_pixels / texel_area_ratio ); + imagep->forceUpdateBindStats() ; + if (imagep->getDiscardLevel() < 0) + { + mHasGrey = TRUE; // for statistics gathering + } + } + } + else + { + // texture asset is missing + mHasGrey = TRUE; // for statistics gathering + } + } } LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const { - LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i); - LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index); - if (wearable) - { - return wearable->getLocalTextureObject(i); - } + LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index); + if (wearable) + { + return wearable->getLocalTextureObject(i); + } - return NULL; + return NULL; } //----------------------------------------------------------------------------- @@ -2515,119 +2515,119 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDe //----------------------------------------------------------------------------- ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (layerset == mBakedTextureDatas[i].mTexLayerSet ) - { - return mBakedTextureDatas[i].mTextureIndex; - } - } - llassert(0); - return TEX_HEAD_BAKED; + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (layerset == mBakedTextureDatas[i].mTexLayerSet ) + { + return mBakedTextureDatas[i].mTextureIndex; + } + } + llassert(0); + return TEX_HEAD_BAKED; } // FIXME: This is not called consistently. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { - if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) - { - return ; - } - - const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); - LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << LL_ENDL; - LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << LL_ENDL; - LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << LL_ENDL; - LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << LL_ENDL; - LL_DEBUGS("Avatar") << "\t Load time for each texture: " << LL_ENDL; - for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) - { - std::stringstream out; - out << "\t\t (" << i << ") "; - U32 j=0; - for (j=0; j <= MAX_DISCARD_LEVEL; j++) - { - out << "\t"; - S32 load_time = (S32)mDebugTextureLoadTimes[i][j]; - if (load_time == -1) - { - out << "*"; - if (j == 0) - break; - } - else - { - out << load_time; - } - } - - // Don't print out non-existent textures. - if (j != 0) - { - LL_DEBUGS("Avatar") << out.str() << LL_ENDL; - } - } - LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << LL_ENDL; - for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) - { - LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL; - } - - for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); - baked_iter != sAvatarDictionary->getBakedTextures().end(); - ++baked_iter) - { - const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; - const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); - if (!layerset) continue; - const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); - if (!layerset_buffer) continue; - LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << LL_ENDL; - } - - dumpAllTextures(); + if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) + { + return ; + } + + const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); + LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << LL_ENDL; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << LL_ENDL; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << LL_ENDL; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << LL_ENDL; + LL_DEBUGS("Avatar") << "\t Load time for each texture: " << LL_ENDL; + for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) + { + std::stringstream out; + out << "\t\t (" << i << ") "; + U32 j=0; + for (j=0; j <= MAX_DISCARD_LEVEL; j++) + { + out << "\t"; + S32 load_time = (S32)mDebugTextureLoadTimes[i][j]; + if (load_time == -1) + { + out << "*"; + if (j == 0) + break; + } + else + { + out << load_time; + } + } + + // Don't print out non-existent textures. + if (j != 0) + { + LL_DEBUGS("Avatar") << out.str() << LL_ENDL; + } + } + LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << LL_ENDL; + for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) + { + LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL; + } + + for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin(); + baked_iter != sAvatarDictionary->getBakedTextures().end(); + ++baked_iter) + { + const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; + const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); + if (!layerset) continue; + const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); + if (!layerset_buffer) continue; + LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << LL_ENDL; + } + + dumpAllTextures(); } void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const { - LL_DEBUGS("Avatar") - << avString() - << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) - << LL_ENDL; + LL_DEBUGS("Avatar") + << avString() + << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) + << LL_ENDL; } void LLVOAvatarSelf::reportAvatarRezTime() const { - // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow. + // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow. } // SUNSHINE CLEANUP - not clear we need any of this, may be sufficient to request server appearance in llviewermenu.cpp:handle_rebake_textures() void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) { - LL_INFOS() << "TAT: forced full rebake. " << LL_ENDL; + LL_INFOS() << "TAT: forced full rebake. " << LL_ENDL; - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex; - LLViewerTexLayerSet* layer_set = getLayerSet(baked_index); - if (layer_set) - { - if (slam_for_debug) - { - layer_set->setUpdatesEnabled(TRUE); - } + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex; + LLViewerTexLayerSet* layer_set = getLayerSet(baked_index); + if (layer_set) + { + if (slam_for_debug) + { + layer_set->setUpdatesEnabled(TRUE); + } - invalidateComposite(layer_set); - add(LLStatViewer::TEX_REBAKES, 1); - } - else - { - LL_WARNS() << "TAT: NO LAYER SET FOR " << (S32)baked_index << LL_ENDL; - } - } + invalidateComposite(layer_set); + add(LLStatViewer::TEX_REBAKES, 1); + } + else + { + LL_WARNS() << "TAT: NO LAYER SET FOR " << (S32)baked_index << LL_ENDL; + } + } - // Don't know if this is needed - updateMeshTextures(); + // Don't know if this is needed + updateMeshTextures(); } //----------------------------------------------------------------------------- @@ -2635,21 +2635,21 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) //----------------------------------------------------------------------------- void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index ) { - /* switch(index) - case LOCTEX_UPPER_BODYPAINT: - case LOCTEX_UPPER_SHIRT: - if( mUpperBodyLayerSet ) - mUpperBodyLayerSet->requestUpdate(); */ - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index); - if (!texture_dict) - return; - if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) - return; - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - if (mBakedTextureDatas[baked_index].mTexLayerSet) - { - mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate(); - } + /* switch(index) + case LOCTEX_UPPER_BODYPAINT: + case LOCTEX_UPPER_SHIRT: + if( mUpperBodyLayerSet ) + mUpperBodyLayerSet->requestUpdate(); */ + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index); + if (!texture_dict) + return; + if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) + return; + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + if (mBakedTextureDatas[baked_index].mTexLayerSet) + { + mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate(); + } } LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const @@ -2675,7 +2675,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) return mHeadLayerSet; */ if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES) { - return getTexLayerSet(baked_index); + return getTexLayerSet(baked_index); } return NULL; } @@ -2686,54 +2686,54 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) // static void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) { - if (isAgentAvatarValid()) - { - LLUIUsage::instance().logCommand("Avatar.CustomizeStart"); - if (!gAgentAvatarp->mEndCustomizeCallback.get()) - { - gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy; - } - - gAgentAvatarp->mIsEditingAppearance = true; - gAgentAvatarp->mUseLocalAppearance = true; - - if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) - { - gAgentCamera.changeCameraToCustomizeAvatar(); - } - - gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates - gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh. - gAgentAvatarp->updateTextures(); // call updateTextureStats - } + if (isAgentAvatarValid()) + { + LLUIUsage::instance().logCommand("Avatar.CustomizeStart"); + if (!gAgentAvatarp->mEndCustomizeCallback.get()) + { + gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy; + } + + gAgentAvatarp->mIsEditingAppearance = true; + gAgentAvatarp->mUseLocalAppearance = true; + + if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) + { + gAgentCamera.changeCameraToCustomizeAvatar(); + } + + gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates + gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh. + gAgentAvatarp->updateTextures(); // call updateTextureStats + } } // static void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch) { - if (isAgentAvatarValid()) - { - gAgentAvatarp->mIsEditingAppearance = false; - gAgentAvatarp->invalidateAll(); + if (isAgentAvatarValid()) + { + gAgentAvatarp->mIsEditingAppearance = false; + gAgentAvatarp->invalidateAll(); - if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) - { - gAgentCamera.changeCameraToDefault(); - gAgentCamera.resetView(); - } + if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) + { + gAgentCamera.changeCameraToDefault(); + gAgentCamera.resetView(); + } - // Dereferencing the previous callback will cause - // updateAppearanceFromCOF to be called, whenever all refs - // have resolved. - gAgentAvatarp->mEndCustomizeCallback = NULL; - } + // Dereferencing the previous callback will cause + // updateAppearanceFromCOF to be called, whenever all refs + // have resolved. + gAgentAvatarp->mEndCustomizeCallback = NULL; + } } // virtual bool LLVOAvatarSelf::shouldRenderRigged() const { - return gAgent.needsRenderAvatar(); + return gAgent.needsRenderAvatar(); } // HACK: this will null out the avatar's local texture IDs before the TE message is sent @@ -2743,39 +2743,39 @@ bool LLVOAvatarSelf::shouldRenderRigged() const // This will involve further refactoring that is too risky for the initial release of 2.0. bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const { - LLUUID texture_id[TEX_NUM_INDICES]; - // pack away current TEs to make sure we don't send them out - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); - iter != sAvatarDictionary->getTextures().end(); - ++iter) - { - const ETextureIndex index = iter->first; - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - if (!texture_dict->mIsBakedTexture) - { - LLTextureEntry* entry = getTE((U8) index); - texture_id[index] = entry->getID(); - entry->setID(IMG_DEFAULT_AVATAR); - } - } - - bool success = packTEMessage(mesgsys); - - // unpack TEs to make sure we don't re-trigger a bake - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); - iter != sAvatarDictionary->getTextures().end(); - ++iter) - { - const ETextureIndex index = iter->first; - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - if (!texture_dict->mIsBakedTexture) - { - LLTextureEntry* entry = getTE((U8) index); - entry->setID(texture_id[index]); - } - } - - return success; + LLUUID texture_id[TEX_NUM_INDICES]; + // pack away current TEs to make sure we don't send them out + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); + iter != sAvatarDictionary->getTextures().end(); + ++iter) + { + const ETextureIndex index = iter->first; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + if (!texture_dict->mIsBakedTexture) + { + LLTextureEntry* entry = getTE((U8) index); + texture_id[index] = entry->getID(); + entry->setID(IMG_DEFAULT_AVATAR); + } + } + + bool success = packTEMessage(mesgsys); + + // unpack TEs to make sure we don't re-trigger a bake + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin(); + iter != sAvatarDictionary->getTextures().end(); + ++iter) + { + const ETextureIndex index = iter->first; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + if (!texture_dict->mIsBakedTexture) + { + LLTextureEntry* entry = getTE((U8) index); + entry->setID(texture_id[index]); + } + } + + return success; } //------------------------------------------------------------------------ @@ -2783,37 +2783,37 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const //------------------------------------------------------------------------ void LLVOAvatarSelf::sendHoverHeight() const { - std::string url = gAgent.getRegionCapability("AgentPreferences"); + std::string url = gAgent.getRegionCapability("AgentPreferences"); - if (!url.empty()) - { - LLSD update = LLSD::emptyMap(); - const LLVector3& hover_offset = getHoverOffset(); - update["hover_height"] = hover_offset[2]; + if (!url.empty()) + { + LLSD update = LLSD::emptyMap(); + const LLVector3& hover_offset = getHoverOffset(); + update["hover_height"] = hover_offset[2]; - LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL; + LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL; // *TODO: - this class doesn't really do anything, could just use a base - // class responder if nothing else gets added. + // class responder if nothing else gets added. // (comment from removed Responder) - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update, + LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update, "Hover height sent to sim", "Hover height not sent to sim"); - mLastHoverOffsetSent = hover_offset; - } + mLastHoverOffsetSent = hover_offset; + } } void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_update) { - if (getHoverOffset() != hover_offset) - { - LL_INFOS("Avatar") << avString() << " setting hover due to change " << hover_offset[2] << LL_ENDL; - LLVOAvatar::setHoverOffset(hover_offset, send_update); - } - if (send_update && (hover_offset != mLastHoverOffsetSent)) - { - LL_INFOS("Avatar") << avString() << " sending hover due to change " << hover_offset[2] << LL_ENDL; - sendHoverHeight(); - } + if (getHoverOffset() != hover_offset) + { + LL_INFOS("Avatar") << avString() << " setting hover due to change " << hover_offset[2] << LL_ENDL; + LLVOAvatar::setHoverOffset(hover_offset, send_update); + } + if (send_update && (hover_offset != mLastHoverOffsetSent)) + { + LL_INFOS("Avatar") << avString() << " sending hover due to change " << hover_offset[2] << LL_ENDL; + sendHoverHeight(); + } } //------------------------------------------------------------------------ @@ -2821,9 +2821,9 @@ void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_upd //------------------------------------------------------------------------ BOOL LLVOAvatarSelf::needsRenderBeam() { - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); + BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); LLViewerObject* objp = LLToolGrab::getInstance()->getEditingObject(); if (objp // might need to be "!objp ||" instead of "objp &&". && (objp->isAttachment() || objp->isAvatar())) @@ -2832,65 +2832,65 @@ BOOL LLVOAvatarSelf::needsRenderBeam() // attachments or avatars is_touching_or_grabbing = FALSE; } - return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); + return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); } // static void LLVOAvatarSelf::deleteScratchTextures() { - for(std::map< LLGLenum, LLGLuint*>::iterator it = sScratchTexNames.begin(), end_it = sScratchTexNames.end(); - it != end_it; - ++it) - { - LLImageGL::deleteTextures(1, (U32 *)it->second ); - stop_glerror(); - } + for(std::map< LLGLenum, LLGLuint*>::iterator it = sScratchTexNames.begin(), end_it = sScratchTexNames.end(); + it != end_it; + ++it) + { + LLImageGL::deleteTextures(1, (U32 *)it->second ); + stop_glerror(); + } - if( sScratchTexBytes.value() ) - { - LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL; + if( sScratchTexBytes.value() ) + { + LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL; - delete_and_clear(sScratchTexNames); - sScratchTexBytes = S32Bytes(0); - } + delete_and_clear(sScratchTexNames); + sScratchTexBytes = S32Bytes(0); + } } -// static +// static void LLVOAvatarSelf::dumpScratchTextureByteCount() { - LL_INFOS() << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << LL_ENDL; + LL_INFOS() << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << LL_ENDL; } void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) { - apr_file_t* file = outfile.getFileHandle(); - if (!file) - { - return; - } + apr_file_t* file = outfile.getFileHandle(); + if (!file) + { + return; + } + - - apr_file_printf( file, "\n\n" ); + apr_file_printf( file, "\n\n" ); - LLWearableData *wd = getWearableData(); + LLWearableData *wd = getWearableData(); LLWearableType *wr_inst = LLWearableType::getInstance(); - for (S32 type = 0; type < LLWearableType::WT_COUNT; type++) - { - const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type); - for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++) - { - LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j); - apr_file_printf( file, "\n\t \n", - type_name.c_str(), wearable->getName().c_str() ); - LLWearable::visual_param_vec_t v_params; - wearable->getVisualParams(v_params); - for (LLWearable::visual_param_vec_t::iterator it = v_params.begin(); - it != v_params.end(); ++it) - { - LLVisualParam *param = *it; - dump_visual_param(file, param, param->getWeight()); - } - } - } - apr_file_printf( file, "\n\n" ); + for (S32 type = 0; type < LLWearableType::WT_COUNT; type++) + { + const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type); + for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++) + { + LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j); + apr_file_printf( file, "\n\t \n", + type_name.c_str(), wearable->getName().c_str() ); + LLWearable::visual_param_vec_t v_params; + wearable->getVisualParams(v_params); + for (LLWearable::visual_param_vec_t::iterator it = v_params.begin(); + it != v_params.end(); ++it) + { + LLVisualParam *param = *it; + dump_visual_param(file, param, param->getWeight()); + } + } + } + apr_file_printf( file, "\n\n" ); } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 8dad833eaa..bfac68b68f 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvocache.cpp * @brief Cache of objects on the viewer. * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,14 +45,14 @@ BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE; const S32 ENTRY_HEADER_SIZE = 6 * sizeof(S32); const S32 MAX_ENTRY_BODY_SIZE = 10000; -BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) +BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { - return apr_file->read(src, n_bytes) == n_bytes ; + return apr_file->read(src, n_bytes) == n_bytes ; } -BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) +BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) { - return apr_file->write(src, n_bytes) == n_bytes ; + return apr_file->write(src, n_bytes) == n_bytes ; } // Material Override Cache needs a version label, so we can upgrade this later. @@ -62,7 +62,7 @@ const int LLGLTFOverrideCacheEntry::VERSION = 1; bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - + llassert(data.has("local_id")); llassert(data.has("object_id")); llassert(data.has("region_handle_x") && data.has("region_handle_y")); @@ -156,57 +156,57 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const //--------------------------------------------------------------------------- LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) -: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), - mLocalID(local_id), - mCRC(crc), - mUpdateFlags(-1), - mHitCount(0), - mDupeCount(0), - mCRCChangeCount(0), - mState(INACTIVE), - mSceneContrib(0.f), - mValid(TRUE), - mParentID(0), - mBSphereRadius(-1.0f) -{ - mBuffer = new U8[dp.getBufferSize()]; - mDP.assignBuffer(mBuffer, dp.getBufferSize()); - mDP = dp; +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mLocalID(local_id), + mCRC(crc), + mUpdateFlags(-1), + mHitCount(0), + mDupeCount(0), + mCRCChangeCount(0), + mState(INACTIVE), + mSceneContrib(0.f), + mValid(TRUE), + mParentID(0), + mBSphereRadius(-1.0f) +{ + mBuffer = new U8[dp.getBufferSize()]; + mDP.assignBuffer(mBuffer, dp.getBufferSize()); + mDP = dp; } LLVOCacheEntry::LLVOCacheEntry() -: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), - mLocalID(0), - mCRC(0), - mUpdateFlags(-1), - mHitCount(0), - mDupeCount(0), - mCRCChangeCount(0), - mBuffer(NULL), - mState(INACTIVE), - mSceneContrib(0.f), - mValid(TRUE), - mParentID(0), - mBSphereRadius(-1.0f) -{ - mDP.assignBuffer(mBuffer, 0); +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mLocalID(0), + mCRC(0), + mUpdateFlags(-1), + mHitCount(0), + mDupeCount(0), + mCRCChangeCount(0), + mBuffer(NULL), + mState(INACTIVE), + mSceneContrib(0.f), + mValid(TRUE), + mParentID(0), + mBSphereRadius(-1.0f) +{ + mDP.assignBuffer(mBuffer, 0); } LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) -: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), - mBuffer(NULL), - mUpdateFlags(-1), - mState(INACTIVE), - mSceneContrib(0.f), - mValid(FALSE), - mParentID(0), - mBSphereRadius(-1.0f) -{ - S32 size = -1; - BOOL success; +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mBuffer(NULL), + mUpdateFlags(-1), + mState(INACTIVE), + mSceneContrib(0.f), + mValid(FALSE), + mParentID(0), + mBSphereRadius(-1.0f) +{ + S32 size = -1; + BOOL success; static U8 data_buffer[ENTRY_HEADER_SIZE]; - mDP.assignBuffer(mBuffer, 0); + mDP.assignBuffer(mBuffer, 0); success = check_read(apr_file, (void *)data_buffer, ENTRY_HEADER_SIZE); if (success) @@ -218,216 +218,216 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) memcpy(&mCRCChangeCount, data_buffer + (4 * sizeof(U32)), sizeof(S32)); memcpy(&size, data_buffer + (5 * sizeof(U32)), sizeof(S32)); - // Corruption in the cache entries - if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1)) - { - // We've got a bogus size, skip reading it. - // We won't bother seeking, because the rest of this file - // is likely bogus, and will be tossed anyway. - LL_WARNS() << "Bogus cache entry, size " << size << ", aborting!" << LL_ENDL; - success = FALSE; - } - } - if(success && size > 0) - { - mBuffer = new U8[size]; - success = check_read(apr_file, mBuffer, size); - - if(success) - { - mDP.assignBuffer(mBuffer, size); - } - else - { - // Improve logging around vocache - LL_WARNS() << "Error loading cache entry for " << mLocalID << ", size " << size << " aborting!" << LL_ENDL; - delete[] mBuffer ; - mBuffer = NULL ; - } - } - - if(!success) - { - mLocalID = 0; - mCRC = 0; - mHitCount = 0; - mDupeCount = 0; - mCRCChangeCount = 0; - mBuffer = NULL; - mEntry = NULL; - mState = INACTIVE; - } + // Corruption in the cache entries + if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1)) + { + // We've got a bogus size, skip reading it. + // We won't bother seeking, because the rest of this file + // is likely bogus, and will be tossed anyway. + LL_WARNS() << "Bogus cache entry, size " << size << ", aborting!" << LL_ENDL; + success = FALSE; + } + } + if(success && size > 0) + { + mBuffer = new U8[size]; + success = check_read(apr_file, mBuffer, size); + + if(success) + { + mDP.assignBuffer(mBuffer, size); + } + else + { + // Improve logging around vocache + LL_WARNS() << "Error loading cache entry for " << mLocalID << ", size " << size << " aborting!" << LL_ENDL; + delete[] mBuffer ; + mBuffer = NULL ; + } + } + + if(!success) + { + mLocalID = 0; + mCRC = 0; + mHitCount = 0; + mDupeCount = 0; + mCRCChangeCount = 0; + mBuffer = NULL; + mEntry = NULL; + mState = INACTIVE; + } } LLVOCacheEntry::~LLVOCacheEntry() { - mDP.freeBuffer(); + mDP.freeBuffer(); } void LLVOCacheEntry::updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp) -{ - if(mCRC != crc) - { - mCRC = crc; - mCRCChangeCount++; - } - - mDP.freeBuffer(); - - llassert_always(dp.getBufferSize() > 0); - mBuffer = new U8[dp.getBufferSize()]; - mDP.assignBuffer(mBuffer, dp.getBufferSize()); - mDP = dp; +{ + if(mCRC != crc) + { + mCRC = crc; + mCRCChangeCount++; + } + + mDP.freeBuffer(); + + llassert_always(dp.getBufferSize() > 0); + mBuffer = new U8[dp.getBufferSize()]; + mDP.assignBuffer(mBuffer, dp.getBufferSize()); + mDP = dp; } -void LLVOCacheEntry::setParentID(U32 id) +void LLVOCacheEntry::setParentID(U32 id) { - if(mParentID != id) - { - removeAllChildren(); - mParentID = id; - } + if(mParentID != id) + { + removeAllChildren(); + mParentID = id; + } } void LLVOCacheEntry::removeAllChildren() { - if(mChildrenList.empty()) - { - return; - } + if(mChildrenList.empty()) + { + return; + } - for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter) - { - (*iter)->setParentID(0); - } - mChildrenList.clear(); + for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter) + { + (*iter)->setParentID(0); + } + mChildrenList.clear(); - return; + return; } -//virtual +//virtual void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry) { - if(!entry && mDP.getBufferSize() > 0) - { - LLUUID fullid; - LLViewerObject::unpackUUID(&mDP, fullid, "ID"); - - LLViewerObject* obj = gObjectList.findObject(fullid); - if(obj && obj->mDrawable) - { - entry = obj->mDrawable->getEntry(); - } - } - - LLViewerOctreeEntryData::setOctreeEntry(entry); + if(!entry && mDP.getBufferSize() > 0) + { + LLUUID fullid; + LLViewerObject::unpackUUID(&mDP, fullid, "ID"); + + LLViewerObject* obj = gObjectList.findObject(fullid); + if(obj && obj->mDrawable) + { + entry = obj->mDrawable->getEntry(); + } + } + + LLViewerOctreeEntryData::setOctreeEntry(entry); } void LLVOCacheEntry::setState(U32 state) { - if(state > LOW_BITS) //special states - { - mState |= (HIGH_BITS & state); - return; - } - - // - //otherwise LOW_BITS states - // - clearState(LOW_BITS); - mState |= (LOW_BITS & state); - - if(getState() == ACTIVE) - { - const S32 MIN_INTERVAL = 64 + sMinFrameRange; - U32 last_visible = getVisible(); - - setVisible(); - - U32 cur_visible = getVisible(); - if(cur_visible - last_visible > MIN_INTERVAL || - cur_visible < MIN_INTERVAL) - { - mLastCameraUpdated = 0; //reset - } - else - { - mLastCameraUpdated = LLViewerRegion::sLastCameraUpdated; - } - } + if(state > LOW_BITS) //special states + { + mState |= (HIGH_BITS & state); + return; + } + + // + //otherwise LOW_BITS states + // + clearState(LOW_BITS); + mState |= (LOW_BITS & state); + + if(getState() == ACTIVE) + { + const S32 MIN_INTERVAL = 64 + sMinFrameRange; + U32 last_visible = getVisible(); + + setVisible(); + + U32 cur_visible = getVisible(); + if(cur_visible - last_visible > MIN_INTERVAL || + cur_visible < MIN_INTERVAL) + { + mLastCameraUpdated = 0; //reset + } + else + { + mLastCameraUpdated = LLViewerRegion::sLastCameraUpdated; + } + } } void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) { - llassert(entry != NULL); - llassert(entry->getParentID() == mLocalID); - llassert(entry->getEntry() != NULL); - - if(!entry || !entry->getEntry() || entry->getParentID() != mLocalID) - { - return; - } - - mChildrenList.insert(entry); - - //update parent bbox - if(getEntry() != NULL && isState(INACTIVE)) - { - updateParentBoundingInfo(entry); - resetVisible(); - } + llassert(entry != NULL); + llassert(entry->getParentID() == mLocalID); + llassert(entry->getEntry() != NULL); + + if(!entry || !entry->getEntry() || entry->getParentID() != mLocalID) + { + return; + } + + mChildrenList.insert(entry); + + //update parent bbox + if(getEntry() != NULL && isState(INACTIVE)) + { + updateParentBoundingInfo(entry); + resetVisible(); + } } - + void LLVOCacheEntry::removeChild(LLVOCacheEntry* entry) { - entry->setParentID(0); + entry->setParentID(0); - vocache_entry_set_t::iterator iter = mChildrenList.find(entry); - if(iter != mChildrenList.end()) - { - mChildrenList.erase(iter); - } + vocache_entry_set_t::iterator iter = mChildrenList.find(entry); + if(iter != mChildrenList.end()) + { + mChildrenList.erase(iter); + } } //remove the first child, and return it. LLVOCacheEntry* LLVOCacheEntry::getChild() { - LLVOCacheEntry* child = NULL; - vocache_entry_set_t::iterator iter = mChildrenList.begin(); - if(iter != mChildrenList.end()) - { - child = *iter; - mChildrenList.erase(iter); - } + LLVOCacheEntry* child = NULL; + vocache_entry_set_t::iterator iter = mChildrenList.begin(); + if(iter != mChildrenList.end()) + { + child = *iter; + mChildrenList.erase(iter); + } - return child; + return child; } LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP() { - if (mDP.getBufferSize() == 0) - { - //LL_INFOS() << "Not getting cache entry, invalid!" << LL_ENDL; - return NULL; - } - - return &mDP; + if (mDP.getBufferSize() == 0) + { + //LL_INFOS() << "Not getting cache entry, invalid!" << LL_ENDL; + return NULL; + } + + return &mDP; } void LLVOCacheEntry::recordHit() { - mHitCount++; + mHitCount++; } void LLVOCacheEntry::dump() const { - LL_INFOS() << "local " << mLocalID - << " crc " << mCRC - << " hits " << mHitCount - << " dupes " << mDupeCount - << " change " << mCRCChangeCount - << LL_ENDL; + LL_INFOS() << "local " << mLocalID + << " crc " << mCRC + << " hits " << mHitCount + << " dupes " << mDupeCount + << " change " << mCRCChangeCount + << LL_ENDL; } S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const @@ -452,34 +452,34 @@ S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const } #ifndef LL_TEST -//static +//static void LLVOCacheEntry::updateDebugSettings() { - static LLFrameTimer timer; - if(timer.getElapsedTimeF32() < 1.0f) //update frequency once per second. - { - return; - } - timer.reset(); - - //objects within the view frustum whose visible area is greater than this threshold will be loaded - static LLCachedControl front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); - sFrontPixelThreshold = front_pixel_threshold; - - //objects out of the view frustum whose visible area is greater than this threshold will remain loaded - static LLCachedControl rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold"); - sRearPixelThreshold = rear_pixel_threshold; - sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. - - //make parameters adaptive to memory usage - //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB - static LLCachedControl low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); - static LLCachedControl high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); - - LLMemory::updateMemoryInfo() ; - U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); + static LLFrameTimer timer; + if(timer.getElapsedTimeF32() < 1.0f) //update frequency once per second. + { + return; + } + timer.reset(); + + //objects within the view frustum whose visible area is greater than this threshold will be loaded + static LLCachedControl front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); + sFrontPixelThreshold = front_pixel_threshold; + + //objects out of the view frustum whose visible area is greater than this threshold will remain loaded + static LLCachedControl rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold"); + sRearPixelThreshold = rear_pixel_threshold; + sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. + + //make parameters adaptive to memory usage + //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB + static LLCachedControl low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); + static LLCachedControl high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); + + LLMemory::updateMemoryInfo() ; + U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); static const F32 KB_to_MB = 1.f / 1024.f; - U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB); + U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB); const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB; const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1] @@ -506,613 +506,613 @@ void LLVOCacheEntry::updateDebugSettings() } #endif // LL_TEST -//static +//static F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front) { - F32 threshold; - if(is_front) - { - threshold = sFrontPixelThreshold; - } - else - { - threshold = sRearPixelThreshold; - } - - //object projected area threshold - F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); - F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f; - projection_threshold *= projection_threshold; - - return projection_threshold; + F32 threshold; + if(is_front) + { + threshold = sFrontPixelThreshold; + } + else + { + threshold = sRearPixelThreshold; + } + + //object projected area threshold + F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); + F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f; + projection_threshold *= projection_threshold; + + return projection_threshold; } bool LLVOCacheEntry::isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold) { - LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)getGroup(); - if(!group) - { - return false; - } - - //any visible - bool vis = group->isAnyRecentlyVisible(); - - //not ready to remove - if(!vis) - { - S32 cur_vis = llmax(group->getAnyVisible(), (S32)getVisible()); - vis = (cur_vis + sMinFrameRange > LLViewerOctreeEntryData::getCurrentFrame()); - } - - //within the back sphere - if(!vis && !mParentID && !group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) - { - LLVector4a lookAt; - - if(mBSphereRadius > 0.f) - { - lookAt.setSub(mBSphereCenter, local_camera_origin); - dist_threshold += mBSphereRadius; - } - else - { - lookAt.setSub(getPositionGroup(), camera_origin); - dist_threshold += getBinRadius(); - } - - vis = (lookAt.dot3(lookAt).getF32() < dist_threshold * dist_threshold); - } - - return vis; + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)getGroup(); + if(!group) + { + return false; + } + + //any visible + bool vis = group->isAnyRecentlyVisible(); + + //not ready to remove + if(!vis) + { + S32 cur_vis = llmax(group->getAnyVisible(), (S32)getVisible()); + vis = (cur_vis + sMinFrameRange > LLViewerOctreeEntryData::getCurrentFrame()); + } + + //within the back sphere + if(!vis && !mParentID && !group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { + LLVector4a lookAt; + + if(mBSphereRadius > 0.f) + { + lookAt.setSub(mBSphereCenter, local_camera_origin); + dist_threshold += mBSphereRadius; + } + else + { + lookAt.setSub(getPositionGroup(), camera_origin); + dist_threshold += getBinRadius(); + } + + vis = (lookAt.dot3(lookAt).getF32() < dist_threshold * dist_threshold); + } + + return vis; } void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 max_dist) { - if(!needs_update && getVisible() >= last_update) - { - return; //no need to update - } - - LLVector4a lookAt; - lookAt.setSub(getPositionGroup(), camera_origin); - F32 distance = lookAt.getLength3().getF32(); - distance -= sNearRadius; - - if(distance <= 0.f) - { - //nearby objects, set a large number - const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. - mSceneContrib = LARGE_SCENE_CONTRIBUTION; - } - else - { - F32 rad = getBinRadius(); - max_dist += rad; - - if(distance + sNearRadius < max_dist) - { - mSceneContrib = (rad * rad) / distance; - } - else - { - mSceneContrib = 0.f; //out of draw distance, not to load - } - } - - setVisible(); + if(!needs_update && getVisible() >= last_update) + { + return; //no need to update + } + + LLVector4a lookAt; + lookAt.setSub(getPositionGroup(), camera_origin); + F32 distance = lookAt.getLength3().getF32(); + distance -= sNearRadius; + + if(distance <= 0.f) + { + //nearby objects, set a large number + const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. + mSceneContrib = LARGE_SCENE_CONTRIBUTION; + } + else + { + F32 rad = getBinRadius(); + max_dist += rad; + + if(distance + sNearRadius < max_dist) + { + mSceneContrib = (rad * rad) / distance; + } + else + { + mSceneContrib = 0.f; //out of draw distance, not to load + } + } + + setVisible(); } void LLVOCacheEntry::saveBoundingSphere() { - mBSphereCenter = getPositionGroup(); - mBSphereRadius = getBinRadius(); + mBSphereCenter = getPositionGroup(); + mBSphereRadius = getBinRadius(); } void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale) { - LLVector4a center, newMin, newMax; - center.load3(pos.mV); - LLVector4a size; - size.load3(scale.mV); - newMin.setSub(center, size); - newMax.setAdd(center, size); - - setPositionGroup(center); - setSpatialExtents(newMin, newMax); - - if(getNumOfChildren() > 0) //has children - { - updateParentBoundingInfo(); - } - else - { - setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); - } + LLVector4a center, newMin, newMax; + center.load3(pos.mV); + LLVector4a size; + size.load3(scale.mV); + newMin.setSub(center, size); + newMax.setAdd(center, size); + + setPositionGroup(center); + setSpatialExtents(newMin, newMax); + + if(getNumOfChildren() > 0) //has children + { + updateParentBoundingInfo(); + } + else + { + setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); + } } //make the parent bounding box to include all children void LLVOCacheEntry::updateParentBoundingInfo() { - if(mChildrenList.empty()) - { - return; - } + if(mChildrenList.empty()) + { + return; + } - for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter) - { - updateParentBoundingInfo(*iter); - } - resetVisible(); + for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter) + { + updateParentBoundingInfo(*iter); + } + resetVisible(); } //make the parent bounding box to include this child void LLVOCacheEntry::updateParentBoundingInfo(const LLVOCacheEntry* child) { - const LLVector4a* child_exts = child->getSpatialExtents(); - LLVector4a newMin, newMax; - newMin = child_exts[0]; - newMax = child_exts[1]; - - //move to regional space. - { - const LLVector4a& parent_pos = getPositionGroup(); - newMin.add(parent_pos); - newMax.add(parent_pos); - } - - //update parent's bbox(min, max) - const LLVector4a* parent_exts = getSpatialExtents(); - update_min_max(newMin, newMax, parent_exts[0]); - update_min_max(newMin, newMax, parent_exts[1]); - for(S32 i = 0; i < 4; i++) - { - llclamp(newMin[i], 0.f, 256.f); - llclamp(newMax[i], 0.f, 256.f); - } - setSpatialExtents(newMin, newMax); - - //update parent's bbox center - LLVector4a center; - center.setAdd(newMin, newMax); - center.mul(0.5f); - setPositionGroup(center); - - //update parent's bbox size vector - LLVector4a size; - size.setSub(newMax, newMin); - size.mul(0.5f); - setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); + const LLVector4a* child_exts = child->getSpatialExtents(); + LLVector4a newMin, newMax; + newMin = child_exts[0]; + newMax = child_exts[1]; + + //move to regional space. + { + const LLVector4a& parent_pos = getPositionGroup(); + newMin.add(parent_pos); + newMax.add(parent_pos); + } + + //update parent's bbox(min, max) + const LLVector4a* parent_exts = getSpatialExtents(); + update_min_max(newMin, newMax, parent_exts[0]); + update_min_max(newMin, newMax, parent_exts[1]); + for(S32 i = 0; i < 4; i++) + { + llclamp(newMin[i], 0.f, 256.f); + llclamp(newMax[i], 0.f, 256.f); + } + setSpatialExtents(newMin, newMax); + + //update parent's bbox center + LLVector4a center; + center.setAdd(newMin, newMax); + center.mul(0.5f); + setPositionGroup(center); + + //update parent's bbox size vector + LLVector4a size; + size.setSub(newMax, newMin); + size.mul(0.5f); + setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); } //------------------------------------------------------------------- //LLVOCachePartition //------------------------------------------------------------------- LLVOCacheGroup::~LLVOCacheGroup() { - if(mOcclusionState[LLViewerCamera::CAMERA_WORLD] & ACTIVE_OCCLUSION) - { - ((LLVOCachePartition*)mSpatialPartition)->removeOccluder(this); - } + if(mOcclusionState[LLViewerCamera::CAMERA_WORLD] & ACTIVE_OCCLUSION) + { + ((LLVOCachePartition*)mSpatialPartition)->removeOccluder(this); + } } //virtual void LLVOCacheGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { - if (child->getListenerCount() == 0) - { - new LLVOCacheGroup(child, mSpatialPartition); - } - else - { - OCT_ERRS << "LLVOCacheGroup redundancy detected." << LL_ENDL; - } - - unbound(); - - ((LLViewerOctreeGroup*)child->getListener(0))->unbound(); + if (child->getListenerCount() == 0) + { + new LLVOCacheGroup(child, mSpatialPartition); + } + else + { + OCT_ERRS << "LLVOCacheGroup redundancy detected." << LL_ENDL; + } + + unbound(); + + ((LLViewerOctreeGroup*)child->getListener(0))->unbound(); } LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) { - mLODPeriod = 16; - mRegionp = regionp; - mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; - mBackSlectionEnabled = -1; - mIdleHash = 0; - - for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mCulledTime[i] = 0; - } - mCullHistory = -1; - - new LLVOCacheGroup(mOctree, this); + mLODPeriod = 16; + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mBackSlectionEnabled = -1; + mIdleHash = 0; + + for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mCulledTime[i] = 0; + } + mCullHistory = -1; + + new LLVOCacheGroup(mOctree, this); } LLVOCachePartition::~LLVOCachePartition() { // SL-17276 make sure to do base class cleanup while this instance - // can still be treated as an LLVOCachePartition + // can still be treated as an LLVOCachePartition cleanup(); } bool LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) { - llassert(entry->hasVOCacheEntry()); + llassert(entry->hasVOCacheEntry()); - if(!llfinite(entry->getBinRadius()) || !entry->getPositionGroup().isFinite3()) - { - return false; //data corrupted - } + if(!llfinite(entry->getBinRadius()) || !entry->getPositionGroup().isFinite3()) + { + return false; //data corrupted + } - mOctree->insert(entry); + mOctree->insert(entry); - return true; + return true; } - + void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) { - entry->getVOCacheEntry()->setGroup(NULL); + entry->getVOCacheEntry()->setGroup(NULL); - llassert(!entry->getGroup()); + llassert(!entry->getGroup()); } - + class LLVOCacheOctreeCull : public LLViewerOctreeCull { public: - LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, - const LLVector3& shift, bool use_object_cache_occlusion, F32 pixel_threshold, LLVOCachePartition* part) - : LLViewerOctreeCull(camera), - mRegionp(regionp), - mPartition(part), - mPixelThreshold(pixel_threshold) - { - mLocalShift = shift; - mUseObjectCacheOcclusion = use_object_cache_occlusion; - mNearRadius = LLVOCacheEntry::sNearRadius; - } - - virtual bool earlyFail(LLViewerOctreeGroup* base_group) - { - if( mUseObjectCacheOcclusion && - base_group->getOctreeNode()->getParent()) //never occlusion cull the root node - { - LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; - if(group->needsUpdate()) - { - //needs to issue new occlusion culling check, perform view culling check first. - return false; - } - - group->checkOcclusion(); - - if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) - { - return true; - } - } - - return false; - } - - virtual S32 frustumCheck(const LLViewerOctreeGroup* group) - { + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, + const LLVector3& shift, bool use_object_cache_occlusion, F32 pixel_threshold, LLVOCachePartition* part) + : LLViewerOctreeCull(camera), + mRegionp(regionp), + mPartition(part), + mPixelThreshold(pixel_threshold) + { + mLocalShift = shift; + mUseObjectCacheOcclusion = use_object_cache_occlusion; + mNearRadius = LLVOCacheEntry::sNearRadius; + } + + virtual bool earlyFail(LLViewerOctreeGroup* base_group) + { + if( mUseObjectCacheOcclusion && + base_group->getOctreeNode()->getParent()) //never occlusion cull the root node + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if(group->needsUpdate()) + { + //needs to issue new occlusion culling check, perform view culling check first. + return false; + } + + group->checkOcclusion(); + + if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { + return true; + } + } + + return false; + } + + virtual S32 frustumCheck(const LLViewerOctreeGroup* group) + { #if 0 - S32 res = AABBInRegionFrustumGroupBounds(group); -#else - S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); - if (res != 0) - { - res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift)); - } + S32 res = AABBInRegionFrustumGroupBounds(group); +#else + S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); + if (res != 0) + { + res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift)); + } #endif - return res; - } + return res; + } - virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) - { + virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) + { #if 0 - S32 res = AABBInRegionFrustumObjectBounds(group); + S32 res = AABBInRegionFrustumObjectBounds(group); #else - S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); - if (res != 0) - { - res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift)); - } + S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); + if (res != 0) + { + res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift)); + } #endif - if(res != 0) - { - //check if the objects projection large enough - const LLVector4a* exts = group->getObjectExtents(); - res = checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mNearRadius); - } - - return res; - } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - if( !mUseObjectCacheOcclusion || - !base_group->getOctreeNode()->getParent()) - { - //no occlusion check - if(mRegionp->addVisibleGroup(base_group)) - { - base_group->setVisible(); - } - return; - } - - LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; - if(group->needsUpdate() || !group->isRecentlyVisible())//needs to issue new occlusion culling check. - { - mPartition->addOccluders(group); - group->setVisible(); - return ; //wait for occlusion culling result - } - - if(group->isOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING) || - group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) - { - //keep waiting - group->setVisible(); - } - else - { - if(mRegionp->addVisibleGroup(base_group)) - { - base_group->setVisible(); - } - } - } + if(res != 0) + { + //check if the objects projection large enough + const LLVector4a* exts = group->getObjectExtents(); + res = checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mNearRadius); + } + + return res; + } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + if( !mUseObjectCacheOcclusion || + !base_group->getOctreeNode()->getParent()) + { + //no occlusion check + if(mRegionp->addVisibleGroup(base_group)) + { + base_group->setVisible(); + } + return; + } + + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if(group->needsUpdate() || !group->isRecentlyVisible())//needs to issue new occlusion culling check. + { + mPartition->addOccluders(group); + group->setVisible(); + return ; //wait for occlusion culling result + } + + if(group->isOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING) || + group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) + { + //keep waiting + group->setVisible(); + } + else + { + if(mRegionp->addVisibleGroup(base_group)) + { + base_group->setVisible(); + } + } + } private: - LLVOCachePartition* mPartition; - LLViewerRegion* mRegionp; - LLVector3 mLocalShift; //shift vector from agent space to local region space. - F32 mPixelThreshold; - F32 mNearRadius; - bool mUseObjectCacheOcclusion; + LLVOCachePartition* mPartition; + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. + F32 mPixelThreshold; + F32 mNearRadius; + bool mUseObjectCacheOcclusion; }; //select objects behind camera class LLVOCacheOctreeBackCull : public LLViewerOctreeCull { public: - LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold, bool use_occlusion) - : LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold), mUseObjectCacheOcclusion(use_occlusion) - { - mLocalShift = shift; - mSphereRadius = LLVOCacheEntry::sRearFarRadius; - } - - virtual bool earlyFail(LLViewerOctreeGroup* base_group) - { - if( mUseObjectCacheOcclusion && - base_group->getOctreeNode()->getParent()) //never occlusion cull the root node - { - LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; - - if (group->getOcclusionState() > 0) //occlusion state is not clear. - { - return true; - } - } - - return false; - } - - virtual S32 frustumCheck(const LLViewerOctreeGroup* group) - { - const LLVector4a* exts = group->getExtents(); - return backSphereCheck(exts[0], exts[1]); - } - - virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) - { - const LLVector4a* exts = group->getObjectExtents(); - if(backSphereCheck(exts[0], exts[1])) - { - //check if the objects projection large enough - const LLVector4a* exts = group->getObjectExtents(); - return checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSphereRadius); - } - return false; - } - - virtual void processGroup(LLViewerOctreeGroup* base_group) - { - mRegionp->addVisibleGroup(base_group); - return; - } + LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold, bool use_occlusion) + : LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold), mUseObjectCacheOcclusion(use_occlusion) + { + mLocalShift = shift; + mSphereRadius = LLVOCacheEntry::sRearFarRadius; + } + + virtual bool earlyFail(LLViewerOctreeGroup* base_group) + { + if( mUseObjectCacheOcclusion && + base_group->getOctreeNode()->getParent()) //never occlusion cull the root node + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + + if (group->getOcclusionState() > 0) //occlusion state is not clear. + { + return true; + } + } + + return false; + } + + virtual S32 frustumCheck(const LLViewerOctreeGroup* group) + { + const LLVector4a* exts = group->getExtents(); + return backSphereCheck(exts[0], exts[1]); + } + + virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group) + { + const LLVector4a* exts = group->getObjectExtents(); + if(backSphereCheck(exts[0], exts[1])) + { + //check if the objects projection large enough + const LLVector4a* exts = group->getObjectExtents(); + return checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSphereRadius); + } + return false; + } + + virtual void processGroup(LLViewerOctreeGroup* base_group) + { + mRegionp->addVisibleGroup(base_group); + return; + } private: - //a sphere around the camera origin, including objects behind camera. - S32 backSphereCheck(const LLVector4a& min, const LLVector4a& max) - { - return AABBSphereIntersect(min, max, mCamera->getOrigin() - mLocalShift, mSphereRadius); - } + //a sphere around the camera origin, including objects behind camera. + S32 backSphereCheck(const LLVector4a& min, const LLVector4a& max) + { + return AABBSphereIntersect(min, max, mCamera->getOrigin() - mLocalShift, mSphereRadius); + } private: - F32 mSphereRadius; - LLViewerRegion* mRegionp; - LLVector3 mLocalShift; //shift vector from agent space to local region space. - F32 mPixelThreshold; - bool mUseObjectCacheOcclusion; + F32 mSphereRadius; + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. + F32 mPixelThreshold; + bool mUseObjectCacheOcclusion; }; void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold, bool use_occlusion) { - if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) - { - return; - } - - if(mBackSlectionEnabled < 0) - { - mBackSlectionEnabled = LLVOCacheEntry::sMinFrameRange - 1; - mBackSlectionEnabled = llmax(mBackSlectionEnabled, (S32)1); - } - - if(!mBackSlectionEnabled) - { - return; - } - - //localize the camera - LLVector3 region_agent = mRegionp->getOriginAgent(); - - LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold, use_occlusion); - culler.traverse(mOctree); - - mBackSlectionEnabled--; - if(!mRegionp->getNumOfVisibleGroups()) - { - mBackSlectionEnabled = 0; - } - - return; + if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + return; + } + + if(mBackSlectionEnabled < 0) + { + mBackSlectionEnabled = LLVOCacheEntry::sMinFrameRange - 1; + mBackSlectionEnabled = llmax(mBackSlectionEnabled, (S32)1); + } + + if(!mBackSlectionEnabled) + { + return; + } + + //localize the camera + LLVector3 region_agent = mRegionp->getOriginAgent(); + + LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold, use_occlusion); + culler.traverse(mOctree); + + mBackSlectionEnabled--; + if(!mRegionp->getNumOfVisibleGroups()) + { + mBackSlectionEnabled = 0; + } + + return; } #ifndef LL_TEST S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) { - static LLCachedControl use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); - - if(!LLViewerRegion::sVOCacheCullingEnabled) - { - return 0; - } - if(mRegionp->isPaused()) - { - return 0; - } - - ((LLViewerOctreeGroup*)mOctree->getListener(0))->rebound(); - - if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) - { - return 0; //no need for those cameras. - } - - if(mCulledTime[LLViewerCamera::sCurCameraID] == LLViewerOctreeEntryData::getCurrentFrame()) - { - return 0; //already culled - } - mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); - - if(!mCullHistory && LLViewerRegion::isViewerCameraStatic()) - { - U32 seed = llmax(mLODPeriod >> 1, (U32)4); - if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - if(!(LLViewerOctreeEntryData::getCurrentFrame() % seed)) - { - mIdleHash = (mIdleHash + 1) % seed; - } - } - if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash) - { - mFrontCull = FALSE; - - //process back objects selection - selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), - do_occlusion && use_object_cache_occlusion); - return 0; //nothing changed, reduce frequency of culling - } - } - else - { - mBackSlectionEnabled = -1; //reset it. - } - - //localize the camera - LLVector3 region_agent = mRegionp->getOriginAgent(); - camera.calcRegionFrustumPlanes(region_agent, gAgentCamera.mDrawDistance); - - mFrontCull = TRUE; - LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, - LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), this); - culler.traverse(mOctree); - - if(!sNeedsOcclusionCheck) - { - sNeedsOcclusionCheck = !mOccludedGroups.empty(); - } - return 1; + static LLCachedControl use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); + + if(!LLViewerRegion::sVOCacheCullingEnabled) + { + return 0; + } + if(mRegionp->isPaused()) + { + return 0; + } + + ((LLViewerOctreeGroup*)mOctree->getListener(0))->rebound(); + + if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + return 0; //no need for those cameras. + } + + if(mCulledTime[LLViewerCamera::sCurCameraID] == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //already culled + } + mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); + + if(!mCullHistory && LLViewerRegion::isViewerCameraStatic()) + { + U32 seed = llmax(mLODPeriod >> 1, (U32)4); + if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + if(!(LLViewerOctreeEntryData::getCurrentFrame() % seed)) + { + mIdleHash = (mIdleHash + 1) % seed; + } + } + if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash) + { + mFrontCull = FALSE; + + //process back objects selection + selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), + do_occlusion && use_object_cache_occlusion); + return 0; //nothing changed, reduce frequency of culling + } + } + else + { + mBackSlectionEnabled = -1; //reset it. + } + + //localize the camera + LLVector3 region_agent = mRegionp->getOriginAgent(); + camera.calcRegionFrustumPlanes(region_agent, gAgentCamera.mDrawDistance); + + mFrontCull = TRUE; + LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, + LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), this); + culler.traverse(mOctree); + + if(!sNeedsOcclusionCheck) + { + sNeedsOcclusionCheck = !mOccludedGroups.empty(); + } + return 1; } #endif // LL_TEST void LLVOCachePartition::setCullHistory(BOOL has_new_object) { - mCullHistory <<= 1; - mCullHistory |= has_new_object; + mCullHistory <<= 1; + mCullHistory |= has_new_object; } void LLVOCachePartition::addOccluders(LLViewerOctreeGroup* gp) { - LLVOCacheGroup* group = (LLVOCacheGroup*)gp; + LLVOCacheGroup* group = (LLVOCacheGroup*)gp; - if(!group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) - { - group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); - mOccludedGroups.insert(group); - } + if(!group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) + { + group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + mOccludedGroups.insert(group); + } } void LLVOCachePartition::processOccluders(LLCamera* camera) { - if(mOccludedGroups.empty()) - { - return; - } - if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) - { - return; //no need for those cameras. - } - - LLVector3 region_agent = mRegionp->getOriginAgent(); - LLVector4a shift(region_agent[0], region_agent[1], region_agent[2]); - for(std::set::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) - { - LLVOCacheGroup* group = *iter; - if(group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) - { - group->doOcclusion(camera, &shift); - group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); - } - } - - //safe to clear mOccludedGroups here because only the world camera accesses it. - mOccludedGroups.clear(); - sNeedsOcclusionCheck = FALSE; + if(mOccludedGroups.empty()) + { + return; + } + if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + return; //no need for those cameras. + } + + LLVector3 region_agent = mRegionp->getOriginAgent(); + LLVector4a shift(region_agent[0], region_agent[1], region_agent[2]); + for(std::set::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) + { + LLVOCacheGroup* group = *iter; + if(group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) + { + group->doOcclusion(camera, &shift); + group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + } + } + + //safe to clear mOccludedGroups here because only the world camera accesses it. + mOccludedGroups.clear(); + sNeedsOcclusionCheck = FALSE; } void LLVOCachePartition::resetOccluders() { - if(mOccludedGroups.empty()) - { - return; - } - - for(std::set::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) - { - LLVOCacheGroup* group = *iter; - group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); - } - mOccludedGroups.clear(); - sNeedsOcclusionCheck = FALSE; + if(mOccludedGroups.empty()) + { + return; + } + + for(std::set::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) + { + LLVOCacheGroup* group = *iter; + group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + } + mOccludedGroups.clear(); + sNeedsOcclusionCheck = FALSE; } void LLVOCachePartition::removeOccluder(LLVOCacheGroup* group) { - if(mOccludedGroups.empty()) - { - return; - } - mOccludedGroups.erase(group); + if(mOccludedGroups.empty()) + { + return; + } + mOccludedGroups.erase(group); } //------------------------------------------------------------------- //LLVOCache @@ -1129,148 +1129,148 @@ const char* header_filename = "object.cache"; LLVOCache::LLVOCache(bool read_only) : - mInitialized(false), - mReadOnly(read_only), - mNumEntries(0), - mCacheSize(1), + mInitialized(false), + mReadOnly(read_only), + mNumEntries(0), + mCacheSize(1), mEnabled(true) { #ifndef LL_TEST - mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled"); + mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled"); #endif - mLocalAPRFilePoolp = new LLVolatileAPRPool() ; + mLocalAPRFilePoolp = new LLVolatileAPRPool() ; } LLVOCache::~LLVOCache() { - if(mEnabled) - { - writeCacheHeader(); - clearCacheInMemory(); - } - delete mLocalAPRFilePoolp; + if(mEnabled) + { + writeCacheHeader(); + clearCacheInMemory(); + } + delete mLocalAPRFilePoolp; } void LLVOCache::setDirNames(ELLPath location) { - mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename); - mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname); + mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename); + mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname); } void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) { - if(!mEnabled) - { - LL_WARNS() << "Not initializing cache: Cache is currently disabled." << LL_ENDL; - return ; - } - - if(mInitialized) - { - LL_WARNS() << "Cache already initialized." << LL_ENDL; - return ; - } - mInitialized = true; - - setDirNames(location); - if (!mReadOnly) - { - LLFile::mkdir(mObjectCacheDirName); - } - mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES); - mMetaInfo.mVersion = cache_version; + if(!mEnabled) + { + LL_WARNS() << "Not initializing cache: Cache is currently disabled." << LL_ENDL; + return ; + } + + if(mInitialized) + { + LL_WARNS() << "Cache already initialized." << LL_ENDL; + return ; + } + mInitialized = true; + + setDirNames(location); + if (!mReadOnly) + { + LLFile::mkdir(mObjectCacheDirName); + } + mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES); + mMetaInfo.mVersion = cache_version; #if defined(ADDRESS_SIZE) - U32 expected_address = ADDRESS_SIZE; + U32 expected_address = ADDRESS_SIZE; #else - U32 expected_address = 32; + U32 expected_address = 32; #endif - mMetaInfo.mAddressSize = expected_address; - - readCacheHeader(); - - LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL; - - if( mMetaInfo.mVersion != cache_version - || mMetaInfo.mAddressSize != expected_address) - { - mMetaInfo.mVersion = cache_version ; - mMetaInfo.mAddressSize = expected_address; - if(mReadOnly) //disable cache - { - clearCacheInMemory(); - } - else //delete the current cache if the format does not match. - { - LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL; - removeCache(); - } - } + mMetaInfo.mAddressSize = expected_address; + + readCacheHeader(); + + LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL; + + if( mMetaInfo.mVersion != cache_version + || mMetaInfo.mAddressSize != expected_address) + { + mMetaInfo.mVersion = cache_version ; + mMetaInfo.mAddressSize = expected_address; + if(mReadOnly) //disable cache + { + clearCacheInMemory(); + } + else //delete the current cache if the format does not match. + { + LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL; + removeCache(); + } + } } - -void LLVOCache::removeCache(ELLPath location, bool started) -{ - if(started) - { - removeCache(); - return; - } - - if(mReadOnly) - { - LL_WARNS() << "Not removing cache at " << location << ": Cache is currently in read-only mode." << LL_ENDL; - return ; - } - - LL_INFOS() << "about to remove the object cache due to settings." << LL_ENDL ; - - std::string mask = "*"; - std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname); - LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL; - gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files - LLFile::rmdir(cache_dir); - - clearCacheInMemory(); - mInitialized = false; + +void LLVOCache::removeCache(ELLPath location, bool started) +{ + if(started) + { + removeCache(); + return; + } + + if(mReadOnly) + { + LL_WARNS() << "Not removing cache at " << location << ": Cache is currently in read-only mode." << LL_ENDL; + return ; + } + + LL_INFOS() << "about to remove the object cache due to settings." << LL_ENDL ; + + std::string mask = "*"; + std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname); + LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL; + gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files + LLFile::rmdir(cache_dir); + + clearCacheInMemory(); + mInitialized = false; } -void LLVOCache::removeCache() +void LLVOCache::removeCache() { - if(!mInitialized) - { - //OK to remove cache even it is not initialized. - LL_WARNS() << "Object cache is not initialized yet." << LL_ENDL; - } + if(!mInitialized) + { + //OK to remove cache even it is not initialized. + LL_WARNS() << "Object cache is not initialized yet." << LL_ENDL; + } - if(mReadOnly) - { - LL_WARNS() << "Not clearing object cache: Cache is currently in read-only mode." << LL_ENDL; - return ; - } + if(mReadOnly) + { + LL_WARNS() << "Not clearing object cache: Cache is currently in read-only mode." << LL_ENDL; + return ; + } - std::string mask = "*"; - LL_INFOS() << "Removing object cache at " << mObjectCacheDirName << LL_ENDL; - gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask); + std::string mask = "*"; + LL_INFOS() << "Removing object cache at " << mObjectCacheDirName << LL_ENDL; + gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask); - clearCacheInMemory() ; - writeCacheHeader(); + clearCacheInMemory() ; + writeCacheHeader(); } -void LLVOCache::removeEntry(HeaderEntryInfo* entry) -{ - llassert_always(mInitialized); - if(mReadOnly) - { - return; - } - if(!entry) - { - return; - } - // Bit more tracking of cache creation/destruction. - std::string filename; - getObjectCacheFilename(entry->mHandle, filename); - LL_INFOS() << "Removing entry for region with filename" << filename << LL_ENDL; +void LLVOCache::removeEntry(HeaderEntryInfo* entry) +{ + llassert_always(mInitialized); + if(mReadOnly) + { + return; + } + if(!entry) + { + return; + } + // Bit more tracking of cache creation/destruction. + std::string filename; + getObjectCacheFilename(entry->mHandle, filename); + LL_INFOS() << "Removing entry for region with filename" << filename << LL_ENDL; // make sure corresponding LLViewerRegion also clears its in-memory cache LLViewerRegion* regionp = LLWorld::instance().getRegionFromHandle(entry->mHandle); @@ -1279,53 +1279,53 @@ void LLVOCache::removeEntry(HeaderEntryInfo* entry) regionp->clearVOCacheFromMemory(); } - header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry); - if(iter != mHeaderEntryQueue.end()) - { - mHandleEntryMap.erase(entry->mHandle); - mHeaderEntryQueue.erase(iter); - removeFromCache(entry); - delete entry; + header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry); + if(iter != mHeaderEntryQueue.end()) + { + mHandleEntryMap.erase(entry->mHandle); + mHeaderEntryQueue.erase(iter); + removeFromCache(entry); + delete entry; - mNumEntries = mHandleEntryMap.size() ; - } + mNumEntries = mHandleEntryMap.size() ; + } } -void LLVOCache::removeEntry(U64 handle) +void LLVOCache::removeEntry(U64 handle) { - handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; - if(iter == mHandleEntryMap.end()) //no cache - { - return ; - } - HeaderEntryInfo* entry = iter->second ; - removeEntry(entry) ; + handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; + if(iter == mHandleEntryMap.end()) //no cache + { + return ; + } + HeaderEntryInfo* entry = iter->second ; + removeEntry(entry) ; } void LLVOCache::clearCacheInMemory() { - if(!mHeaderEntryQueue.empty()) - { - for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter) - { - delete *iter ; - } - mHeaderEntryQueue.clear(); - mHandleEntryMap.clear(); - mNumEntries = 0 ; - } + if(!mHeaderEntryQueue.empty()) + { + for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter) + { + delete *iter ; + } + mHeaderEntryQueue.clear(); + mHandleEntryMap.clear(); + mNumEntries = 0 ; + } } -void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename) +void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename) { - U32 region_x, region_y; + U32 region_x, region_y; - grid_from_region_handle(handle, ®ion_x, ®ion_y); - filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname, - llformat(OBJECT_CACHE_FILENAME, region_x, region_y)); + grid_from_region_handle(handle, ®ion_x, ®ion_y); + filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname, + llformat(OBJECT_CACHE_FILENAME, region_x, region_y)); - return ; + return ; } std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle) @@ -1339,238 +1339,238 @@ std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle) void LLVOCache::removeFromCache(HeaderEntryInfo* entry) { - if(mReadOnly) - { - LL_WARNS() << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << LL_ENDL; - return ; - } + if(mReadOnly) + { + LL_WARNS() << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << LL_ENDL; + return ; + } - std::string filename; - getObjectCacheFilename(entry->mHandle, filename); + std::string filename; + getObjectCacheFilename(entry->mHandle, filename); LL_WARNS("GLTF", "VOCache") << "Removing object cache for handle " << entry->mHandle << "Filename: " << filename << LL_ENDL; - LLAPRFile::remove(filename, mLocalAPRFilePoolp); - + LLAPRFile::remove(filename, mLocalAPRFilePoolp); + // Note: `removeFromCache` should take responsibility for cleaning up all cache artefacts specfic to the handle/entry. - // as such this now includes the generic extras + // as such this now includes the generic extras filename = getObjectCacheExtrasFilename(entry->mHandle); LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << entry->mHandle << "Filename: " << filename << LL_ENDL; LLFile::remove(filename); - entry->mTime = INVALID_TIME ; - updateEntry(entry) ; //update the head file. + entry->mTime = INVALID_TIME ; + updateEntry(entry) ; //update the head file. } void LLVOCache::readCacheHeader() { - if(!mEnabled) - { - LL_WARNS() << "Not reading cache header: Cache is currently disabled." << LL_ENDL; - return; - } - - //clear stale info. - clearCacheInMemory(); - - bool success = true ; - if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp)) - { - LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp); - - //read the meta element - success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; - - if(success) - { - HeaderEntryInfo* entry = NULL ; - mNumEntries = 0 ; - U32 num_read = 0 ; - while(num_read++ < MAX_NUM_OBJECT_ENTRIES) - { - if(!entry) - { - entry = new HeaderEntryInfo() ; - } - success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo)); - - if(!success) //failed - { - LL_WARNS() << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << LL_ENDL; - delete entry ; - entry = NULL ; - break ; - } - else if(entry->mTime == INVALID_TIME) - { - continue ; //an empty entry - } - - entry->mIndex = mNumEntries++ ; - mHeaderEntryQueue.insert(entry) ; - mHandleEntryMap[entry->mHandle] = entry ; - entry = NULL ; - } - if(entry) - { - delete entry ; - } - } - - //--------- - //debug code - //---------- - //std::string name ; - //for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) - //{ - // getObjectCacheFilename((*iter)->mHandle, name) ; - // LL_INFOS() << name << LL_ENDL ; - //} - //----------- - } - else - { - writeCacheHeader() ; - } - - if(!success) - { - removeCache() ; //failed to read header, clear the cache - } - else if(mNumEntries >= mCacheSize) - { - purgeEntries(mCacheSize) ; - } - - return ; + if(!mEnabled) + { + LL_WARNS() << "Not reading cache header: Cache is currently disabled." << LL_ENDL; + return; + } + + //clear stale info. + clearCacheInMemory(); + + bool success = true ; + if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp)) + { + LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp); + + //read the meta element + success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; + + if(success) + { + HeaderEntryInfo* entry = NULL ; + mNumEntries = 0 ; + U32 num_read = 0 ; + while(num_read++ < MAX_NUM_OBJECT_ENTRIES) + { + if(!entry) + { + entry = new HeaderEntryInfo() ; + } + success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo)); + + if(!success) //failed + { + LL_WARNS() << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << LL_ENDL; + delete entry ; + entry = NULL ; + break ; + } + else if(entry->mTime == INVALID_TIME) + { + continue ; //an empty entry + } + + entry->mIndex = mNumEntries++ ; + mHeaderEntryQueue.insert(entry) ; + mHandleEntryMap[entry->mHandle] = entry ; + entry = NULL ; + } + if(entry) + { + delete entry ; + } + } + + //--------- + //debug code + //---------- + //std::string name ; + //for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) + //{ + // getObjectCacheFilename((*iter)->mHandle, name) ; + // LL_INFOS() << name << LL_ENDL ; + //} + //----------- + } + else + { + writeCacheHeader() ; + } + + if(!success) + { + removeCache() ; //failed to read header, clear the cache + } + else if(mNumEntries >= mCacheSize) + { + purgeEntries(mCacheSize) ; + } + + return ; } void LLVOCache::writeCacheHeader() { - if (!mEnabled) - { - LL_WARNS() << "Not writing cache header: Cache is currently disabled." << LL_ENDL; - return; - } - - if(mReadOnly) - { - LL_WARNS() << "Not writing cache header: Cache is currently in read-only mode." << LL_ENDL; - return; - } - - bool success = true ; - { - LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); - - //write the meta element - success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; - - - mNumEntries = 0 ; - for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) - { - (*iter)->mIndex = mNumEntries++ ; - success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo)); - } - - mNumEntries = mHeaderEntryQueue.size() ; - if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES) - { - HeaderEntryInfo* entry = new HeaderEntryInfo() ; - entry->mTime = INVALID_TIME ; - for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++) - { - //fill the cache with the default entry. - success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ; - - } - delete entry ; - } - } - - if(!success) - { - clearCacheInMemory() ; - mReadOnly = TRUE ; //disable the cache. - } - return ; + if (!mEnabled) + { + LL_WARNS() << "Not writing cache header: Cache is currently disabled." << LL_ENDL; + return; + } + + if(mReadOnly) + { + LL_WARNS() << "Not writing cache header: Cache is currently in read-only mode." << LL_ENDL; + return; + } + + bool success = true ; + { + LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); + + //write the meta element + success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; + + + mNumEntries = 0 ; + for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) + { + (*iter)->mIndex = mNumEntries++ ; + success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo)); + } + + mNumEntries = mHeaderEntryQueue.size() ; + if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES) + { + HeaderEntryInfo* entry = new HeaderEntryInfo() ; + entry->mTime = INVALID_TIME ; + for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++) + { + //fill the cache with the default entry. + success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ; + + } + delete entry ; + } + } + + if(!success) + { + clearCacheInMemory() ; + mReadOnly = TRUE ; //disable the cache. + } + return ; } BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry) { - LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); - apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; + LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); + apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; - return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; + return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; } // we now return bool to trigger dirty cache // this in turn forces a rewrite after a partial read due to corruption. -bool LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) -{ - if(!mEnabled) - { - LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL; - return true; // no problem we're just read only - } - llassert_always(mInitialized); - - handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; - if(iter == mHandleEntryMap.end()) //no cache - { - LL_WARNS() << "No handle map entry for " << handle << LL_ENDL; - return false; // arguably no a problem, but we'll mark this as dirty anyway. - } - - bool success = true ; - S32 num_entries = 0 ; // lifted out of inner loop. - std::string filename; // lifted out of loop - { - LLUUID cache_id; - getObjectCacheFilename(handle, filename); - LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); - - success = check_read(&apr_file, cache_id.mData, UUID_BYTES); - - if(success) - { - if(cache_id != id) - { - LL_INFOS() << "Cache ID doesn't match for this region, discarding"<< LL_ENDL; - success = false ; - } - - if(success) - { - success = check_read(&apr_file, &num_entries, sizeof(S32)) ; - - if(success) - { - for (S32 i = 0; i < num_entries && apr_file.eof() != APR_EOF; i++) - { - LLPointer entry = new LLVOCacheEntry(&apr_file); - if (!entry->getLocalID()) - { - LL_WARNS() << "Aborting cache file load for " << filename << ", cache file corruption!" << LL_ENDL; - success = false ; - break ; - } - cache_entry_map[entry->getLocalID()] = entry; - } - } - } - } - } - - if(!success) - { - if(cache_entry_map.empty()) - { - removeEntry(iter->second) ; - } - } - - LL_DEBUGS("GLTF", "VOCache") << "Read " << cache_entry_map.size() << " entries from object cache " << filename << ", expected " << num_entries << ", success=" << (success?"True":"False") << LL_ENDL; - return success; +bool LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) +{ + if(!mEnabled) + { + LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL; + return true; // no problem we're just read only + } + llassert_always(mInitialized); + + handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; + if(iter == mHandleEntryMap.end()) //no cache + { + LL_WARNS() << "No handle map entry for " << handle << LL_ENDL; + return false; // arguably no a problem, but we'll mark this as dirty anyway. + } + + bool success = true ; + S32 num_entries = 0 ; // lifted out of inner loop. + std::string filename; // lifted out of loop + { + LLUUID cache_id; + getObjectCacheFilename(handle, filename); + LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); + + success = check_read(&apr_file, cache_id.mData, UUID_BYTES); + + if(success) + { + if(cache_id != id) + { + LL_INFOS() << "Cache ID doesn't match for this region, discarding"<< LL_ENDL; + success = false ; + } + + if(success) + { + success = check_read(&apr_file, &num_entries, sizeof(S32)) ; + + if(success) + { + for (S32 i = 0; i < num_entries && apr_file.eof() != APR_EOF; i++) + { + LLPointer entry = new LLVOCacheEntry(&apr_file); + if (!entry->getLocalID()) + { + LL_WARNS() << "Aborting cache file load for " << filename << ", cache file corruption!" << LL_ENDL; + success = false ; + break ; + } + cache_entry_map[entry->getLocalID()] = entry; + } + } + } + } + } + + if(!success) + { + if(cache_entry_map.empty()) + { + removeEntry(iter->second) ; + } + } + + LL_DEBUGS("GLTF", "VOCache") << "Read " << cache_entry_map.size() << " entries from object cache " << filename << ", expected " << num_entries << ", success=" << (success?"True":"False") << LL_ENDL; + return success; } // We now pass in the cache entry map, so that we can remove entries from extras that are no longer in the primary cache. @@ -1599,7 +1599,7 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac std::string line; std::getline(in, line); - if(!in.good()) + if(!in.good()) { LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL; in.close(); @@ -1609,7 +1609,7 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac // file formats need versions, let's add one. legacy cache files will be considered version 0 // This will make it easier to upgrade/revise later. int versionNumber=0; - if (line.compare(0, LLGLTFOverrideCacheEntry::VERSION_LABEL.length(), LLGLTFOverrideCacheEntry::VERSION_LABEL) == 0) + if (line.compare(0, LLGLTFOverrideCacheEntry::VERSION_LABEL.length(), LLGLTFOverrideCacheEntry::VERSION_LABEL) == 0) { std::string versionStr = line.substr(LLGLTFOverrideCacheEntry::VERSION_LABEL.length()+1); // skip the version label and ':' versionNumber = std::stol(versionStr); @@ -1646,14 +1646,14 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac U32 num_entries; // if removal was enabled during write num_entries might be wrong std::getline(in, line); - if(!in.good()) + if(!in.good()) { LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL; in.close(); removeGenericExtrasForHandle(handle); return; } - try + try { num_entries = std::stol(line); } @@ -1673,7 +1673,7 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac static const U32 max_size = 4096; bool success = LLSDSerialize::deserialize(entry_llsd, in, max_size); // check bool(in) this time since eof is not a failure condition here - if(!success || !in) + if(!success || !in) { LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << " cache patrtial load only." << LL_ENDL; in.close(); @@ -1706,90 +1706,90 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac void LLVOCache::purgeEntries(U32 size) { - LL_DEBUGS("VOCache","GLTF") << "Purging " << size << " entries from cache" << LL_ENDL; - while(mHeaderEntryQueue.size() > size) - { - header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; - HeaderEntryInfo* entry = *iter ; - mHandleEntryMap.erase(entry->mHandle) ; - mHeaderEntryQueue.erase(iter) ; - removeFromCache(entry) ; // This now handles removing extras cache where appropriate. - delete entry; - } - mNumEntries = mHandleEntryMap.size() ; + LL_DEBUGS("VOCache","GLTF") << "Purging " << size << " entries from cache" << LL_ENDL; + while(mHeaderEntryQueue.size() > size) + { + header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; + HeaderEntryInfo* entry = *iter ; + mHandleEntryMap.erase(entry->mHandle) ; + mHeaderEntryQueue.erase(iter) ; + removeFromCache(entry) ; // This now handles removing extras cache where appropriate. + delete entry; + } + mNumEntries = mHandleEntryMap.size() ; } -void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled) -{ - std::string filename; - getObjectCacheFilename(handle, filename); - if(!mEnabled) - { - LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently disabled." << LL_ENDL; - return ; - } - llassert_always(mInitialized); - - if(mReadOnly) - { - LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently in read-only mode." << LL_ENDL; - return ; - } - - HeaderEntryInfo* entry; - handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; - if(iter == mHandleEntryMap.end()) //new entry - { - if(mNumEntries >= mCacheSize - 1) - { - purgeEntries(mCacheSize - 1) ; - } - - entry = new HeaderEntryInfo(); - entry->mHandle = handle ; - entry->mTime = time(NULL) ; - entry->mIndex = mNumEntries++; - mHeaderEntryQueue.insert(entry) ; - mHandleEntryMap[handle] = entry ; - } - else - { - // Update access time. - entry = iter->second ; - - //resort - mHeaderEntryQueue.erase(entry) ; - - entry->mTime = time(NULL) ; - mHeaderEntryQueue.insert(entry) ; - } - - //update cache header - if(!updateEntry(entry)) - { - LL_WARNS() << "Failed to update cache header index " << entry->mIndex << ". " << filename << " handle = " << handle << LL_ENDL; - return ; //update failed. - } - - if(!dirty_cache) - { - LL_WARNS() << "Skipping write to cache for " << filename << " (handle:" << handle << "): cache not dirty" << LL_ENDL; - return ; //nothing changed, no need to update. - } - - //write to cache file - bool success = true ; - { - std::string filename; - getObjectCacheFilename(handle, filename); - LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp); - - success = check_write(&apr_file, (void*)id.mData, UUID_BYTES); - - if(success) - { - S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong - success = check_write(&apr_file, &num_entries, sizeof(S32)); +void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled) +{ + std::string filename; + getObjectCacheFilename(handle, filename); + if(!mEnabled) + { + LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently disabled." << LL_ENDL; + return ; + } + llassert_always(mInitialized); + + if(mReadOnly) + { + LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently in read-only mode." << LL_ENDL; + return ; + } + + HeaderEntryInfo* entry; + handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; + if(iter == mHandleEntryMap.end()) //new entry + { + if(mNumEntries >= mCacheSize - 1) + { + purgeEntries(mCacheSize - 1) ; + } + + entry = new HeaderEntryInfo(); + entry->mHandle = handle ; + entry->mTime = time(NULL) ; + entry->mIndex = mNumEntries++; + mHeaderEntryQueue.insert(entry) ; + mHandleEntryMap[handle] = entry ; + } + else + { + // Update access time. + entry = iter->second ; + + //resort + mHeaderEntryQueue.erase(entry) ; + + entry->mTime = time(NULL) ; + mHeaderEntryQueue.insert(entry) ; + } + + //update cache header + if(!updateEntry(entry)) + { + LL_WARNS() << "Failed to update cache header index " << entry->mIndex << ". " << filename << " handle = " << handle << LL_ENDL; + return ; //update failed. + } + + if(!dirty_cache) + { + LL_WARNS() << "Skipping write to cache for " << filename << " (handle:" << handle << "): cache not dirty" << LL_ENDL; + return ; //nothing changed, no need to update. + } + + //write to cache file + bool success = true ; + { + std::string filename; + getObjectCacheFilename(handle, filename); + LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp); + + success = check_write(&apr_file, (void*)id.mData, UUID_BYTES); + + if(success) + { + S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong + success = check_write(&apr_file, &num_entries, sizeof(S32)); if (success) { const S32 buffer_size = 32768; //should be large enough for couple MAX_ENTRY_BODY_SIZE @@ -1840,15 +1840,15 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: } LL_DEBUGS("VOCache") << "Wrote " << num_entries << " entries to the primary VOCache file " << filename << ". success = " << (success ? "True":"False") << LL_ENDL; } - } - } + } + } - if(!success) - { - removeEntry(entry) ; - } + if(!success) + { + removeEntry(entry) ; + } - return ; + return ; } void LLVOCache::removeGenericExtrasForHandle(U64 handle) @@ -1858,7 +1858,7 @@ void LLVOCache::removeGenericExtrasForHandle(U64 handle) LL_WARNS() << "Not removing cache for handle " << handle << ": Cache is currently in read-only mode." << LL_ENDL; return ; } - + // NOTE: when removing the extras, we must also remove the objects so the simulator will send us a full upddate with the valid overrides auto* entry = mHandleEntryMap[handle]; if (entry) @@ -1906,16 +1906,16 @@ void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LL if(!out.good()) { LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL; - removeGenericExtrasForHandle(handle); + removeGenericExtrasForHandle(handle); return; } - // Because we don't write out all the entries we need to record a placeholder and rewrite this later + // Because we don't write out all the entries we need to record a placeholder and rewrite this later auto num_entries_placeholder = out.tellp(); out << std::setw(10) << std::setfill('0') << 0 << '\n'; if(!out.good()) { LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL; - removeGenericExtrasForHandle(handle); + removeGenericExtrasForHandle(handle); return; } @@ -1932,7 +1932,7 @@ void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LL // worst case we have an extra cache miss. // Note: A null mObjectId is valid when in memory as we might have a data race between GLTF of the object itself. // This remains a valid state to persist as it is consistent with the localid checks on import with the main cache. - // the mObjectId will be updated if/when the local object is updated from the gObject list (due to full update) + // the mObjectId will be updated if/when the local object is updated from the gObject list (due to full update) if(entry.mObjectId.isNull() && pRegion) { gObjectList.getUUIDFromLocal( entry.mObjectId, local_id, pRegion->getHost().getAddress(), pRegion->getHost().getPort() ); diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index d94e79ce1b..b2578085d8 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -1,25 +1,25 @@ -/** +/** * @file llvocache.h * @brief Cache of objects on the viewer. * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -55,189 +55,189 @@ public: U64 mRegionHandle = 0; }; -class LLVOCacheEntry -: public LLViewerOctreeEntryData +class LLVOCacheEntry +: public LLViewerOctreeEntryData { LL_ALIGN_NEW public: - enum - { - //low 16-bit state - INACTIVE = 0x00000000, //not visible - IN_QUEUE = 0x00000001, //in visible queue, object to be created - WAITING = 0x00000002, //object creation request sent - ACTIVE = 0x00000004, //object created, and in rendering pipeline. - - //high 16-bit state - IN_VO_TREE = 0x00010000, //the entry is in the object cache tree. - - LOW_BITS = 0x0000ffff, - HIGH_BITS = 0xffff0000 - }; - - struct CompareVOCacheEntry - { - bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) const - { - F32 lpa = lhs->getSceneContribution(); - F32 rpa = rhs->getSceneContribution(); - - //larger pixel area first - if(lpa > rpa) - { - return true; - } - else if(lpa < rpa) - { - return false; - } - else - { - return lhs < rhs; - } - } - }; + enum + { + //low 16-bit state + INACTIVE = 0x00000000, //not visible + IN_QUEUE = 0x00000001, //in visible queue, object to be created + WAITING = 0x00000002, //object creation request sent + ACTIVE = 0x00000004, //object created, and in rendering pipeline. + + //high 16-bit state + IN_VO_TREE = 0x00010000, //the entry is in the object cache tree. + + LOW_BITS = 0x0000ffff, + HIGH_BITS = 0xffff0000 + }; + + struct CompareVOCacheEntry + { + bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) const + { + F32 lpa = lhs->getSceneContribution(); + F32 rpa = rhs->getSceneContribution(); + + //larger pixel area first + if(lpa > rpa) + { + return true; + } + else if(lpa < rpa) + { + return false; + } + else + { + return lhs < rhs; + } + } + }; protected: - ~LLVOCacheEntry(); + ~LLVOCacheEntry(); public: - LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp); - LLVOCacheEntry(LLAPRFile* apr_file); - LLVOCacheEntry(); - - void updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp); - - void clearState(U32 state) {mState &= ~state;} - bool hasState(U32 state) {return mState & state;} - void setState(U32 state); - bool isState(U32 state) {return (mState & LOW_BITS) == state;} - U32 getState() const {return mState & LOW_BITS;} - - bool isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold); - - U32 getLocalID() const { return mLocalID; } - U32 getCRC() const { return mCRC; } - S32 getHitCount() const { return mHitCount; } - S32 getCRCChangeCount() const { return mCRCChangeCount; } - - void calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 dist_threshold); - void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;} - F32 getSceneContribution() const { return mSceneContrib;} - - void dump() const; - S32 writeToBuffer(U8 *data_buffer) const; - LLDataPackerBinaryBuffer *getDP(); - void recordHit(); - void recordDupe() { mDupeCount++; } - - /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); - - void setParentID(U32 id); - U32 getParentID() const {return mParentID;} - bool isChild() const {return mParentID > 0;} - - void addChild(LLVOCacheEntry* entry); - void removeChild(LLVOCacheEntry* entry); - void removeAllChildren(); - LLVOCacheEntry* getChild(); //remove the first child, and return it. - S32 getNumOfChildren() const {return mChildrenList.size();} - - void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); //called from processing object update message - void updateParentBoundingInfo(); - void saveBoundingSphere(); - - void setValid(BOOL valid = TRUE) {mValid = valid;} - BOOL isValid() const {return mValid;} - - void setUpdateFlags(U32 flags) {mUpdateFlags = flags;} - U32 getUpdateFlags() const {return mUpdateFlags;} - - static void updateDebugSettings(); - static F32 getSquaredPixelThreshold(bool is_front); + LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp); + LLVOCacheEntry(LLAPRFile* apr_file); + LLVOCacheEntry(); + + void updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp); + + void clearState(U32 state) {mState &= ~state;} + bool hasState(U32 state) {return mState & state;} + void setState(U32 state); + bool isState(U32 state) {return (mState & LOW_BITS) == state;} + U32 getState() const {return mState & LOW_BITS;} + + bool isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold); + + U32 getLocalID() const { return mLocalID; } + U32 getCRC() const { return mCRC; } + S32 getHitCount() const { return mHitCount; } + S32 getCRCChangeCount() const { return mCRCChangeCount; } + + void calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 dist_threshold); + void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;} + F32 getSceneContribution() const { return mSceneContrib;} + + void dump() const; + S32 writeToBuffer(U8 *data_buffer) const; + LLDataPackerBinaryBuffer *getDP(); + void recordHit(); + void recordDupe() { mDupeCount++; } + + /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); + + void setParentID(U32 id); + U32 getParentID() const {return mParentID;} + bool isChild() const {return mParentID > 0;} + + void addChild(LLVOCacheEntry* entry); + void removeChild(LLVOCacheEntry* entry); + void removeAllChildren(); + LLVOCacheEntry* getChild(); //remove the first child, and return it. + S32 getNumOfChildren() const {return mChildrenList.size();} + + void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); //called from processing object update message + void updateParentBoundingInfo(); + void saveBoundingSphere(); + + void setValid(BOOL valid = TRUE) {mValid = valid;} + BOOL isValid() const {return mValid;} + + void setUpdateFlags(U32 flags) {mUpdateFlags = flags;} + U32 getUpdateFlags() const {return mUpdateFlags;} + + static void updateDebugSettings(); + static F32 getSquaredPixelThreshold(bool is_front); private: - void updateParentBoundingInfo(const LLVOCacheEntry* child); + void updateParentBoundingInfo(const LLVOCacheEntry* child); public: - typedef std::map > vocache_entry_map_t; - typedef std::set vocache_entry_set_t; - typedef std::set vocache_entry_priority_list_t; + typedef std::map > vocache_entry_map_t; + typedef std::set vocache_entry_set_t; + typedef std::set vocache_entry_priority_list_t; typedef std::unordered_map vocache_gltf_overrides_map_t; - S32 mLastCameraUpdated; + S32 mLastCameraUpdated; protected: - U32 mLocalID; - U32 mParentID; - U32 mCRC; - U32 mUpdateFlags; //receive from sim - S32 mHitCount; - S32 mDupeCount; - S32 mCRCChangeCount; - LLDataPackerBinaryBuffer mDP; - U8 *mBuffer; + U32 mLocalID; + U32 mParentID; + U32 mCRC; + U32 mUpdateFlags; //receive from sim + S32 mHitCount; + S32 mDupeCount; + S32 mCRCChangeCount; + LLDataPackerBinaryBuffer mDP; + U8 *mBuffer; - F32 mSceneContrib; //projected scene contributuion of this object. - U32 mState; //high 16 bits reserved for special use. - vocache_entry_set_t mChildrenList; //children entries in a linked set. + F32 mSceneContrib; //projected scene contributuion of this object. + U32 mState; //high 16 bits reserved for special use. + vocache_entry_set_t mChildrenList; //children entries in a linked set. - BOOL mValid; //if set, this entry is valid, otherwise it is invalid and will be removed. + BOOL mValid; //if set, this entry is valid, otherwise it is invalid and will be removed. - LLVector4a mBSphereCenter; //bounding sphere center - F32 mBSphereRadius; //bounding sphere radius + LLVector4a mBSphereCenter; //bounding sphere center + F32 mBSphereRadius; //bounding sphere radius public: - static U32 sMinFrameRange; - static F32 sNearRadius; - static F32 sRearFarRadius; - static F32 sFrontPixelThreshold; - static F32 sRearPixelThreshold; + static U32 sMinFrameRange; + static F32 sNearRadius; + static F32 sRearFarRadius; + static F32 sFrontPixelThreshold; + static F32 sRearPixelThreshold; }; class LLVOCacheGroup : public LLOcclusionCullingGroup { public: - LLVOCacheGroup(OctreeNode* node, LLViewerOctreePartition* part) : LLOcclusionCullingGroup(node, part){} + LLVOCacheGroup(OctreeNode* node, LLViewerOctreePartition* part) : LLOcclusionCullingGroup(node, part){} - //virtual - void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + //virtual + void handleChildAddition(const OctreeNode* parent, OctreeNode* child); protected: - virtual ~LLVOCacheGroup(); + virtual ~LLVOCacheGroup(); }; class LLVOCachePartition : public LLViewerOctreePartition { public: - LLVOCachePartition(LLViewerRegion* regionp); + LLVOCachePartition(LLViewerRegion* regionp); virtual ~LLVOCachePartition(); - bool addEntry(LLViewerOctreeEntry* entry); - void removeEntry(LLViewerOctreeEntry* entry); - /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion); - void addOccluders(LLViewerOctreeGroup* gp); - void resetOccluders(); - void processOccluders(LLCamera* camera); - void removeOccluder(LLVOCacheGroup* group); + bool addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion); + void addOccluders(LLViewerOctreeGroup* gp); + void resetOccluders(); + void processOccluders(LLCamera* camera); + void removeOccluder(LLVOCacheGroup* group); - void setCullHistory(BOOL has_new_object); + void setCullHistory(BOOL has_new_object); - bool isFrontCull() const {return mFrontCull;} + bool isFrontCull() const {return mFrontCull;} private: - void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff, bool use_occlusion); //select objects behind camera. + void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff, bool use_occlusion); //select objects behind camera. public: - static BOOL sNeedsOcclusionCheck; + static BOOL sNeedsOcclusionCheck; private: - BOOL mFrontCull; //the view frustum cull if set, otherwise is back sphere cull. - U32 mCullHistory; - U32 mCulledTime[LLViewerCamera::NUM_CAMERAS]; - std::set mOccludedGroups; + BOOL mFrontCull; //the view frustum cull if set, otherwise is back sphere cull. + U32 mCullHistory; + U32 mCulledTime[LLViewerCamera::NUM_CAMERAS]; + std::set mOccludedGroups; - S32 mBackSlectionEnabled; //enable to select back objects if > 0. - U32 mIdleHash; + S32 mBackSlectionEnabled; //enable to select back objects if > 0. + U32 mIdleHash; }; // @@ -245,83 +245,83 @@ private: // class LLVOCache : public LLParamSingleton { - LLSINGLETON(LLVOCache, bool read_only); - ~LLVOCache() ; + LLSINGLETON(LLVOCache, bool read_only); + ~LLVOCache() ; private: - struct HeaderEntryInfo - { - HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {} - S32 mIndex; - U64 mHandle ; - U32 mTime ; - }; - - struct HeaderMetaInfo - { - HeaderMetaInfo() : mVersion(0), mAddressSize(0) {} - - U32 mVersion; - U32 mAddressSize; - }; - - struct header_entry_less - { - bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const - { - if(lhs->mTime == rhs->mTime) - { - return lhs < rhs ; - } - - return lhs->mTime < rhs->mTime ; // older entry in front of queue (set) - } - }; - typedef std::set header_entry_queue_t; - typedef std::map handle_entry_map_t; + struct HeaderEntryInfo + { + HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {} + S32 mIndex; + U64 mHandle ; + U32 mTime ; + }; + + struct HeaderMetaInfo + { + HeaderMetaInfo() : mVersion(0), mAddressSize(0) {} + + U32 mVersion; + U32 mAddressSize; + }; + + struct header_entry_less + { + bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const + { + if(lhs->mTime == rhs->mTime) + { + return lhs < rhs ; + } + + return lhs->mTime < rhs->mTime ; // older entry in front of queue (set) + } + }; + typedef std::set header_entry_queue_t; + typedef std::map handle_entry_map_t; public: - // We need this init to be separate from constructor, since we might construct cache, purge it, then init. - void initCache(ELLPath location, U32 size, U32 cache_version); - void removeCache(ELLPath location, bool started = false) ; + // We need this init to be separate from constructor, since we might construct cache, purge it, then init. + void initCache(ELLPath location, U32 size, U32 cache_version); + void removeCache(ELLPath location, bool started = false) ; - bool readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ; - void readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map); + bool readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ; + void readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map); - void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled); + void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled); void writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled); - void removeEntry(U64 handle) ; - void removeGenericExtrasForHandle(U64 handle); + void removeEntry(U64 handle) ; + void removeGenericExtrasForHandle(U64 handle); - U32 getCacheEntries() { return mNumEntries; } - U32 getCacheEntriesMax() { return mCacheSize; } + U32 getCacheEntries() { return mNumEntries; } + U32 getCacheEntriesMax() { return mCacheSize; } private: - void setDirNames(ELLPath location); - // determine the cache filename for the region from the region handle - void getObjectCacheFilename(U64 handle, std::string& filename); + void setDirNames(ELLPath location); + // determine the cache filename for the region from the region handle + void getObjectCacheFilename(U64 handle, std::string& filename); std::string getObjectCacheExtrasFilename(U64 handle); - void removeFromCache(HeaderEntryInfo* entry); - void readCacheHeader(); - void writeCacheHeader(); - void clearCacheInMemory(); - void removeCache() ; - void removeEntry(HeaderEntryInfo* entry) ; - void purgeEntries(U32 size); - BOOL updateEntry(const HeaderEntryInfo* entry); - + void removeFromCache(HeaderEntryInfo* entry); + void readCacheHeader(); + void writeCacheHeader(); + void clearCacheInMemory(); + void removeCache() ; + void removeEntry(HeaderEntryInfo* entry) ; + void purgeEntries(U32 size); + BOOL updateEntry(const HeaderEntryInfo* entry); + private: - bool mEnabled; - bool mInitialized ; - bool mReadOnly ; - HeaderMetaInfo mMetaInfo; - U32 mCacheSize; - U32 mNumEntries; - std::string mHeaderFileName ; - std::string mObjectCacheDirName; - LLVolatileAPRPool* mLocalAPRFilePoolp ; - header_entry_queue_t mHeaderEntryQueue; - handle_entry_map_t mHandleEntryMap; + bool mEnabled; + bool mInitialized ; + bool mReadOnly ; + HeaderMetaInfo mMetaInfo; + U32 mCacheSize; + U32 mNumEntries; + std::string mHeaderFileName ; + std::string mObjectCacheDirName; + LLVolatileAPRPool* mLocalAPRFilePoolp ; + header_entry_queue_t mHeaderEntryQueue; + handle_entry_map_t mHandleEntryMap; }; #endif diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69b9476d38..405d0e59ce 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvosurfacepatch.cpp * @brief Viewer-object derived "surface patch", which is a piece of terrain * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,51 +47,51 @@ F32 LLVOSurfacePatch::sLODFactor = 1.f; LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) - : LLStaticViewerObject(id, pcode, regionp), - mDirtiedPatch(FALSE), - mPool(NULL), - mBaseComp(0), - mPatchp(NULL), - mDirtyTexture(FALSE), - mDirtyTerrain(FALSE), - mLastNorthStride(0), - mLastEastStride(0), - mLastStride(0), - mLastLength(0) + : LLStaticViewerObject(id, pcode, regionp), + mDirtiedPatch(FALSE), + mPool(NULL), + mBaseComp(0), + mPatchp(NULL), + mDirtyTexture(FALSE), + mDirtyTerrain(FALSE), + mLastNorthStride(0), + mLastEastStride(0), + mLastStride(0), + mLastLength(0) { - // Terrain must draw during selection passes so it can block objects behind it. - mbCanSelect = TRUE; - setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility. + // Terrain must draw during selection passes so it can block objects behind it. + mbCanSelect = TRUE; + setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility. } LLVOSurfacePatch::~LLVOSurfacePatch() { - mPatchp = NULL; + mPatchp = NULL; } void LLVOSurfacePatch::markDead() { - if (mPatchp) - { - mPatchp->clearVObj(); - mPatchp = NULL; - } - LLViewerObject::markDead(); + if (mPatchp) + { + mPatchp->clearVObj(); + mPatchp = NULL; + } + LLViewerObject::markDead(); } BOOL LLVOSurfacePatch::isActive() const { - return FALSE; + return FALSE; } void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent) { - mAppAngle = 50; - mPixelArea = 500*500; + mAppAngle = 50; + mPixelArea = 500*500; } @@ -102,145 +102,145 @@ void LLVOSurfacePatch::updateTextures() LLFacePool *LLVOSurfacePatch::getPool() { - mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture()); + mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture()); - return mPool; + return mPool; } LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN); - - mBaseComp = llfloor(mPatchp->getMinComposition()); - S32 min_comp, max_comp, range; - min_comp = llfloor(mPatchp->getMinComposition()); - max_comp = llceil(mPatchp->getMaxComposition()); - range = (max_comp - min_comp); - range++; - if (range > 3) - { - if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) - { - // The top side runs over more - mBaseComp++; - } - range = 3; - } - - LLFacePool *poolp = getPool(); - - mDrawable->addFace(poolp, NULL); - - return mDrawable; + pipeline->allocDrawable(this); + + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN); + + mBaseComp = llfloor(mPatchp->getMinComposition()); + S32 min_comp, max_comp, range; + min_comp = llfloor(mPatchp->getMinComposition()); + max_comp = llceil(mPatchp->getMaxComposition()); + range = (max_comp - min_comp); + range++; + if (range > 3) + { + if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) + { + // The top side runs over more + mBaseComp++; + } + range = 3; + } + + LLFacePool *poolp = getPool(); + + mDrawable->addFace(poolp, NULL); + + return mDrawable; } void LLVOSurfacePatch::updateGL() { - if (mPatchp) - { - LL_PROFILE_ZONE_SCOPED - mPatchp->updateGL(); - } + if (mPatchp) + { + LL_PROFILE_ZONE_SCOPED + mPatchp->updateGL(); + } } BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED; - dirtySpatialGroup(); - - S32 min_comp, max_comp, range; - min_comp = lltrunc(mPatchp->getMinComposition()); - max_comp = lltrunc(ceil(mPatchp->getMaxComposition())); - range = (max_comp - min_comp); - range++; - S32 new_base_comp = lltrunc(mPatchp->getMinComposition()); - if (range > 3) - { - if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) - { - // The top side runs over more - new_base_comp++; - } - range = 3; - } - - // Pick the two closest detail textures for this patch... - // Then create the draw pool for it. - // Actually, should get the average composition instead of the center. - mBaseComp = new_base_comp; - - ////////////////////////// - // - // Figure out the strides - // - // - - U32 patch_width, render_stride, north_stride, east_stride, length; - render_stride = mPatchp->getRenderStride(); - patch_width = mPatchp->getSurface()->getGridsPerPatchEdge(); - - length = patch_width / render_stride; - - if (mPatchp->getNeighborPatch(NORTH)) - { - north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride(); - } - else - { - north_stride = render_stride; - } - - if (mPatchp->getNeighborPatch(EAST)) - { - east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride(); - } - else - { - east_stride = render_stride; - } - - mLastLength = length; - mLastStride = render_stride; - mLastNorthStride = north_stride; - mLastEastStride = east_stride; - - return TRUE; + dirtySpatialGroup(); + + S32 min_comp, max_comp, range; + min_comp = lltrunc(mPatchp->getMinComposition()); + max_comp = lltrunc(ceil(mPatchp->getMaxComposition())); + range = (max_comp - min_comp); + range++; + S32 new_base_comp = lltrunc(mPatchp->getMinComposition()); + if (range > 3) + { + if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) + { + // The top side runs over more + new_base_comp++; + } + range = 3; + } + + // Pick the two closest detail textures for this patch... + // Then create the draw pool for it. + // Actually, should get the average composition instead of the center. + mBaseComp = new_base_comp; + + ////////////////////////// + // + // Figure out the strides + // + // + + U32 patch_width, render_stride, north_stride, east_stride, length; + render_stride = mPatchp->getRenderStride(); + patch_width = mPatchp->getSurface()->getGridsPerPatchEdge(); + + length = patch_width / render_stride; + + if (mPatchp->getNeighborPatch(NORTH)) + { + north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride(); + } + else + { + north_stride = render_stride; + } + + if (mPatchp->getNeighborPatch(EAST)) + { + east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride(); + } + else + { + east_stride = render_stride; + } + + mLastLength = length; + mLastStride = render_stride; + mLastNorthStride = north_stride; + mLastEastStride = east_stride; + + return TRUE; } void LLVOSurfacePatch::updateFaceSize(S32 idx) { LL_PROFILE_ZONE_SCOPED; - if (idx != 0) - { - LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL; - return; - } - - LLFace* facep = mDrawable->getFace(idx); - if (facep) - { - S32 num_vertices = 0; - S32 num_indices = 0; - - if (mLastStride) - { - getGeomSizesMain(mLastStride, num_vertices, num_indices); - getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); - getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); - } - - facep->setSize(num_vertices, num_indices); - } + if (idx != 0) + { + LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL; + return; + } + + LLFace* facep = mDrawable->getFace(idx); + if (facep) + { + S32 num_vertices = 0; + S32 num_indices = 0; + + if (mLastStride) + { + getGeomSizesMain(mLastStride, num_vertices, num_indices); + getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); + getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); + } + + facep->setSize(num_vertices, num_indices); + } } BOOL LLVOSurfacePatch::updateLOD() { - return TRUE; + return TRUE; } void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, @@ -249,7 +249,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &texCoords1p, LLStrider &indicesp) { - LLFace* facep = mDrawable->getFace(0); + LLFace* facep = mDrawable->getFace(0); if (!facep) { return; @@ -257,21 +257,21 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, U32 index_offset = facep->getGeomIndex(); - updateMainGeometry(facep, + updateMainGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, index_offset); - updateNorthGeometry(facep, + updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, index_offset); - updateEastGeometry(facep, + updateEastGeometry(facep, verticesp, normalsp, texCoords0p, @@ -288,99 +288,99 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, LLStrider &indicesp, U32 &index_offset) { - S32 i, j, x, y; - - U32 patch_size, render_stride; - S32 num_vertices, num_indices; - U32 index; - - llassert(mLastStride > 0); - - render_stride = mLastStride; - patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - S32 vert_size = patch_size / render_stride; - - /////////////////////////// - // - // Render the main patch - // - // - - num_vertices = 0; - num_indices = 0; - // First, figure out how many vertices we need... - getGeomSizesMain(render_stride, num_vertices, num_indices); - - if (num_vertices > 0) - { - facep->mCenterAgent = mPatchp->getPointAgent(8, 8); - - // Generate patch points first - for (j = 0; j < vert_size; j++) - { - for (i = 0; i < vert_size; i++) - { - x = i * render_stride; - y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - } - - for (j = 0; j < (vert_size - 1); j++) - { - if (j % 2) - { - for (i = (vert_size - 1); i > 0; i--) - { - index = (i - 1)+ j*vert_size; - *(indicesp++) = index_offset + index; - - index = i + (j+1)*vert_size; - *(indicesp++) = index_offset + index; - - index = (i - 1) + (j+1)*vert_size; - *(indicesp++) = index_offset + index; - - index = (i - 1) + j*vert_size; - *(indicesp++) = index_offset + index; - - index = i + j*vert_size; - *(indicesp++) = index_offset + index; - - index = i + (j+1)*vert_size; - *(indicesp++) = index_offset + index; - } - } - else - { - for (i = 0; i < (vert_size - 1); i++) - { - index = i + j*vert_size; - *(indicesp++) = index_offset + index; - - index = (i + 1) + (j+1)*vert_size; - *(indicesp++) = index_offset + index; - - index = i + (j+1)*vert_size; - *(indicesp++) = index_offset + index; - - index = i + j*vert_size; - *(indicesp++) = index_offset + index; - - index = (i + 1) + j*vert_size; - *(indicesp++) = index_offset + index; - - index = (i + 1) + (j + 1)*vert_size; - *(indicesp++) = index_offset + index; - } - } - } - } - index_offset += num_vertices; + S32 i, j, x, y; + + U32 patch_size, render_stride; + S32 num_vertices, num_indices; + U32 index; + + llassert(mLastStride > 0); + + render_stride = mLastStride; + patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 vert_size = patch_size / render_stride; + + /////////////////////////// + // + // Render the main patch + // + // + + num_vertices = 0; + num_indices = 0; + // First, figure out how many vertices we need... + getGeomSizesMain(render_stride, num_vertices, num_indices); + + if (num_vertices > 0) + { + facep->mCenterAgent = mPatchp->getPointAgent(8, 8); + + // Generate patch points first + for (j = 0; j < vert_size; j++) + { + for (i = 0; i < vert_size; i++) + { + x = i * render_stride; + y = j * render_stride; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + } + + for (j = 0; j < (vert_size - 1); j++) + { + if (j % 2) + { + for (i = (vert_size - 1); i > 0; i--) + { + index = (i - 1)+ j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = (i - 1) + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = (i - 1) + j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + } + } + else + { + for (i = 0; i < (vert_size - 1); i++) + { + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + (j + 1)*vert_size; + *(indicesp++) = index_offset + index; + } + } + } + } + index_offset += num_vertices; } @@ -392,186 +392,186 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, LLStrider &indicesp, U32 &index_offset) { - S32 i, x, y; - - S32 num_vertices; - - U32 render_stride = mLastStride; - S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - S32 length = patch_size / render_stride; - S32 half_length = length / 2; - U32 north_stride = mLastNorthStride; - - /////////////////////////// - // - // Render the north strip - // - // - - // Stride lengths are the same - if (north_stride == render_stride) - { - num_vertices = 2 * length + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; - - // Main patch - for (i = 0; i < length; i++) - { - x = i * render_stride; - y = 16 - render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - // North patch - for (i = 0; i <= length; i++) - { - x = i * render_stride; - y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - - for (i = 0; i < length; i++) - { - // Generate indices - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + length + i + 1; - *(indicesp++) = index_offset + length + i; - - if (i != length - 1) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + i + 1; - *(indicesp++) = index_offset + length + i + 1; - } - } - } - else if (north_stride > render_stride) - { - // North stride is longer (has less vertices) - num_vertices = length + length/2 + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; - - // Iterate through this patch's points - for (i = 0; i < length; i++) - { - x = i * render_stride; - y = 16 - render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - // Iterate through the north patch's points - for (i = 0; i <= length; i+=2) - { - x = i * render_stride; - y = 16; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - - for (i = 0; i < length; i++) - { - if (!(i % 2)) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + i + 1; - *(indicesp++) = index_offset + length + (i/2); - - *(indicesp++) = index_offset + i + 1; - *(indicesp++) = index_offset + length + (i/2) + 1; - *(indicesp++) = index_offset + length + (i/2); - } - else if (i < (length - 1)) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + i + 1; - *(indicesp++) = index_offset + length + (i/2) + 1; - } - } - } - else - { - // North stride is shorter (more vertices) - length = patch_size / north_stride; - half_length = length / 2; - num_vertices = length + half_length + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; - - // Iterate through this patch's points - for (i = 0; i < length; i+=2) - { - x = i * north_stride; - y = 16 - render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - // Iterate through the north patch's points - for (i = 0; i <= length; i++) - { - x = i * north_stride; - y = 16; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - for (i = 0; i < length; i++) - { - if (!(i%2)) - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + i/2; - *(indicesp++) = index_offset + half_length + i + 1; - } - else if (i < (length - 2)) - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + i/2; - *(indicesp++) = index_offset + i/2 + 1; - - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + i/2 + 1; - *(indicesp++) = index_offset + half_length + i + 1; - } - else - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + i/2; - *(indicesp++) = index_offset + half_length + i + 1; - } - } - } - index_offset += num_vertices; + S32 i, x, y; + + S32 num_vertices; + + U32 render_stride = mLastStride; + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / render_stride; + S32 half_length = length / 2; + U32 north_stride = mLastNorthStride; + + /////////////////////////// + // + // Render the north strip + // + // + + // Stride lengths are the same + if (north_stride == render_stride) + { + num_vertices = 2 * length + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Main patch + for (i = 0; i < length; i++) + { + x = i * render_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + // North patch + for (i = 0; i <= length; i++) + { + x = i * render_stride; + y = 16; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + + for (i = 0; i < length; i++) + { + // Generate indices + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i + 1; + *(indicesp++) = index_offset + length + i; + + if (i != length - 1) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + i + 1; + } + } + } + else if (north_stride > render_stride) + { + // North stride is longer (has less vertices) + num_vertices = length + length/2 + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i++) + { + x = i * render_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + // Iterate through the north patch's points + for (i = 0; i <= length; i+=2) + { + x = i * render_stride; + y = 16; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + + for (i = 0; i < length; i++) + { + if (!(i % 2)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2); + + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2) + 1; + *(indicesp++) = index_offset + length + (i/2); + } + else if (i < (length - 1)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2) + 1; + } + } + } + else + { + // North stride is shorter (more vertices) + length = patch_size / north_stride; + half_length = length / 2; + num_vertices = length + half_length + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i+=2) + { + x = i * north_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + // Iterate through the north patch's points + for (i = 0; i <= length; i++) + { + x = i * north_stride; + y = 16; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + for (i = 0; i < length; i++) + { + if (!(i%2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + half_length + i + 1; + } + else if (i < (length - 2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + i/2 + 1; + + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2 + 1; + *(indicesp++) = index_offset + half_length + i + 1; + } + else + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + half_length + i + 1; + } + } + } + index_offset += num_vertices; } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, @@ -582,408 +582,408 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, LLStrider &indicesp, U32 &index_offset) { - S32 i, x, y; - - S32 num_vertices; - - U32 render_stride = mLastStride; - S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - S32 length = patch_size / render_stride; - S32 half_length = length / 2; - - U32 east_stride = mLastEastStride; - - // Stride lengths are the same - if (east_stride == render_stride) - { - num_vertices = 2 * length + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; - - // Main patch - for (i = 0; i < length; i++) - { - x = 16 - render_stride; - y = i * render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - // East patch - for (i = 0; i <= length; i++) - { - x = 16; - y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - - for (i = 0; i < length; i++) - { - // Generate indices - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + length + i; - *(indicesp++) = index_offset + length + i + 1; - - if (i != length - 1) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + length + i + 1; - *(indicesp++) = index_offset + i + 1; - } - } - } - else if (east_stride > render_stride) - { - // East stride is longer (has less vertices) - num_vertices = length + half_length + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; - - // Iterate through this patch's points - for (i = 0; i < length; i++) - { - x = 16 - render_stride; - y = i * render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - // Iterate through the east patch's points - for (i = 0; i <= length; i+=2) - { - x = 16; - y = i * render_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - for (i = 0; i < length; i++) - { - if (!(i % 2)) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + length + (i/2); - *(indicesp++) = index_offset + i + 1; - - *(indicesp++) = index_offset + i + 1; - *(indicesp++) = index_offset + length + (i/2); - *(indicesp++) = index_offset + length + (i/2) + 1; - } - else if (i < (length - 1)) - { - *(indicesp++) = index_offset + i; - *(indicesp++) = index_offset + length + (i/2) + 1; - *(indicesp++) = index_offset + i + 1; - } - } - } - else - { - // East stride is shorter (more vertices) - length = patch_size / east_stride; - half_length = length / 2; - num_vertices = length + length/2 + 1; - - facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; - - // Iterate through this patch's points - for (i = 0; i < length; i+=2) - { - x = 16 - render_stride; - y = i * east_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - // Iterate through the east patch's points - for (i = 0; i <= length; i++) - { - x = 16; - y = i * east_stride; - - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - verticesp++; - normalsp++; - texCoords0p++; - texCoords1p++; - } - - for (i = 0; i < length; i++) - { - if (!(i%2)) - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + half_length + i + 1; - *(indicesp++) = index_offset + i/2; - } - else if (i < (length - 2)) - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + i/2 + 1; - *(indicesp++) = index_offset + i/2; - - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + half_length + i + 1; - *(indicesp++) = index_offset + i/2 + 1; - } - else - { - *(indicesp++) = index_offset + half_length + i; - *(indicesp++) = index_offset + half_length + i + 1; - *(indicesp++) = index_offset + i/2; - } - } - } - index_offset += num_vertices; + S32 i, x, y; + + S32 num_vertices; + + U32 render_stride = mLastStride; + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / render_stride; + S32 half_length = length / 2; + + U32 east_stride = mLastEastStride; + + // Stride lengths are the same + if (east_stride == render_stride) + { + num_vertices = 2 * length + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Main patch + for (i = 0; i < length; i++) + { + x = 16 - render_stride; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + // East patch + for (i = 0; i <= length; i++) + { + x = 16; + y = i * render_stride; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + + for (i = 0; i < length; i++) + { + // Generate indices + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i; + *(indicesp++) = index_offset + length + i + 1; + + if (i != length - 1) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i + 1; + *(indicesp++) = index_offset + i + 1; + } + } + } + else if (east_stride > render_stride) + { + // East stride is longer (has less vertices) + num_vertices = length + half_length + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i++) + { + x = 16 - render_stride; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + // Iterate through the east patch's points + for (i = 0; i <= length; i+=2) + { + x = 16; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + for (i = 0; i < length; i++) + { + if (!(i % 2)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + (i/2); + *(indicesp++) = index_offset + i + 1; + + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2); + *(indicesp++) = index_offset + length + (i/2) + 1; + } + else if (i < (length - 1)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + (i/2) + 1; + *(indicesp++) = index_offset + i + 1; + } + } + } + else + { + // East stride is shorter (more vertices) + length = patch_size / east_stride; + half_length = length / 2; + num_vertices = length + length/2 + 1; + + facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i+=2) + { + x = 16 - render_stride; + y = i * east_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + // Iterate through the east patch's points + for (i = 0; i <= length; i++) + { + x = 16; + y = i * east_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + verticesp++; + normalsp++; + texCoords0p++; + texCoords1p++; + } + + for (i = 0; i < length; i++) + { + if (!(i%2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2; + } + else if (i < (length - 2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2 + 1; + *(indicesp++) = index_offset + i/2; + + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2 + 1; + } + else + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2; + } + } + } + index_offset += num_vertices; } void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { - mPatchp = patchp; + mPatchp = patchp; - dirtyPatch(); + dirtyPatch(); }; void LLVOSurfacePatch::dirtyPatch() { - mDirtiedPatch = TRUE; - dirtyGeom(); - mDirtyTerrain = TRUE; - LLVector3 center = mPatchp->getCenterRegion(); - LLSurface *surfacep = mPatchp->getSurface(); + mDirtiedPatch = TRUE; + dirtyGeom(); + mDirtyTerrain = TRUE; + LLVector3 center = mPatchp->getCenterRegion(); + LLSurface *surfacep = mPatchp->getSurface(); - setPositionRegion(center); + setPositionRegion(center); - F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid(); - setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ())); + F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid(); + setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ())); } void LLVOSurfacePatch::dirtyGeom() { - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - LLFace* facep = mDrawable->getFace(0); - if (facep) - { - facep->setVertexBuffer(NULL); - } - mDrawable->movePartition(); - } + if (mDrawable) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + LLFace* facep = mDrawable->getFace(0); + if (facep) + { + facep->setVertexBuffer(NULL); + } + mDrawable->movePartition(); + } } void LLVOSurfacePatch::getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices) { - S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - - // First, figure out how many vertices we need... - S32 vert_size = patch_size / stride; - if (vert_size >= 2) - { - num_vertices += vert_size * vert_size; - num_indices += 6 * (vert_size - 1)*(vert_size - 1); - } + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + + // First, figure out how many vertices we need... + S32 vert_size = patch_size / stride; + if (vert_size >= 2) + { + num_vertices += vert_size * vert_size; + num_indices += 6 * (vert_size - 1)*(vert_size - 1); + } } void LLVOSurfacePatch::getGeomSizesNorth(const S32 stride, const S32 north_stride, - S32 &num_vertices, S32 &num_indices) + S32 &num_vertices, S32 &num_indices) { - S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - S32 length = patch_size / stride; - // Stride lengths are the same - if (north_stride == stride) - { - num_vertices += 2 * length + 1; - num_indices += length * 6 - 3; - } - else if (north_stride > stride) - { - // North stride is longer (has less vertices) - num_vertices += length + (length/2) + 1; - num_indices += (length/2)*9 - 3; - } - else - { - // North stride is shorter (more vertices) - length = patch_size / north_stride; - num_vertices += length + (length/2) + 1; - num_indices += 9*(length/2) - 3; - } + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / stride; + // Stride lengths are the same + if (north_stride == stride) + { + num_vertices += 2 * length + 1; + num_indices += length * 6 - 3; + } + else if (north_stride > stride) + { + // North stride is longer (has less vertices) + num_vertices += length + (length/2) + 1; + num_indices += (length/2)*9 - 3; + } + else + { + // North stride is shorter (more vertices) + length = patch_size / north_stride; + num_vertices += length + (length/2) + 1; + num_indices += 9*(length/2) - 3; + } } void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride, - S32 &num_vertices, S32 &num_indices) + S32 &num_vertices, S32 &num_indices) { - S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); - S32 length = patch_size / stride; - // Stride lengths are the same - if (east_stride == stride) - { - num_vertices += 2 * length + 1; - num_indices += length * 6 - 3; - } - else if (east_stride > stride) - { - // East stride is longer (has less vertices) - num_vertices += length + (length/2) + 1; - num_indices += (length/2)*9 - 3; - } - else - { - // East stride is shorter (more vertices) - length = patch_size / east_stride; - num_vertices += length + (length/2) + 1; - num_indices += 9*(length/2) - 3; - } + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / stride; + // Stride lengths are the same + if (east_stride == stride) + { + num_vertices += 2 * length + 1; + num_indices += length * 6 - 3; + } + else if (east_stride > stride) + { + // East stride is longer (has less vertices) + num_vertices += length + (length/2) + 1; + num_indices += (length/2)*9 - 3; + } + else + { + // East stride is shorter (more vertices) + length = patch_size / east_stride; + num_vertices += length + (length/2) + 1; + num_indices += 9*(length/2) - 3; + } } BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) - + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + { - if (!lineSegmentBoundingBox(start, end)) - { - return FALSE; - } - - LLVector4a da; - da.setSub(end, start); - LLVector3 delta(da.getF32ptr()); - - LLVector3 pdelta = delta; - pdelta.mV[2] = 0; - - F32 plength = pdelta.length(); - - F32 tdelta = 1.f/plength; - - LLVector3 v_start(start.getF32ptr()); - - LLVector3 origin = v_start - mRegionp->getOriginAgent(); - - if (mRegionp->getLandHeightRegion(origin) > origin.mV[2]) - { - //origin is under ground, treat as no intersection - return FALSE; - } - - //step one meter at a time until intersection point found - - //VECTORIZE THIS - const LLVector4a* exta = mDrawable->getSpatialExtents(); - - LLVector3 ext[2]; - ext[0].set(exta[0].getF32ptr()); - ext[1].set(exta[1].getF32ptr()); - - F32 rad = (delta*tdelta).magVecSquared(); - - F32 t = 0.f; - while ( t <= 1.f) - { - LLVector3 sample = origin + delta*t; - - if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad)) - { - F32 height = mRegionp->getLandHeightRegion(sample); - if (height > sample.mV[2]) - { //ray went below ground, positive intersection - //quick and dirty binary search to get impact point - tdelta = -tdelta*0.5f; - F32 err_dist = 0.001f; - F32 dist = fabsf(sample.mV[2] - height); - - while (dist > err_dist && tdelta*tdelta > 0.0f) - { - t += tdelta; - sample = origin+delta*t; - height = mRegionp->getLandHeightRegion(sample); - if ((tdelta < 0 && height < sample.mV[2]) || - (height > sample.mV[2] && tdelta > 0)) - { //jumped over intersection point, go back - tdelta = -tdelta; - } - tdelta *= 0.5f; - dist = fabsf(sample.mV[2] - height); - } - - if (intersection) - { - F32 height = mRegionp->getLandHeightRegion(sample); - if (fabsf(sample.mV[2]-height) < delta.length()*tdelta) - { - sample.mV[2] = mRegionp->getLandHeightRegion(sample); - } - intersection->load3((sample + mRegionp->getOriginAgent()).mV); - } - - if (normal) - { - normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV); - } - - return TRUE; - } - } - - t += tdelta; - if (t > 1 && t < 1.f+tdelta*0.99f) - { //make sure end point is checked (saves vertical lines coming up negative) - t = 1.f; - } - } - - - return FALSE; + if (!lineSegmentBoundingBox(start, end)) + { + return FALSE; + } + + LLVector4a da; + da.setSub(end, start); + LLVector3 delta(da.getF32ptr()); + + LLVector3 pdelta = delta; + pdelta.mV[2] = 0; + + F32 plength = pdelta.length(); + + F32 tdelta = 1.f/plength; + + LLVector3 v_start(start.getF32ptr()); + + LLVector3 origin = v_start - mRegionp->getOriginAgent(); + + if (mRegionp->getLandHeightRegion(origin) > origin.mV[2]) + { + //origin is under ground, treat as no intersection + return FALSE; + } + + //step one meter at a time until intersection point found + + //VECTORIZE THIS + const LLVector4a* exta = mDrawable->getSpatialExtents(); + + LLVector3 ext[2]; + ext[0].set(exta[0].getF32ptr()); + ext[1].set(exta[1].getF32ptr()); + + F32 rad = (delta*tdelta).magVecSquared(); + + F32 t = 0.f; + while ( t <= 1.f) + { + LLVector3 sample = origin + delta*t; + + if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad)) + { + F32 height = mRegionp->getLandHeightRegion(sample); + if (height > sample.mV[2]) + { //ray went below ground, positive intersection + //quick and dirty binary search to get impact point + tdelta = -tdelta*0.5f; + F32 err_dist = 0.001f; + F32 dist = fabsf(sample.mV[2] - height); + + while (dist > err_dist && tdelta*tdelta > 0.0f) + { + t += tdelta; + sample = origin+delta*t; + height = mRegionp->getLandHeightRegion(sample); + if ((tdelta < 0 && height < sample.mV[2]) || + (height > sample.mV[2] && tdelta > 0)) + { //jumped over intersection point, go back + tdelta = -tdelta; + } + tdelta *= 0.5f; + dist = fabsf(sample.mV[2] - height); + } + + if (intersection) + { + F32 height = mRegionp->getLandHeightRegion(sample); + if (fabsf(sample.mV[2]-height) < delta.length()*tdelta) + { + sample.mV[2] = mRegionp->getLandHeightRegion(sample); + } + intersection->load3((sample + mRegionp->getOriginAgent()).mV); + } + + if (normal) + { + normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV); + } + + return TRUE; + } + } + + t += tdelta; + if (t > 1 && t < 1.f+tdelta*0.99f) + { //make sure end point is checked (saves vertical lines coming up negative) + t = 1.f; + } + } + + + return FALSE; } void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { - LLVector3 posAgent = getPositionAgent(); - LLVector3 scale = getScale(); - //make z-axis scale at least 1 to avoid shadow artifacts on totally flat land - scale.mV[VZ] = llmax(scale.mV[VZ], 1.f); - newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong - newMax.load3( (posAgent+scale*0.5f).mV); - LLVector4a pos; - pos.setAdd(newMin,newMax); - pos.mul(0.5f); - mDrawable->setPositionGroup(pos); + LLVector3 posAgent = getPositionAgent(); + LLVector3 scale = getScale(); + //make z-axis scale at least 1 to avoid shadow artifacts on totally flat land + scale.mV[VZ] = llmax(scale.mV[VZ], 1.f); + newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong + newMax.load3( (posAgent+scale*0.5f).mV); + LLVector4a pos; + pos.setAdd(newMin,newMax); + pos.mul(0.5f); + mDrawable->setPositionGroup(pos); } U32 LLVOSurfacePatch::getPartitionType() const -{ - return LLViewerRegion::PARTITION_TERRAIN; +{ + return LLViewerRegion::PARTITION_TERRAIN; } LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) : LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, regionp) { - mOcclusionEnabled = FALSE; - mInfiniteFarClip = TRUE; - mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; - mPartitionType = LLViewerRegion::PARTITION_TERRAIN; + mOcclusionEnabled = FALSE; + mInfiniteFarClip = TRUE; + mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; + mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } // Do not add vertices; honor strict vertex count specified by strider_vertex_count @@ -1033,22 +1033,22 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - LLVertexBuffer* buffer = group->mVertexBuffer; + LLVertexBuffer* buffer = group->mVertexBuffer; - //get vertex buffer striders - LLStrider vertices_start; - LLStrider normals_start; - LLStrider tangents_start; - LLStrider texcoords_start; - LLStrider texcoords2_start; - LLStrider indices_start; + //get vertex buffer striders + LLStrider vertices_start; + LLStrider normals_start; + LLStrider tangents_start; + LLStrider texcoords_start; + LLStrider texcoords2_start; + LLStrider indices_start; - llassert_always(buffer->getVertexStrider(vertices_start)); - llassert_always(buffer->getNormalStrider(normals_start)); - llassert_always(buffer->getTangentStrider(tangents_start)); - llassert_always(buffer->getTexCoord0Strider(texcoords_start)); - llassert_always(buffer->getTexCoord1Strider(texcoords2_start)); - llassert_always(buffer->getIndexStrider(indices_start)); + llassert_always(buffer->getVertexStrider(vertices_start)); + llassert_always(buffer->getNormalStrider(normals_start)); + llassert_always(buffer->getTangentStrider(tangents_start)); + llassert_always(buffer->getTexCoord0Strider(texcoords_start)); + llassert_always(buffer->getTexCoord1Strider(texcoords2_start)); + llassert_always(buffer->getIndexStrider(indices_start)); U32 indices_index = 0; U32 index_offset = 0; @@ -1088,7 +1088,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, texcoords, indices); } - buffer->unmapBuffer(); - mFaceList.clear(); + buffer->unmapBuffer(); + mFaceList.clear(); } diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a3dcb945d1..a38a5e011f 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -1,25 +1,25 @@ -/** +/** * @file llvosurfacepatch.h * @brief Description of LLVOSurfacePatch class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,103 +39,103 @@ class LLFace; class LLVOSurfacePatch : public LLStaticViewerObject { public: - static F32 sLODFactor; + static F32 sLODFactor; - enum - { - VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | - (1 << LLVertexBuffer::TYPE_NORMAL) | - (1 << LLVertexBuffer::TYPE_TEXCOORD0) | - (1 << LLVertexBuffer::TYPE_TEXCOORD1) - }; + enum + { + VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | + (1 << LLVertexBuffer::TYPE_NORMAL) | + (1 << LLVertexBuffer::TYPE_TEXCOORD0) | + (1 << LLVertexBuffer::TYPE_TEXCOORD1) + }; - LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - /*virtual*/ void markDead(); + /*virtual*/ void markDead(); - // Initialize data that's only inited once per class. - static void initClass(); + // Initialize data that's only inited once per class. + static void initClass(); - virtual U32 getPartitionType() const; + virtual U32 getPartitionType() const; - /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); - /*virtual*/ void updateGL(); - /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ BOOL updateLOD(); - /*virtual*/ void updateFaceSize(S32 idx); + /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); + /*virtual*/ void updateGL(); + /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); + /*virtual*/ BOOL updateLOD(); + /*virtual*/ void updateFaceSize(S32 idx); void getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp); - /*virtual*/ void updateTextures(); - /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area + /*virtual*/ void updateTextures(); + /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area - /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); - /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); + /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - void setPatch(LLSurfacePatch *patchp); - LLSurfacePatch *getPatch() const { return mPatchp; } + void setPatch(LLSurfacePatch *patchp); + LLSurfacePatch *getPatch() const { return mPatchp; } - void dirtyPatch(); - void dirtyGeom(); + void dirtyPatch(); + void dirtyGeom(); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face = -1, // which face to check, -1 = ALL_SIDES - BOOL pick_transparent = FALSE, - BOOL pick_rigged = FALSE, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + BOOL pick_transparent = FALSE, + BOOL pick_rigged = FALSE, BOOL pick_unselectable = TRUE, - S32* face_hit = NULL, // which face was hit - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ); - - BOOL mDirtiedPatch; + S32* face_hit = NULL, // which face was hit + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ); + + BOOL mDirtiedPatch; protected: - ~LLVOSurfacePatch(); - - LLFacePool *mPool; - LLFacePool *getPool(); - S32 mBaseComp; - LLSurfacePatch *mPatchp; - BOOL mDirtyTexture; - BOOL mDirtyTerrain; - - S32 mLastNorthStride; - S32 mLastEastStride; - S32 mLastStride; - S32 mLastLength; - - void getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices); - void getGeomSizesNorth(const S32 stride, const S32 north_stride, - S32 &num_vertices, S32 &num_indices); - void getGeomSizesEast(const S32 stride, const S32 east_stride, - S32 &num_vertices, S32 &num_indices); - - void updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset); - void updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset); - void updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset); + ~LLVOSurfacePatch(); + + LLFacePool *mPool; + LLFacePool *getPool(); + S32 mBaseComp; + LLSurfacePatch *mPatchp; + BOOL mDirtyTexture; + BOOL mDirtyTerrain; + + S32 mLastNorthStride; + S32 mLastEastStride; + S32 mLastStride; + S32 mLastLength; + + void getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices); + void getGeomSizesNorth(const S32 stride, const S32 north_stride, + S32 &num_vertices, S32 &num_indices); + void getGeomSizesEast(const S32 stride, const S32 east_stride, + S32 &num_vertices, S32 &num_indices); + + void updateMainGeometry(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset); + void updateNorthGeometry(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset); + void updateEastGeometry(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset); }; #endif // LL_VOSURFACEPATCH_H diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a956814147..2459f8cd58 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvovolume.cpp * @brief LLVOVolume class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -97,7 +97,7 @@ U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; F32 LLVOVolume::sLODFactor = 1.f; -F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop +F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop F32 LLVOVolume::sDistanceFactor = 1.0f; S32 LLVOVolume::sNumLODChanges = 0; S32 LLVOVolume::mRenderComplexity_last = 0; @@ -111,218 +111,218 @@ extern BOOL gCubeSnapshot; class LLMediaDataClientObjectImpl : public LLMediaDataClientObject { public: - LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) - { - mObject->addMDCImpl(); - } - ~LLMediaDataClientObjectImpl() - { - mObject->removeMDCImpl(); - } - - virtual U8 getMediaDataCount() const - { return mObject->getNumTEs(); } - - virtual LLSD getMediaDataLLSD(U8 index) const - { - LLSD result; - LLTextureEntry *te = mObject->getTE(index); - if (NULL != te) - { - llassert((te->getMediaData() != NULL) == te->hasMedia()); - if (te->getMediaData() != NULL) - { - result = te->getMediaData()->asLLSD(); - // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly - // See DEV-41949 - if (!result.has(LLMediaEntry::WHITELIST_KEY)) - { - result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); - } - } - } - return result; - } - virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const - { - LLTextureEntry *te = mObject->getTE(index); - if (te) - { - if (te->getMediaData()) - { - return (te->getMediaData()->getCurrentURL() == url); - } - } - return url.empty(); - } - - virtual LLUUID getID() const - { return mObject->getID(); } - - virtual void mediaNavigateBounceBack(U8 index) - { mObject->mediaNavigateBounceBack(index); } - - virtual bool hasMedia() const - { return mObject->hasMedia(); } - - virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string) - { mObject->updateObjectMediaData(data, version_string); } - - virtual F64 getMediaInterest() const - { - F64 interest = mObject->getTotalMediaInterest(); - if (interest < (F64)0.0) - { - // media interest not valid yet, try pixel area - interest = mObject->getPixelArea(); - // HACK: force recalculation of pixel area if interest is the "magic default" of 1024. - if (interest == 1024.f) - { - const_cast(static_cast(mObject))->setPixelAreaAndAngle(gAgent); - interest = mObject->getPixelArea(); - } - } - return interest; - } - - virtual bool isInterestingEnough() const - { - return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest()); - } - - virtual std::string getCapabilityUrl(const std::string &name) const - { return mObject->getRegion()->getCapability(name); } - - virtual bool isDead() const - { return mObject->isDead(); } - - virtual U32 getMediaVersion() const - { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); } - - virtual bool isNew() const - { return mNew; } + LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) + { + mObject->addMDCImpl(); + } + ~LLMediaDataClientObjectImpl() + { + mObject->removeMDCImpl(); + } + + virtual U8 getMediaDataCount() const + { return mObject->getNumTEs(); } + + virtual LLSD getMediaDataLLSD(U8 index) const + { + LLSD result; + LLTextureEntry *te = mObject->getTE(index); + if (NULL != te) + { + llassert((te->getMediaData() != NULL) == te->hasMedia()); + if (te->getMediaData() != NULL) + { + result = te->getMediaData()->asLLSD(); + // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly + // See DEV-41949 + if (!result.has(LLMediaEntry::WHITELIST_KEY)) + { + result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); + } + } + } + return result; + } + virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const + { + LLTextureEntry *te = mObject->getTE(index); + if (te) + { + if (te->getMediaData()) + { + return (te->getMediaData()->getCurrentURL() == url); + } + } + return url.empty(); + } + + virtual LLUUID getID() const + { return mObject->getID(); } + + virtual void mediaNavigateBounceBack(U8 index) + { mObject->mediaNavigateBounceBack(index); } + + virtual bool hasMedia() const + { return mObject->hasMedia(); } + + virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string) + { mObject->updateObjectMediaData(data, version_string); } + + virtual F64 getMediaInterest() const + { + F64 interest = mObject->getTotalMediaInterest(); + if (interest < (F64)0.0) + { + // media interest not valid yet, try pixel area + interest = mObject->getPixelArea(); + // HACK: force recalculation of pixel area if interest is the "magic default" of 1024. + if (interest == 1024.f) + { + const_cast(static_cast(mObject))->setPixelAreaAndAngle(gAgent); + interest = mObject->getPixelArea(); + } + } + return interest; + } + + virtual bool isInterestingEnough() const + { + return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest()); + } + + virtual std::string getCapabilityUrl(const std::string &name) const + { return mObject->getRegion()->getCapability(name); } + + virtual bool isDead() const + { return mObject->isDead(); } + + virtual U32 getMediaVersion() const + { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); } + + virtual bool isNew() const + { return mNew; } private: - LLPointer mObject; - bool mNew; + LLPointer mObject; + bool mNew; }; LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) - : LLViewerObject(id, pcode, regionp), - mVolumeImpl(NULL) + : LLViewerObject(id, pcode, regionp), + mVolumeImpl(NULL) { - mTexAnimMode = 0; - mRelativeXform.setIdentity(); - mRelativeXformInvTrans.setIdentity(); + mTexAnimMode = 0; + mRelativeXform.setIdentity(); + mRelativeXformInvTrans.setIdentity(); - mFaceMappingChanged = FALSE; - mLOD = MIN_LOD; + mFaceMappingChanged = FALSE; + mLOD = MIN_LOD; mLODDistance = 0.0f; mLODAdjustedDistance = 0.0f; mLODRadius = 0.0f; - mTextureAnimp = NULL; - mVolumeChanged = FALSE; - mVObjRadius = LLVector3(1,1,0.5f).length(); - mNumFaces = 0; - mLODChanged = FALSE; - mSculptChanged = FALSE; + mTextureAnimp = NULL; + mVolumeChanged = FALSE; + mVObjRadius = LLVector3(1,1,0.5f).length(); + mNumFaces = 0; + mLODChanged = FALSE; + mSculptChanged = FALSE; mColorChanged = FALSE; - mSpotLightPriority = 0.f; + mSpotLightPriority = 0.f; mSkinInfoUnavaliable = false; - mSkinInfo = NULL; + mSkinInfo = NULL; - mMediaImplList.resize(getNumTEs()); - mLastFetchedMediaVersion = -1; + mMediaImplList.resize(getNumTEs()); + mLastFetchedMediaVersion = -1; mServerDrawableUpdateCount = 0; - memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); - mMDCImplCount = 0; - mLastRiggingInfoLOD = -1; - mResetDebugText = false; + memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); + mMDCImplCount = 0; + mLastRiggingInfoLOD = -1; + mResetDebugText = false; } LLVOVolume::~LLVOVolume() { LL_PROFILE_ZONE_SCOPED; - delete mTextureAnimp; - mTextureAnimp = NULL; - delete mVolumeImpl; - mVolumeImpl = NULL; + delete mTextureAnimp; + mTextureAnimp = NULL; + delete mVolumeImpl; + mVolumeImpl = NULL; - gMeshRepo.unregisterMesh(this); + gMeshRepo.unregisterMesh(this); - if(!mMediaImplList.empty()) - { - for(U32 i = 0 ; i < mMediaImplList.size() ; i++) - { - if(mMediaImplList[i].notNull()) - { - mMediaImplList[i]->removeObject(this) ; - } - } - } + if(!mMediaImplList.empty()) + { + for(U32 i = 0 ; i < mMediaImplList.size() ; i++) + { + if(mMediaImplList[i].notNull()) + { + mMediaImplList[i]->removeObject(this) ; + } + } + } } void LLVOVolume::markDead() { - if (!mDead) - { + if (!mDead) + { LL_PROFILE_ZONE_SCOPED; if (getVolume()) { LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID()); } - if(getMDCImplCount() > 0) - { - LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast(this), false); - if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj); - if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj); - } - - // Detach all media impls from this object - for(U32 i = 0 ; i < mMediaImplList.size() ; i++) - { - removeMediaImpl(i); - } - - if (mSculptTexture.notNull()) - { - mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this); - } - - if (mLightTexture.notNull()) - { - mLightTexture->removeVolume(LLRender::LIGHT_TEX, this); - } - + if(getMDCImplCount() > 0) + { + LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast(this), false); + if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj); + if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj); + } + + // Detach all media impls from this object + for(U32 i = 0 ; i < mMediaImplList.size() ; i++) + { + removeMediaImpl(i); + } + + if (mSculptTexture.notNull()) + { + mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this); + } + + if (mLightTexture.notNull()) + { + mLightTexture->removeVolume(LLRender::LIGHT_TEX, this); + } + if (mIsHeroProbe) { gPipeline.mHeroProbeManager.unregisterViewerObject(this); } - } - - LLViewerObject::markDead(); + } + + LLViewerObject::markDead(); } // static void LLVOVolume::initClass() { - // gSavedSettings better be around - if (gSavedSettings.getBOOL("PrimMediaMasterEnabled")) - { - const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay"); - const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay"); - const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries"); - const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize"); - const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize"); - sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries, - max_sorted_queue_size, max_round_robin_queue_size); - sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, - max_retries, max_sorted_queue_size, max_round_robin_queue_size); - } + // gSavedSettings better be around + if (gSavedSettings.getBOOL("PrimMediaMasterEnabled")) + { + const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay"); + const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay"); + const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries"); + const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize"); + const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize"); + sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries, + max_sorted_queue_size, max_round_robin_queue_size); + sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, + max_retries, max_sorted_queue_size, max_round_robin_queue_size); + } } // static @@ -333,65 +333,65 @@ void LLVOVolume::cleanupClass() } U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, EObjectUpdateType update_type, + LLDataPacker *dp) { - - LLColor4U color; - const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); + + LLColor4U color; + const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); const bool previously_volume_changed = mVolumeChanged; const bool previously_face_mapping_changed = mFaceMappingChanged; const bool previously_color_changed = mColorChanged; - // Do base class updates... - U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + // Do base class updates... + U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - LLUUID sculpt_id; - U8 sculpt_type = 0; - if (isSculpted()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - sculpt_id = sculpt_params->getSculptTexture(); - sculpt_type = sculpt_params->getSculptType(); + LLUUID sculpt_id; + U8 sculpt_type = 0; + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + sculpt_id = sculpt_params->getSculptTexture(); + sculpt_type = sculpt_params->getSculptType(); LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL; dumpStack("ObjectUpdateStack"); - } - - if (!dp) - { - if (update_type == OUT_FULL) - { - //////////////////////////////// - // - // Unpack texture animation data - // - // - - if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim)) - { - if (!mTextureAnimp) - { - mTextureAnimp = new LLViewerTextureAnim(this); - } - else - { - if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) - { - mTextureAnimp->reset(); - } - } - mTexAnimMode = 0; - - mTextureAnimp->unpackTAMessage(mesgsys, block_num); - } - else - { - if (mTextureAnimp) - { - delete mTextureAnimp; - mTextureAnimp = NULL; + } + + if (!dp) + { + if (update_type == OUT_FULL) + { + //////////////////////////////// + // + // Unpack texture animation data + // + // + + if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim)) + { + if (!mTextureAnimp) + { + mTextureAnimp = new LLViewerTextureAnim(this); + } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } + mTexAnimMode = 0; + + mTextureAnimp->unpackTAMessage(mesgsys, block_num); + } + else + { + if (mTextureAnimp) + { + delete mTextureAnimp; + mTextureAnimp = NULL; for (S32 i = 0; i < getNumTEs(); i++) { @@ -404,98 +404,98 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - } - - // Unpack volume data - LLVolumeParams volume_params; - LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num); - volume_params.setSculptID(sculpt_id, sculpt_type); - - if (setVolume(volume_params, 0)) - { - markForUpdate(); - } - } - - // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens... - //////////////////////////// - // - // Unpack texture entry data - // - - S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); - - if (result & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - else - { - if (update_type != OUT_TERSE_IMPROVED) - { - LLVolumeParams volume_params; - BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp); - if (!res) - { - LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL; - LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL; - } - - volume_params.setSculptID(sculpt_id, sculpt_type); - - if (setVolume(volume_params, 0)) - { - markForUpdate(); - } - S32 res2 = unpackTEMessage(*dp); - if (TEM_INVALID == res2) - { - // There's something bogus in the data that we're unpacking. - dp->dumpBufferToLog(); - LL_WARNS() << "Flushing cache files" << LL_ENDL; - - if(LLVOCache::instanceExists() && getRegion()) - { - LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; - } - - LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL; - } - else - { - if (res2 & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - - U32 value = dp->getPassFlags(); - - if (value & 0x40) - { - if (!mTextureAnimp) - { - mTextureAnimp = new LLViewerTextureAnim(this); - } - else - { - if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) - { - mTextureAnimp->reset(); - } - } - mTexAnimMode = 0; - mTextureAnimp->unpackTAMessage(*dp); - } - else if (mTextureAnimp) - { - delete mTextureAnimp; - mTextureAnimp = NULL; + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + } + + // Unpack volume data + LLVolumeParams volume_params; + LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num); + volume_params.setSculptID(sculpt_id, sculpt_type); + + if (setVolume(volume_params, 0)) + { + markForUpdate(); + } + } + + // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens... + //////////////////////////// + // + // Unpack texture entry data + // + + S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); + + if (result & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + else + { + if (update_type != OUT_TERSE_IMPROVED) + { + LLVolumeParams volume_params; + BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp); + if (!res) + { + LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL; + LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL; + } + + volume_params.setSculptID(sculpt_id, sculpt_type); + + if (setVolume(volume_params, 0)) + { + markForUpdate(); + } + S32 res2 = unpackTEMessage(*dp); + if (TEM_INVALID == res2) + { + // There's something bogus in the data that we're unpacking. + dp->dumpBufferToLog(); + LL_WARNS() << "Flushing cache files" << LL_ENDL; + + if(LLVOCache::instanceExists() && getRegion()) + { + LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; + } + + LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL; + } + else + { + if (res2 & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + + U32 value = dp->getPassFlags(); + + if (value & 0x40) + { + if (!mTextureAnimp) + { + mTextureAnimp = new LLViewerTextureAnim(this); + } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } + mTexAnimMode = 0; + mTextureAnimp->unpackTAMessage(*dp); + } + else if (mTextureAnimp) + { + delete mTextureAnimp; + mTextureAnimp = NULL; for (S32 i = 0; i < getNumTEs(); i++) { @@ -508,59 +508,59 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - - if (value & 0x400) - { //particle system (new) - unpackParticleSource(*dp, mOwnerID, false); - } - } - else - { - S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry); - if (texture_length) - { - U8 tdpbuffer[1024]; - LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); - S32 result = unpackTEMessage(tdp); - if (result & teDirtyBits) - { - if (mDrawable) + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + + if (value & 0x400) + { //particle system (new) + unpackParticleSource(*dp, mOwnerID, false); + } + } + else + { + S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry); + if (texture_length) + { + U8 tdpbuffer[1024]; + LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); + S32 result = unpackTEMessage(tdp); + if (result & teDirtyBits) + { + if (mDrawable) { //on the fly TE updates break batches, isolate in octree shrinkWrap(); } - } - if (result & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - } - } - if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) - { - // If only the media URL changed, and it isn't a media version URL, - // ignore it - if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) && - mMedia && ! mMedia->mMediaURL.empty() && - ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) ) - { - // If the media changed at all, request new media data - LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " << + } + if (result & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + } + } + if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) + { + // If only the media URL changed, and it isn't a media version URL, + // ignore it + if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) && + mMedia && ! mMedia->mMediaURL.empty() && + ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) ) + { + // If the media changed at all, request new media data + LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " << ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL; - requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED); - } + requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED); + } else { LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " << ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL; } - } - // ...and clean up any media impls - cleanUpMediaImpls(); + } + // ...and clean up any media impls + cleanUpMediaImpls(); if (( (mVolumeChanged && !previously_volume_changed) || @@ -571,7 +571,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, onDrawableUpdateFromServer(); } - return retval; + return retval; } // Called when a volume, material, etc is updated by the server, possibly by a @@ -590,117 +590,117 @@ void LLVOVolume::onDrawableUpdateFromServer() void LLVOVolume::animateTextures() { - if (!mDead) - { + if (!mDead) + { shrinkWrap(); - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) - { - if (!mTexAnimMode) - { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; - - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } - - for (S32 i = start; i <= end; i++) - { - LLFace* facep = mDrawable->getFace(i); - if (!facep) continue; - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - - const LLTextureEntry* te = facep->getTextureEntry(); - - if (!te) - { - continue; - } - - if (!(result & LLViewerTextureAnim::ROTATE)) - { - te->getRotation(&rot); - } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) - { - te->getScale(&scale_s, &scale_t); - } - - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } - - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; - - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); - - tex_mat.rotate(quat); - - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; - - tex_mat.translate(trans); - } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) - { - U8 start, count; - - if (mTextureAnimp->mFace == -1) - { - start = 0; - count = getNumTEs(); - } - else - { - start = (U8) mTextureAnimp->mFace; - count = 1; - } - - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) - { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); - } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) - { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); - } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) - { - setTERotation(i, mTextureAnimp->mRot); - } - } - - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - } - } + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) + { + if (!mTexAnimMode) + { + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); + } + mTexAnimMode = result | mTextureAnimp->mMode; + + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) + { + start = end = mTextureAnimp->mFace; + } + + for (S32 i = start; i <= end; i++) + { + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; + + const LLTextureEntry* te = facep->getTextureEntry(); + + if (!te) + { + continue; + } + + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } + + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } + + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; + + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); + + tex_mat.rotate(quat); + + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; + + tex_mat.translate(trans); + } + } + else + { + if (mTexAnimMode && mTextureAnimp->mRate == 0) + { + U8 start, count; + + if (mTextureAnimp->mFace == -1) + { + start = 0; + count = getNumTEs(); + } + else + { + start = (U8) mTextureAnimp->mFace; + count = 1; + } + + for (S32 i = start; i < start + count; i++) + { + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } + } + + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + } + } } void LLVOVolume::updateTextures() @@ -709,403 +709,403 @@ void LLVOVolume::updateTextures() updateTextureVirtualSize(); } -BOOL LLVOVolume::isVisible() const +BOOL LLVOVolume::isVisible() const { - if(mDrawable.notNull() && mDrawable->isVisible()) - { - return TRUE ; - } + if(mDrawable.notNull() && mDrawable->isVisible()) + { + return TRUE ; + } - if(isAttachment()) - { - LLViewerObject* objp = (LLViewerObject*)getParent() ; - while(objp && !objp->isAvatar()) - { - objp = (LLViewerObject*)objp->getParent() ; - } + if(isAttachment()) + { + LLViewerObject* objp = (LLViewerObject*)getParent() ; + while(objp && !objp->isAvatar()) + { + objp = (LLViewerObject*)objp->getParent() ; + } - return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ; - } + return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ; + } - return FALSE ; + return FALSE ; } void LLVOVolume::updateTextureVirtualSize(bool forced) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - // Update the pixel area of all faces + // Update the pixel area of all faces if (mDrawable.isNull() || gCubeSnapshot) { return; } - if(!forced) - { - if(!isVisible()) - { //don't load textures for non-visible faces - const S32 num_faces = mDrawable->getNumFaces(); - for (S32 i = 0; i < num_faces; i++) - { - LLFace* face = mDrawable->getFace(i); - if (face) - { - face->setPixelArea(0.f); - face->setVirtualSize(0.f); - } - } - - return ; - } - - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) - { - return; - } - } - - static LLCachedControl dont_load_textures(gSavedSettings,"TextureDisable", false); - - if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible()) - { - return; - } - - mTextureUpdateTimer.reset(); - - F32 old_area = mPixelArea; - mPixelArea = 0.f; - - const S32 num_faces = mDrawable->getNumFaces(); - F32 min_vsize=999999999.f, max_vsize=0.f; - LLViewerCamera* camera = LLViewerCamera::getInstance(); - std::stringstream debug_text; - for (S32 i = 0; i < num_faces; i++) - { - LLFace* face = mDrawable->getFace(i); - if (!face) continue; - const LLTextureEntry *te = face->getTextureEntry(); - LLViewerTexture *imagep = face->getTexture(); - if (!imagep || !te || - face->mExtents[0].equals3(face->mExtents[1])) - { - continue; - } - - F32 vsize; - F32 old_size = face->getVirtualSize(); - - if (isHUDAttachment()) - { - F32 area = (F32) camera->getScreenPixelArea(); - vsize = area; - imagep->setBoostLevel(LLGLTexture::BOOST_HUD); - face->setPixelArea(area); // treat as full screen - face->setVirtualSize(vsize); - } - else - { - vsize = face->getTextureVirtualSize(); - } - - mPixelArea = llmax(mPixelArea, face->getPixelArea()); + if(!forced) + { + if(!isVisible()) + { //don't load textures for non-visible faces + const S32 num_faces = mDrawable->getNumFaces(); + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + if (face) + { + face->setPixelArea(0.f); + face->setVirtualSize(0.f); + } + } - // if the face has gotten small enough to turn off texture animation and texture - // animation is running, rebuild the render batch for this face to turn off - // texture animation - if (face->mTextureMatrix != NULL) - { - if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || - (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; - if(img) - { - debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n"; - /*F32 pri = img->getDecodePriority(); - pri = llmax(pri, 0.0f); - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri;*/ - } - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) - { - F32 pri = mPixelArea; - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri; - } - } - - if (isSculpted()) - { - updateSculptTexture(); - - - - if (mSculptTexture.notNull()) - { - mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLGLTexture::BOOST_SCULPTED)); - mSculptTexture->setForSculpt() ; - - if(!mSculptTexture->isCachedRawImageReady()) - { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); - } - - S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture - S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; - - if (texture_discard >= 0 && //texture has some data available - (texture_discard < current_discard || //texture has more data than last rebuild - current_discard < 0)) //no previous rebuild - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - mSculptChanged = TRUE; - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) - { - setDebugText(llformat("T%d C%d V%d\n%dx%d", - texture_discard, current_discard, getVolume()->getSculptLevel(), - mSculptTexture->getHeight(), mSculptTexture->getWidth())); - } - } - - } - - if (getLightTextureID().notNull()) - { - LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - LLUUID id = params->getLightTexture(); - mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); - if (mLightTexture.notNull()) - { - F32 rad = getLightRadius(); - mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), - LLVector3(rad,rad,rad), - *camera)); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) - { - setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); - setDebugText(debug_text.str()); - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) - { - setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); - } + return ; + } - if (mPixelArea == 0) - { //flexi phasing issues make this happen - mPixelArea = old_area; - } -} + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) + { + return; + } + } -BOOL LLVOVolume::isActive() const -{ - return !mStatic; -} + static LLCachedControl dont_load_textures(gSavedSettings,"TextureDisable", false); -BOOL LLVOVolume::setMaterial(const U8 material) -{ - BOOL res = LLViewerObject::setMaterial(material); - - return res; -} + if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible()) + { + return; + } -void LLVOVolume::setTexture(const S32 face) -{ - llassert(face < getNumTEs()); - gGL.getTexUnit(0)->bind(getTEImage(face)); -} + mTextureUpdateTimer.reset(); -void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) -{ - if (scale != getScale()) - { - // store local radius - LLViewerObject::setScale(scale); + F32 old_area = mPixelArea; + mPixelArea = 0.f; - if (mVolumeImpl) - { - mVolumeImpl->onSetScale(scale, damped); - } - - updateRadius(); + const S32 num_faces = mDrawable->getNumFaces(); + F32 min_vsize=999999999.f, max_vsize=0.f; + LLViewerCamera* camera = LLViewerCamera::getInstance(); + std::stringstream debug_text; + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + if (!face) continue; + const LLTextureEntry *te = face->getTextureEntry(); + LLViewerTexture *imagep = face->getTexture(); + if (!imagep || !te || + face->mExtents[0].equals3(face->mExtents[1])) + { + continue; + } - //since drawable transforms do not include scale, changing volume scale - //requires an immediate rebuild of volume verts. - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); + F32 vsize; + F32 old_size = face->getVirtualSize(); - if (mDrawable) + if (isHUDAttachment()) { - shrinkWrap(); + F32 area = (F32) camera->getScreenPixelArea(); + vsize = area; + imagep->setBoostLevel(LLGLTexture::BOOST_HUD); + face->setPixelArea(area); // treat as full screen + face->setVirtualSize(vsize); + } + else + { + vsize = face->getTextureVirtualSize(); } - } -} -LLFace* LLVOVolume::addFace(S32 f) -{ - const LLTextureEntry* te = getTE(f); - LLViewerTexture* imagep = getTEImage(f); - if (te->getMaterialParams().notNull()) - { - LLViewerTexture* normalp = getTENormalMap(f); - LLViewerTexture* specularp = getTESpecularMap(f); - return mDrawable->addFace(te, imagep, normalp, specularp); - } - return mDrawable->addFace(te, imagep); + mPixelArea = llmax(mPixelArea, face->getPixelArea()); + + // if the face has gotten small enough to turn off texture animation and texture + // animation is running, rebuild the render batch for this face to turn off + // texture animation + if (face->mTextureMatrix != NULL) + { + if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || + (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; + if(img) + { + debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n"; + /*F32 pri = img->getDecodePriority(); + pri = llmax(pri, 0.0f); + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri;*/ + } + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) + { + F32 pri = mPixelArea; + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri; + } + } + + if (isSculpted()) + { + updateSculptTexture(); + + + + if (mSculptTexture.notNull()) + { + mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), + (S32)LLGLTexture::BOOST_SCULPTED)); + mSculptTexture->setForSculpt() ; + + if(!mSculptTexture->isCachedRawImageReady()) + { + S32 lod = llmin(mLOD, 3); + F32 lodf = ((F32)(lod + 1.0f)/4.f); + F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; + mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); + } + + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture + S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; + + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + mSculptChanged = TRUE; + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) + { + setDebugText(llformat("T%d C%d V%d\n%dx%d", + texture_discard, current_discard, getVolume()->getSculptLevel(), + mSculptTexture->getHeight(), mSculptTexture->getWidth())); + } + } + + } + + if (getLightTextureID().notNull()) + { + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLUUID id = params->getLightTexture(); + mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); + if (mLightTexture.notNull()) + { + F32 rad = getLightRadius(); + mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), + LLVector3(rad,rad,rad), + *camera)); + } + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + setDebugText(debug_text.str()); + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) + { + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + } + + if (mPixelArea == 0) + { //flexi phasing issues make this happen + mPixelArea = old_area; + } +} + +BOOL LLVOVolume::isActive() const +{ + return !mStatic; +} + +BOOL LLVOVolume::setMaterial(const U8 material) +{ + BOOL res = LLViewerObject::setMaterial(material); + + return res; +} + +void LLVOVolume::setTexture(const S32 face) +{ + llassert(face < getNumTEs()); + gGL.getTexUnit(0)->bind(getTEImage(face)); +} + +void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) +{ + if (scale != getScale()) + { + // store local radius + LLViewerObject::setScale(scale); + + if (mVolumeImpl) + { + mVolumeImpl->onSetScale(scale, damped); + } + + updateRadius(); + + //since drawable transforms do not include scale, changing volume scale + //requires an immediate rebuild of volume verts. + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); + + if (mDrawable) + { + shrinkWrap(); + } + } +} + +LLFace* LLVOVolume::addFace(S32 f) +{ + const LLTextureEntry* te = getTE(f); + LLViewerTexture* imagep = getTEImage(f); + if (te->getMaterialParams().notNull()) + { + LLViewerTexture* normalp = getTENormalMap(f); + LLViewerTexture* specularp = getTESpecularMap(f); + return mDrawable->addFace(te, imagep, normalp, specularp); + } + return mDrawable->addFace(te, imagep); } LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); + pipeline->allocDrawable(this); + + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); - S32 max_tes_to_set = getNumTEs(); - for (S32 i = 0; i < max_tes_to_set; i++) - { - addFace(i); - } - mNumFaces = max_tes_to_set; + S32 max_tes_to_set = getNumTEs(); + for (S32 i = 0; i < max_tes_to_set; i++) + { + addFace(i); + } + mNumFaces = max_tes_to_set; - if (isAttachment()) - { - mDrawable->makeActive(); - } + if (isAttachment()) + { + mDrawable->makeActive(); + } - if (getIsLight()) - { - // Add it to the pipeline mLightSet - gPipeline.setLight(mDrawable, TRUE); - } + if (getIsLight()) + { + // Add it to the pipeline mLightSet + gPipeline.setLight(mDrawable, TRUE); + } if (isReflectionProbe()) { updateReflectionProbePtr(); } - - updateRadius(); - bool force_update = true; // avoid non-alpha mDistance update being optimized away - mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); - return mDrawable; + updateRadius(); + bool force_update = true; // avoid non-alpha mDistance update being optimized away + mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); + + return mDrawable; } BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bool unique_volume) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - LLVolumeParams volume_params = params_in; - - S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1; - S32 lod = mLOD; - - BOOL is404 = FALSE; - - if (isSculpted()) - { - // if it's a mesh - if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - { //meshes might not have all LODs, get the force detail to best existing LOD - if (NO_LOD != lod) - { - lod = gMeshRepo.getActualMeshLOD(volume_params, lod); - if (lod == -1) - { - is404 = TRUE; - lod = 0; - } - } - } - } - - // Check if we need to change implementations - bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE); - if (is_flexible) - { - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false); - if (!mVolumeImpl) - { - LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - mVolumeImpl = new LLVolumeImplFlexible(this, data); - } - } - else - { - // Mark the parameter not in use - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false); - if (mVolumeImpl) - { - delete mVolumeImpl; - mVolumeImpl = NULL; - if (mDrawable.notNull()) - { - // Undo the damage we did to this matrix - mDrawable->updateXform(FALSE); - } - } - } - - if (is404) - { - setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); - //render prim proxy when mesh loading attempts give up - volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); - - } - - if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) - { - mFaceMappingChanged = TRUE; - - if (mVolumeImpl) - { - mVolumeImpl->onSetVolume(volume_params, mLOD); - } - - updateSculptTexture(); - - if (isSculpted()) - { - updateSculptTexture(); - // if it's a mesh - if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - { - if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) - { - mSkinInfo = NULL; - mSkinInfoUnavaliable = false; - } - - if (!getVolume()->isMeshAssetLoaded()) - { - //load request not yet issued, request pipeline load this mesh - S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); - if (available_lod != lod) - { - LLPrimitive::setVolume(volume_params, available_lod); - } - } - - if (!mSkinInfo && !mSkinInfoUnavaliable) - { + LLVolumeParams volume_params = params_in; + + S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1; + S32 lod = mLOD; + + BOOL is404 = FALSE; + + if (isSculpted()) + { + // if it's a mesh + if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { //meshes might not have all LODs, get the force detail to best existing LOD + if (NO_LOD != lod) + { + lod = gMeshRepo.getActualMeshLOD(volume_params, lod); + if (lod == -1) + { + is404 = TRUE; + lod = 0; + } + } + } + } + + // Check if we need to change implementations + bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE); + if (is_flexible) + { + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false); + if (!mVolumeImpl) + { + LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + mVolumeImpl = new LLVolumeImplFlexible(this, data); + } + } + else + { + // Mark the parameter not in use + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false); + if (mVolumeImpl) + { + delete mVolumeImpl; + mVolumeImpl = NULL; + if (mDrawable.notNull()) + { + // Undo the damage we did to this matrix + mDrawable->updateXform(FALSE); + } + } + } + + if (is404) + { + setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); + //render prim proxy when mesh loading attempts give up + volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); + + } + + if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) + { + mFaceMappingChanged = TRUE; + + if (mVolumeImpl) + { + mVolumeImpl->onSetVolume(volume_params, mLOD); + } + + updateSculptTexture(); + + if (isSculpted()) + { + updateSculptTexture(); + // if it's a mesh + if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { + if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) + { + mSkinInfo = NULL; + mSkinInfoUnavaliable = false; + } + + if (!getVolume()->isMeshAssetLoaded()) + { + //load request not yet issued, request pipeline load this mesh + S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); + if (available_lod != lod) + { + LLPrimitive::setVolume(volume_params, available_lod); + } + } + + if (!mSkinInfo && !mSkinInfoUnavaliable) + { LLUUID mesh_id = volume_params.getSculptID(); if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id)) { @@ -1122,60 +1122,60 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo notifySkinInfoLoaded(skin_info); } } - } - } - else // otherwise is sculptie - { - if (mSculptTexture.notNull()) - { - sculpt(); - } - } - } + } + } + else // otherwise is sculptie + { + if (mSculptTexture.notNull()) + { + sculpt(); + } + } + } return TRUE; - } - else if (NO_LOD == lod) - { - LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID()); - } + } + else if (NO_LOD == lod) + { + LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID()); + } - return FALSE; + return FALSE; } void LLVOVolume::updateSculptTexture() { - LLPointer old_sculpt = mSculptTexture; + LLPointer old_sculpt = mSculptTexture; - if (isSculpted() && !isMesh()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - if (id.notNull()) - { - mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } + if (isSculpted() && !isMesh()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID id = sculpt_params->getSculptTexture(); + if (id.notNull()) + { + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } mSkinInfoUnavaliable = false; - mSkinInfo = NULL; - } - else - { - mSculptTexture = NULL; - } - - if (mSculptTexture != old_sculpt) - { - if (old_sculpt.notNull()) - { - old_sculpt->removeVolume(LLRender::SCULPT_TEX, this); - } - if (mSculptTexture.notNull()) - { - mSculptTexture->addVolume(LLRender::SCULPT_TEX, this); - } - } - + mSkinInfo = NULL; + } + else + { + mSculptTexture = NULL; + } + + if (mSculptTexture != old_sculpt) + { + if (old_sculpt.notNull()) + { + old_sculpt->removeVolume(LLRender::SCULPT_TEX, this); + } + if (mSculptTexture.notNull()) + { + mSculptTexture->addVolume(LLRender::SCULPT_TEX, this); + } + } + } void LLVOVolume::updateVisualComplexity() @@ -1193,9 +1193,9 @@ void LLVOVolume::updateVisualComplexity() } void LLVOVolume::notifyMeshLoaded() -{ - mSculptChanged = TRUE; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); +{ + mSculptChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); if (!mSkinInfo && !mSkinInfoUnavaliable) { @@ -1225,137 +1225,137 @@ void LLVOVolume::notifyMeshLoaded() void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) { mSkinInfoUnavaliable = false; - mSkinInfo = skin; + mSkinInfo = skin; - notifyMeshLoaded(); + notifyMeshLoaded(); } void LLVOVolume::notifySkinInfoUnavailable() { - mSkinInfoUnavaliable = true; - mSkinInfo = nullptr; + mSkinInfoUnavaliable = true; + mSkinInfo = nullptr; } // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() -{ - if (mSculptTexture.notNull()) - { - U16 sculpt_height = 0; - U16 sculpt_width = 0; - S8 sculpt_components = 0; - const U8* sculpt_data = NULL; - - S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; - LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; - - S32 max_discard = mSculptTexture->getMaxDiscardLevel(); - if (discard_level > max_discard) - { - discard_level = max_discard; // clamp to the best we can do - } - if(discard_level > MAX_DISCARD_LEVEL) - { - return; //we think data is not ready yet. - } - - S32 current_discard = getVolume()->getSculptLevel() ; - if(current_discard < -2) - { - static S32 low_sculpty_discard_warning_count = 1; - S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) )); - S32 interval = pow(10.0, exponent); - if ( low_sculpty_discard_warning_count < 10 || - (low_sculpty_discard_warning_count % interval) == 0) - { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs - LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() - << " at " << current_discard - << " is less than -2." - << " Hit this " << low_sculpty_discard_warning_count << " times" - << LL_ENDL; - } - low_sculpty_discard_warning_count++; - - // corrupted volume... don't update the sculpty - return; - } - else if (current_discard > MAX_DISCARD_LEVEL) - { - static S32 high_sculpty_discard_warning_count = 1; - S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) )); - S32 interval = pow(10.0, exponent); - if ( high_sculpty_discard_warning_count < 10 || - (high_sculpty_discard_warning_count % interval) == 0) - { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs - LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() - << " at " << current_discard - << " is more than than allowed max of " << MAX_DISCARD_LEVEL - << ". Hit this " << high_sculpty_discard_warning_count << " times" - << LL_ENDL; - } - high_sculpty_discard_warning_count++; - - // corrupted volume... don't update the sculpty - return; - } - - if (current_discard == discard_level) // no work to do here - return; - - if(!raw_image) - { - llassert(discard_level < 0) ; - - sculpt_width = 0; - sculpt_height = 0; - sculpt_data = NULL ; - - if(LLViewerTextureManager::sTesterp) - { - LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); - } - } - else - { - sculpt_height = raw_image->getHeight(); - sculpt_width = raw_image->getWidth(); - sculpt_components = raw_image->getComponents(); - - sculpt_data = raw_image->getData(); - - if(LLViewerTextureManager::sTesterp) - { - mSculptTexture->updateBindStatsForTester() ; - } - } - getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset()); - - //notify rebuild any other VOVolumes that reference this sculpty volume - for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i) - { - LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i]; - if (volume != this && volume->getVolume() == getVolume()) - { - gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY); - } - } - } -} - -S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor) -{ - S32 cur_detail; - if (LLPipeline::sDynamicLOD) - { - // We've got LOD in the profile, and in the twist. Use radius. - F32 tan_angle = (lod_factor*radius)/distance; - cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); - } - else - { - cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3); - } - return cur_detail; +{ + if (mSculptTexture.notNull()) + { + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + + S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; + LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; + + S32 max_discard = mSculptTexture->getMaxDiscardLevel(); + if (discard_level > max_discard) + { + discard_level = max_discard; // clamp to the best we can do + } + if(discard_level > MAX_DISCARD_LEVEL) + { + return; //we think data is not ready yet. + } + + S32 current_discard = getVolume()->getSculptLevel() ; + if(current_discard < -2) + { + static S32 low_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( low_sculpty_discard_warning_count < 10 || + (low_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs + LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is less than -2." + << " Hit this " << low_sculpty_discard_warning_count << " times" + << LL_ENDL; + } + low_sculpty_discard_warning_count++; + + // corrupted volume... don't update the sculpty + return; + } + else if (current_discard > MAX_DISCARD_LEVEL) + { + static S32 high_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( high_sculpty_discard_warning_count < 10 || + (high_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs + LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is more than than allowed max of " << MAX_DISCARD_LEVEL + << ". Hit this " << high_sculpty_discard_warning_count << " times" + << LL_ENDL; + } + high_sculpty_discard_warning_count++; + + // corrupted volume... don't update the sculpty + return; + } + + if (current_discard == discard_level) // no work to do here + return; + + if(!raw_image) + { + llassert(discard_level < 0) ; + + sculpt_width = 0; + sculpt_height = 0; + sculpt_data = NULL ; + + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); + } + } + else + { + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + sculpt_components = raw_image->getComponents(); + + sculpt_data = raw_image->getData(); + + if(LLViewerTextureManager::sTesterp) + { + mSculptTexture->updateBindStatsForTester() ; + } + } + getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset()); + + //notify rebuild any other VOVolumes that reference this sculpty volume + for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i) + { + LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i]; + if (volume != this && volume->getVolume() == getVolume()) + { + gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY); + } + } + } +} + +S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor) +{ + S32 cur_detail; + if (LLPipeline::sDynamicLOD) + { + // We've got LOD in the profile, and in the twist. Use radius. + F32 tan_angle = (lod_factor*radius)/distance; + cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); + } + else + { + cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3); + } + return cur_detail; } std::string get_debug_object_lod_text(LLVOVolume *rootp) @@ -1400,28 +1400,28 @@ std::string get_debug_object_lod_text(LLVOVolume *rootp) BOOL LLVOVolume::calcLOD() { - if (mDrawable.isNull()) - { - return FALSE; - } + if (mDrawable.isNull()) + { + return FALSE; + } + + S32 cur_detail = 0; - S32 cur_detail = 0; - - F32 radius; - F32 distance; - F32 lod_factor = LLVOVolume::sLODFactor; + F32 radius; + F32 distance; + F32 lod_factor = LLVOVolume::sLODFactor; + + if (mDrawable->isState(LLDrawable::RIGGED)) + { + LLVOAvatar* avatar = getAvatar(); - if (mDrawable->isState(LLDrawable::RIGGED)) - { - LLVOAvatar* avatar = getAvatar(); - - // Not sure how this can really happen, but alas it does. Better exit here than crashing. - if( !avatar || !avatar->mDrawable ) - { - return FALSE; - } + // Not sure how this can really happen, but alas it does. Better exit here than crashing. + if( !avatar || !avatar->mDrawable ) + { + return FALSE; + } - distance = avatar->mDrawable->mDistanceWRTCamera; + distance = avatar->mDrawable->mDistanceWRTCamera; if (avatar->isControlAvatar()) @@ -1448,20 +1448,20 @@ BOOL LLVOVolume::calcLOD() LL_DEBUGS("DynamicBox","CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } - } - else - { - distance = mDrawable->mDistanceWRTCamera; - radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); + } + else + { + distance = mDrawable->mDistanceWRTCamera; + radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); if (distance <= 0.f || radius <= 0.f) { LL_DEBUGS("DynamicBox","CalcLOD") << "non-avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } - } - - //hold onto unmodified distance for debugging - //F32 debug_distance = distance; + } + + //hold onto unmodified distance for debugging + //F32 debug_distance = distance; mLODDistance = distance; mLODRadius = radius; @@ -1487,24 +1487,24 @@ BOOL LLVOVolume::calcLOD() distance *= sDistanceFactor; - F32 rampDist = LLVOVolume::sLODFactor * 2; - - if (distance < rampDist) - { - // Boost LOD when you're REALLY close - distance *= 1.0f/rampDist; - distance *= distance; - distance *= rampDist; - } - - - distance *= F_PI/3.f; - - static LLCachedControl ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); - if(!ignore_fov_zoom) - { - lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); - } + F32 rampDist = LLVOVolume::sLODFactor * 2; + + if (distance < rampDist) + { + // Boost LOD when you're REALLY close + distance *= 1.0f/rampDist; + distance *= distance; + distance *= rampDist; + } + + + distance *= F_PI/3.f; + + static LLCachedControl ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); + if(!ignore_fov_zoom) + { + lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); + } mLODAdjustedDistance = distance; @@ -1527,189 +1527,189 @@ BOOL LLVOVolume::calcLOD() setDebugText(llformat("TRIS SHOWN %d EST %d", total_tris, est_max_tris)); } } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && - mDrawable->getFace(0)) - { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && + mDrawable->getFace(0)) + { // This is a debug display for LODs. Please don't put the texture index here. setDebugText(llformat("%d", cur_detail)); - } + } - if (cur_detail != mLOD) - { - LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD + if (cur_detail != mLOD) + { + LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD << " distance " << distance << " radius " << radius << " rampDist " << rampDist << " drawable rigged? " << (mDrawable ? (S32) mDrawable->isState(LLDrawable::RIGGED) : (S32) -1) - << " mRiggedVolume " << (void*)getRiggedVolume() + << " mRiggedVolume " << (void*)getRiggedVolume() << " distanceWRTCamera " << (mDrawable ? mDrawable->mDistanceWRTCamera : -1.f) << LL_ENDL; - - mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); - mLOD = cur_detail; + + mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); + mLOD = cur_detail; return TRUE; - } + } - return FALSE; + return FALSE; } BOOL LLVOVolume::updateLOD() { - if (mDrawable.isNull()) - { - return FALSE; - } + if (mDrawable.isNull()) + { + return FALSE; + } LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - BOOL lod_changed = FALSE; - - if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID())) - { - lod_changed = calcLOD(); - } - else - { - return FALSE; - } - - if (lod_changed) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - mLODChanged = TRUE; - } - else - { - F32 new_radius = getBinRadius(); - F32 old_radius = mDrawable->getBinRadius(); - if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) - { - gPipeline.markPartitionMove(mDrawable); - } - } - - lod_changed = lod_changed || LLViewerObject::updateLOD(); - - return lod_changed; -} - -BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) -{ - if (!LLViewerObject::setDrawableParent(parentp)) - { - // no change in drawable parent - return FALSE; - } - - if (!mDrawable->isRoot()) - { - // rebuild vertices in parent relative space - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - - if (mDrawable->isActive() && !parentp->isActive()) - { - parentp->makeActive(); - } - else if (mDrawable->isStatic() && parentp->isActive()) - { - mDrawable->makeActive(); - } - } - - return TRUE; -} - -void LLVOVolume::updateFaceFlags() -{ - // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() - for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) - { - LLFace *face = mDrawable->getFace(i); - if (face) - { - BOOL fullbright = getTE(i)->getFullbright(); - face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); - - if (fullbright || (mMaterial == LL_MCODE_LIGHT)) - { - face->setState(LLFace::FULLBRIGHT); - } - if (mDrawable->isLight()) - { - face->setState(LLFace::LIGHT); - } - if (isHUDAttachment()) - { - face->setState(LLFace::HUD_RENDER); - } - } - } -} + BOOL lod_changed = FALSE; + + if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID())) + { + lod_changed = calcLOD(); + } + else + { + return FALSE; + } + + if (lod_changed) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + mLODChanged = TRUE; + } + else + { + F32 new_radius = getBinRadius(); + F32 old_radius = mDrawable->getBinRadius(); + if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) + { + gPipeline.markPartitionMove(mDrawable); + } + } + + lod_changed = lod_changed || LLViewerObject::updateLOD(); + + return lod_changed; +} + +BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) +{ + if (!LLViewerObject::setDrawableParent(parentp)) + { + // no change in drawable parent + return FALSE; + } + + if (!mDrawable->isRoot()) + { + // rebuild vertices in parent relative space + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + + if (mDrawable->isActive() && !parentp->isActive()) + { + parentp->makeActive(); + } + else if (mDrawable->isStatic() && parentp->isActive()) + { + mDrawable->makeActive(); + } + } + + return TRUE; +} + +void LLVOVolume::updateFaceFlags() +{ + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) + { + LLFace *face = mDrawable->getFace(i); + if (face) + { + BOOL fullbright = getTE(i)->getFullbright(); + face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); + + if (fullbright || (mMaterial == LL_MCODE_LIGHT)) + { + face->setState(LLFace::FULLBRIGHT); + } + if (mDrawable->isLight()) + { + face->setState(LLFace::LIGHT); + } + if (isHUDAttachment()) + { + face->setState(LLFace::HUD_RENDER); + } + } + } +} BOOL LLVOVolume::setParent(LLViewerObject* parent) { - BOOL ret = FALSE ; + BOOL ret = FALSE ; LLViewerObject *old_parent = (LLViewerObject*) getParent(); - if (parent != old_parent) - { - ret = LLViewerObject::setParent(parent); - if (ret && mDrawable) - { - gPipeline.markMoved(mDrawable); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } + if (parent != old_parent) + { + ret = LLViewerObject::setParent(parent); + if (ret && mDrawable) + { + gPipeline.markMoved(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } onReparent(old_parent, parent); - } + } - return ret ; + return ret ; } // NOTE: regenFaces() MUST be followed by genTriangles()! void LLVOVolume::regenFaces() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - // remove existing faces - BOOL count_changed = mNumFaces != getNumTEs(); - - if (count_changed) - { - deleteFaces(); - // add new faces - mNumFaces = getNumTEs(); - } - - for (S32 i = 0; i < mNumFaces; i++) - { - LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); - if (!facep) continue; - - facep->setTEOffset(i); - facep->setTexture(getTEImage(i)); - if (facep->getTextureEntry()->getMaterialParams().notNull()) - { - facep->setNormalMap(getTENormalMap(i)); - facep->setSpecularMap(getTESpecularMap(i)); - } - facep->setViewerObject(this); - - // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. - // Re-establish the link. - if((int)mMediaImplList.size() > i) - { - if(mMediaImplList[i]) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->addMediaToFace(facep) ; - } - } - } - } - - if (!count_changed) - { - updateFaceFlags(); - } + // remove existing faces + BOOL count_changed = mNumFaces != getNumTEs(); + + if (count_changed) + { + deleteFaces(); + // add new faces + mNumFaces = getNumTEs(); + } + + for (S32 i = 0; i < mNumFaces; i++) + { + LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); + if (!facep) continue; + + facep->setTEOffset(i); + facep->setTexture(getTEImage(i)); + if (facep->getTextureEntry()->getMaterialParams().notNull()) + { + facep->setNormalMap(getTENormalMap(i)); + facep->setSpecularMap(getTESpecularMap(i)); + } + facep->setViewerObject(this); + + // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. + // Re-establish the link. + if((int)mMediaImplList.size() > i) + { + if(mMediaImplList[i]) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->addMediaToFace(facep) ; + } + } + } + } + + if (!count_changed) + { + updateFaceFlags(); + } } BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) @@ -1827,7 +1827,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) mDrawable->setPositionGroup(min); } } - + updateRadius(); mDrawable->movePartition(); } @@ -1841,581 +1841,581 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) void LLVOVolume::preRebuild() { - if (mVolumeImpl != NULL) - { - mVolumeImpl->preRebuild(); - } + if (mVolumeImpl != NULL) + { + mVolumeImpl->preRebuild(); + } } void LLVOVolume::updateRelativeXform(bool force_identity) { - if (mVolumeImpl) - { - mVolumeImpl->updateRelativeXform(force_identity); - return; - } - - LLDrawable* drawable = mDrawable; - - if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) - { //rigged volume (which is in agent space) is used for generating bounding boxes etc - //inverse of render matrix should go to partition space - mRelativeXform = getRenderMatrix(); - - F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; - F32* src = (F32*) mRelativeXform.mMatrix; - dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; - dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; - dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; - - mRelativeXform.invert(); - mRelativeXformInvTrans.transpose(); - } - else if (drawable->isActive() || force_identity) - { - // setup relative transforms - LLQuaternion delta_rot; - LLVector3 delta_pos, delta_scale; - - //matrix from local space to parent relative/global space - bool use_identity = force_identity || drawable->isSpatialRoot(); - delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); - delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); - delta_scale = mDrawable->getScale(); - - // Vertex transform (4x4) - LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; - LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; - - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(delta_pos, 1.f)); - - - // compute inverse transpose for normals - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // mRelativeXformInvTrans.invert(); - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // grumble - invert is NOT a matrix invert, so we do it by hand: - - LLMatrix3 rot_inverse = LLMatrix3(~delta_rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; - - mRelativeXformInvTrans.transpose(); - } - else - { - LLVector3 pos = getPosition(); - LLVector3 scale = getScale(); - LLQuaternion rot = getRotation(); - - if (mParent) - { - pos *= mParent->getRotation(); - pos += mParent->getPosition(); - rot *= mParent->getRotation(); - } - - //LLViewerRegion* region = getRegion(); - //pos += region->getOriginAgent(); - - LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; - LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot; - - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(pos, 1.f)); - - // compute inverse transpose for normals - LLMatrix3 rot_inverse = LLMatrix3(~rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; - - mRelativeXformInvTrans.transpose(); - } + if (mVolumeImpl) + { + mVolumeImpl->updateRelativeXform(force_identity); + return; + } + + LLDrawable* drawable = mDrawable; + + if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) + { //rigged volume (which is in agent space) is used for generating bounding boxes etc + //inverse of render matrix should go to partition space + mRelativeXform = getRenderMatrix(); + + F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; + F32* src = (F32*) mRelativeXform.mMatrix; + dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; + dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; + dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; + + mRelativeXform.invert(); + mRelativeXformInvTrans.transpose(); + } + else if (drawable->isActive() || force_identity) + { + // setup relative transforms + LLQuaternion delta_rot; + LLVector3 delta_pos, delta_scale; + + //matrix from local space to parent relative/global space + bool use_identity = force_identity || drawable->isSpatialRoot(); + delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); + delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); + delta_scale = mDrawable->getScale(); + + // Vertex transform (4x4) + LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; + LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; + LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; + + mRelativeXform.initRows(LLVector4(x_axis, 0.f), + LLVector4(y_axis, 0.f), + LLVector4(z_axis, 0.f), + LLVector4(delta_pos, 1.f)); + + + // compute inverse transpose for normals + // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); + // mRelativeXformInvTrans.invert(); + // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); + // grumble - invert is NOT a matrix invert, so we do it by hand: + + LLMatrix3 rot_inverse = LLMatrix3(~delta_rot); + + LLMatrix3 scale_inverse; + scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX], + LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY], + LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]); + + + mRelativeXformInvTrans = rot_inverse * scale_inverse; + + mRelativeXformInvTrans.transpose(); + } + else + { + LLVector3 pos = getPosition(); + LLVector3 scale = getScale(); + LLQuaternion rot = getRotation(); + + if (mParent) + { + pos *= mParent->getRotation(); + pos += mParent->getPosition(); + rot *= mParent->getRotation(); + } + + //LLViewerRegion* region = getRegion(); + //pos += region->getOriginAgent(); + + LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; + LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; + LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot; + + mRelativeXform.initRows(LLVector4(x_axis, 0.f), + LLVector4(y_axis, 0.f), + LLVector4(z_axis, 0.f), + LLVector4(pos, 1.f)); + + // compute inverse transpose for normals + LLMatrix3 rot_inverse = LLMatrix3(~rot); + + LLMatrix3 scale_inverse; + scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX], + LLVector3(0.0, 1.0, 0.0) / scale.mV[VY], + LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]); + + + mRelativeXformInvTrans = rot_inverse * scale_inverse; + + mRelativeXformInvTrans.transpose(); + } } bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - bool regen_faces = false; + bool regen_faces = false; - LLVolume *old_volumep, *new_volumep; - F32 old_lod, new_lod; - S32 old_num_faces, new_num_faces; + LLVolume *old_volumep, *new_volumep; + F32 old_lod, new_lod; + S32 old_num_faces, new_num_faces; - old_volumep = getVolume(); - old_lod = old_volumep->getDetail(); - old_num_faces = old_volumep->getNumFaces(); - old_volumep = NULL; + old_volumep = getVolume(); + old_lod = old_volumep->getDetail(); + old_num_faces = old_volumep->getNumFaces(); + old_volumep = NULL; - { - const LLVolumeParams &volume_params = getVolume()->getParams(); - setVolume(volume_params, 0); - } + { + const LLVolumeParams &volume_params = getVolume()->getParams(); + setVolume(volume_params, 0); + } - new_volumep = getVolume(); - new_lod = new_volumep->getDetail(); - new_num_faces = new_volumep->getNumFaces(); - new_volumep = NULL; + new_volumep = getVolume(); + new_lod = new_volumep->getDetail(); + new_num_faces = new_volumep->getNumFaces(); + new_volumep = NULL; - if ((new_lod != old_lod) || mSculptChanged) - { + if ((new_lod != old_lod) || mSculptChanged) + { if (mDrawable->isState(LLDrawable::RIGGED)) { updateVisualComplexity(); } - compiled = TRUE; + compiled = TRUE; // new_lod > old_lod breaks a feedback loop between LOD updates and // bounding box updates. should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod; - sNumLODChanges += new_num_faces; - - if ((S32)getNumTEs() != getVolume()->getNumFaces()) - { - setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. - } - - drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() - - { - regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); - if (regen_faces) - { - regenFaces(); - } - - if (mSculptChanged) - { //changes in sculpt maps can thrash an object bounding box without - //triggering a spatial group bounding box update -- force spatial group - //to update bounding boxes - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->unbound(); - } - } - } - } - - return regen_faces; + sNumLODChanges += new_num_faces; + + if ((S32)getNumTEs() != getVolume()->getNumFaces()) + { + setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. + } + + drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() + + { + regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); + if (regen_faces) + { + regenFaces(); + } + + if (mSculptChanged) + { //changes in sculpt maps can thrash an object bounding box without + //triggering a spatial group bounding box update -- force spatial group + //to update bounding boxes + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->unbound(); + } + } + } + } + + return regen_faces; } BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - - if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) - { + + if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) + { updateRiggedVolume(false); - genBBoxes(FALSE); - mDrawable->clearState(LLDrawable::REBUILD_RIGGED); - } - - if (mVolumeImpl != NULL) - { - BOOL res; - { - res = mVolumeImpl->doUpdateGeometry(drawable); - } - updateFaceFlags(); - return res; - } - - LLSpatialGroup* group = drawable->getSpatialGroup(); - if (group) - { + genBBoxes(FALSE); + mDrawable->clearState(LLDrawable::REBUILD_RIGGED); + } + + if (mVolumeImpl != NULL) + { + BOOL res; + { + res = mVolumeImpl->doUpdateGeometry(drawable); + } + updateFaceFlags(); + return res; + } + + LLSpatialGroup* group = drawable->getSpatialGroup(); + if (group) + { group->dirtyMesh(); - } + } + + updateRelativeXform(); - updateRelativeXform(); - - if (mDrawable.isNull()) // Not sure why this is happening, but it is... - { - return TRUE; // No update to complete - } + if (mDrawable.isNull()) // Not sure why this is happening, but it is... + { + return TRUE; // No update to complete + } - BOOL compiled = FALSE; + BOOL compiled = FALSE; // This should be true in most cases, unless we're sure no octree update is // needed. BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3(); - if (mVolumeChanged || mFaceMappingChanged) - { - dirtySpatialGroup(); + if (mVolumeChanged || mFaceMappingChanged) + { + dirtySpatialGroup(); - bool was_regen_faces = false; + bool was_regen_faces = false; should_update_octree_bounds = true; - if (mVolumeChanged) - { + if (mVolumeChanged) + { was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - drawable->setState(LLDrawable::REBUILD_VOLUME); - } - else if (mSculptChanged || mLODChanged || mColorChanged) - { - compiled = TRUE; + drawable->setState(LLDrawable::REBUILD_VOLUME); + } + else if (mSculptChanged || mLODChanged || mColorChanged) + { + compiled = TRUE; was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - } - - if (!was_regen_faces) { - regenFaces(); - } - } - else if (mLODChanged || mSculptChanged || mColorChanged) - { - dirtySpatialGroup(); - compiled = TRUE; + } + + if (!was_regen_faces) { + regenFaces(); + } + } + else if (mLODChanged || mSculptChanged || mColorChanged) + { + dirtySpatialGroup(); + compiled = TRUE; lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - - if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) - { - updateRiggedVolume(false); - } - } - // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local - else - { - compiled = TRUE; - // All it did was move or we changed the texture coordinate offset - } + + if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) + { + updateRiggedVolume(false); + } + } + // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local + else + { + compiled = TRUE; + // All it did was move or we changed the texture coordinate offset + } // Generate bounding boxes if needed, and update the object's size in the // octree genBBoxes(FALSE, should_update_octree_bounds); - // Update face flags - updateFaceFlags(); - - if(compiled) - { - LLPipeline::sCompiles++; - } - - mVolumeChanged = FALSE; - mLODChanged = FALSE; - mSculptChanged = FALSE; - mFaceMappingChanged = FALSE; + // Update face flags + updateFaceFlags(); + + if(compiled) + { + LLPipeline::sCompiles++; + } + + mVolumeChanged = FALSE; + mLODChanged = FALSE; + mSculptChanged = FALSE; + mFaceMappingChanged = FALSE; mColorChanged = FALSE; - - return LLViewerObject::updateGeometry(drawable); + + return LLViewerObject::updateGeometry(drawable); } void LLVOVolume::updateFaceSize(S32 idx) { - if( mDrawable->getNumFaces() <= idx ) - { - return; - } - - LLFace* facep = mDrawable->getFace(idx); - if (facep) - { - if (idx >= getVolume()->getNumVolumeFaces()) - { - facep->setSize(0,0, true); - } - else - { - const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, - true); // <--- volume faces should be padded for 16-byte alignment - - } - } + if( mDrawable->getNumFaces() <= idx ) + { + return; + } + + LLFace* facep = mDrawable->getFace(idx); + if (facep) + { + if (idx >= getVolume()->getNumVolumeFaces()) + { + facep->setSize(0,0, true); + } + else + { + const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment + + } + } } BOOL LLVOVolume::isRootEdit() const { - if (mParent && !((LLViewerObject*)mParent)->isAvatar()) - { - return FALSE; - } - return TRUE; + if (mParent && !((LLViewerObject*)mParent)->isAvatar()) + { + return FALSE; + } + return TRUE; } //virtual void LLVOVolume::setNumTEs(const U8 num_tes) { - const U8 old_num_tes = getNumTEs() ; - - if(old_num_tes && old_num_tes < num_tes) //new faces added - { - LLViewerObject::setNumTEs(num_tes) ; - - if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists. - { - mMediaImplList.resize(num_tes) ; - const LLTextureEntry* te = getTE(old_num_tes - 1) ; - for(U8 i = old_num_tes; i < num_tes ; i++) - { - setTE(i, *te) ; - mMediaImplList[i] = mMediaImplList[old_num_tes -1] ; - } - mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ; - } - } - else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed - { - U8 end = (U8)(mMediaImplList.size()) ; - for(U8 i = num_tes; i < end ; i++) - { - removeMediaImpl(i) ; - } - mMediaImplList.resize(num_tes) ; - - LLViewerObject::setNumTEs(num_tes) ; - } - else - { - LLViewerObject::setNumTEs(num_tes) ; - } - - return ; + const U8 old_num_tes = getNumTEs() ; + + if(old_num_tes && old_num_tes < num_tes) //new faces added + { + LLViewerObject::setNumTEs(num_tes) ; + + if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists. + { + mMediaImplList.resize(num_tes) ; + const LLTextureEntry* te = getTE(old_num_tes - 1) ; + for(U8 i = old_num_tes; i < num_tes ; i++) + { + setTE(i, *te) ; + mMediaImplList[i] = mMediaImplList[old_num_tes -1] ; + } + mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ; + } + } + else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed + { + U8 end = (U8)(mMediaImplList.size()) ; + for(U8 i = num_tes; i < end ; i++) + { + removeMediaImpl(i) ; + } + mMediaImplList.resize(num_tes) ; + + LLViewerObject::setNumTEs(num_tes) ; + } + else + { + LLViewerObject::setNumTEs(num_tes) ; + } + + return ; } //virtual void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) { - BOOL changed = (mTEImages[index] != imagep); - LLViewerObject::changeTEImage(index, imagep); - if (changed) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } + BOOL changed = (mTEImages[index] != imagep); + LLViewerObject::changeTEImage(index, imagep); + if (changed) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } } void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep) { - BOOL changed = (mTEImages[te] != imagep); - LLViewerObject::setTEImage(te, imagep); - if (changed) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } + BOOL changed = (mTEImages[te] != imagep); + LLViewerObject::setTEImage(te, imagep); + if (changed) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } } S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid) { - S32 res = LLViewerObject::setTETexture(te, uuid); - if (res) - { + S32 res = LLViewerObject::setTETexture(te, uuid); + if (res) + { if (mDrawable) { // dynamic texture changes break batches, isolate in octree shrinkWrap(); gPipeline.markTextured(mDrawable); } - mFaceMappingChanged = TRUE; - } - return res; + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) { - return setTEColor(te, LLColor4(color)); + return setTEColor(te, LLColor4(color)); } S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (color != tep->getColor()) - { - F32 old_alpha = tep->getColor().mV[3]; - if (color.mV[3] != old_alpha) - { - gPipeline.markTextured(mDrawable); - //treat this alpha change as an LoD update since render batches may need to get rebuilt - mLODChanged = TRUE; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } - retval = LLPrimitive::setTEColor(te, color); - if (mDrawable.notNull() && retval) - { - // These should only happen on updates which are not the initial update. + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (color != tep->getColor()) + { + F32 old_alpha = tep->getColor().mV[3]; + if (color.mV[3] != old_alpha) + { + gPipeline.markTextured(mDrawable); + //treat this alpha change as an LoD update since render batches may need to get rebuilt + mLODChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } + retval = LLPrimitive::setTEColor(te, color); + if (mDrawable.notNull() && retval) + { + // These should only happen on updates which are not the initial update. mColorChanged = TRUE; - mDrawable->setState(LLDrawable::REBUILD_COLOR); + mDrawable->setState(LLDrawable::REBUILD_COLOR); shrinkWrap(); - dirtyMesh(); - } - } + dirtyMesh(); + } + } - return retval; + return retval; } S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) { - S32 res = LLViewerObject::setTEBumpmap(te, bumpmap); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEBumpmap(te, bumpmap); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTETexGen(const U8 te, const U8 texgen) { - S32 res = LLViewerObject::setTETexGen(te, texgen); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTETexGen(te, texgen); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMediaTexGen(const U8 te, const U8 media) { - S32 res = LLViewerObject::setTEMediaTexGen(te, media); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMediaTexGen(te, media); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny) { - S32 res = LLViewerObject::setTEShiny(te, shiny); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEShiny(te, shiny); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright) { - S32 res = LLViewerObject::setTEFullbright(te, fullbright); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEFullbright(te, fullbright); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) { - S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) { - S32 res = LLViewerObject::setTEMediaFlags(te, media_flags); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMediaFlags(te, media_flags); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) { - S32 res = LLViewerObject::setTEGlow(te, glow); - if (res) - { + S32 res = LLViewerObject::setTEGlow(te, glow); + if (res) + { if (mDrawable) { gPipeline.markTextured(mDrawable); shrinkWrap(); } - mFaceMappingChanged = TRUE; - } - return res; + mFaceMappingChanged = TRUE; + } + return res; } void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te) { - LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); - if (pVol) - { - LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; - if (te >= pVol->getNumTEs()) - return; + LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); + if (pVol) + { + LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; + if (te >= pVol->getNumTEs()) + return; - LLTextureEntry* texture_entry = pVol->getTE(te); - if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) - { - pVol->setTEMaterialParams(te, pMaterialParams); - } - } + LLTextureEntry* texture_entry = pVol->getTE(te); + if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) + { + pVol->setTEMaterialParams(te, pMaterialParams); + } + } } S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) { - S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); - LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res - << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) - << LL_ENDL; - - LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; - if (res) - { - LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); - - setChanged(ALL_CHANGED); - if (!mDrawable.isNull()) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); - } - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); + LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + + LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; + if (res) + { + LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); - LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res - << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) - << LL_ENDL; - setChanged(ALL_CHANGED); - if (!mDrawable.isNull()) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); - } - mFaceMappingChanged = TRUE; - return TEM_CHANGE_TEXTURE; + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + return TEM_CHANGE_TEXTURE; } S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) @@ -2438,230 +2438,230 @@ S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { - S32 res = LLViewerObject::setTEScale(te, s, t); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScale(te, s, t); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEScaleS(const U8 te, const F32 s) { - S32 res = LLViewerObject::setTEScaleS(te, s); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScaleS(te, s); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t) { - S32 res = LLViewerObject::setTEScaleT(te, t); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScaleT(te, t); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } bool LLVOVolume::hasMedia() const { - bool result = false; - const U8 numTEs = getNumTEs(); - for (U8 i = 0; i < numTEs; i++) - { - const LLTextureEntry* te = getTE(i); - if(te->hasMedia()) - { - result = true; - break; - } - } - return result; + bool result = false; + const U8 numTEs = getNumTEs(); + for (U8 i = 0; i < numTEs; i++) + { + const LLTextureEntry* te = getTE(i); + if(te->hasMedia()) + { + result = true; + break; + } + } + return result; } LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id) { - LLVolume* volume = getVolume(); - LLVector4a result; - result.clear(); + LLVolume* volume = getVolume(); + LLVector4a result; + result.clear(); + + LLVector3 ret; - LLVector3 ret; + if (volume && face_id < volume->getNumVolumeFaces()) + { + const LLVolumeFace& face = volume->getVolumeFace(face_id); + for (S32 i = 0; i < (S32)face.mNumVertices; ++i) + { + result.add(face.mNormals[i]); + } - if (volume && face_id < volume->getNumVolumeFaces()) - { - const LLVolumeFace& face = volume->getVolumeFace(face_id); - for (S32 i = 0; i < (S32)face.mNumVertices; ++i) - { - result.add(face.mNormals[i]); - } + LLVector3 ret(result.getF32ptr()); + ret = volumeDirectionToAgent(ret); + ret.normVec(); + } - LLVector3 ret(result.getF32ptr()); - ret = volumeDirectionToAgent(ret); - ret.normVec(); - } - - return ret; + return ret; } void LLVOVolume::requestMediaDataUpdate(bool isNew) { if (sObjectMediaClient) - sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew)); + sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew)); } bool LLVOVolume::isMediaDataBeingFetched() const { - // I know what I'm doing by const_casting this away: this is just - // a wrapper class that is only going to do a lookup. - return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast(this), false)) : false; + // I know what I'm doing by const_casting this away: this is just + // a wrapper class that is only going to do a lookup. + return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast(this), false)) : false; } void LLVOVolume::cleanUpMediaImpls() { - // Iterate through our TEs and remove any Impls that are no longer used - const U8 numTEs = getNumTEs(); - for (U8 i = 0; i < numTEs; i++) - { - const LLTextureEntry* te = getTE(i); - if( ! te->hasMedia()) - { - // Delete the media IMPL! - removeMediaImpl(i) ; - } - } + // Iterate through our TEs and remove any Impls that are no longer used + const U8 numTEs = getNumTEs(); + for (U8 i = 0; i < numTEs; i++) + { + const LLTextureEntry* te = getTE(i); + if( ! te->hasMedia()) + { + // Delete the media IMPL! + removeMediaImpl(i) ; + } + } } void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version) { - // media_data_array is an array of media entry maps - // media_version is the version string in the response. - U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version); - - // Only update it if it is newer! - if ( (S32)fetched_version > mLastFetchedMediaVersion) - { - mLastFetchedMediaVersion = fetched_version; - //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL; - - LLSD::array_const_iterator iter = media_data_array.beginArray(); - LLSD::array_const_iterator end = media_data_array.endArray(); - U8 texture_index = 0; - for (; iter != end; ++iter, ++texture_index) - { - syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/); - } - } + // media_data_array is an array of media entry maps + // media_version is the version string in the response. + U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version); + + // Only update it if it is newer! + if ( (S32)fetched_version > mLastFetchedMediaVersion) + { + mLastFetchedMediaVersion = fetched_version; + //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL; + + LLSD::array_const_iterator iter = media_data_array.beginArray(); + LLSD::array_const_iterator end = media_data_array.endArray(); + U8 texture_index = 0; + for (; iter != end; ++iter, ++texture_index) + { + syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/); + } + } } void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent) { - if(mDead) - { - // If the object has been marked dead, don't process media updates. - return; - } - - LLTextureEntry *te = getTE(texture_index); - if(!te) - { - return ; - } - - LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index - << " hasMedia = " << te->hasMedia() << " : " - << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; - - std::string previous_url; - LLMediaEntry* mep = te->getMediaData(); - if(mep) - { - // Save the "current url" from before the update so we can tell if - // it changes. - previous_url = mep->getCurrentURL(); - } - - if (merge) - { - te->mergeIntoMediaData(media_data); - } - else { - // XXX Question: what if the media data is undefined LLSD, but the - // update we got above said that we have media flags?? Here we clobber - // that, assuming the data from the service is more up-to-date. - te->updateMediaData(media_data); - } - - mep = te->getMediaData(); - if(mep) - { - bool update_from_self = false; - if (!ignore_agent) - { - LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL()); - update_from_self = (updating_agent == gAgent.getID()); - } - viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); - - addMediaImpl(media_impl, texture_index) ; - } - else - { - removeMediaImpl(texture_index); - } - - LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index - << " hasMedia = " << te->hasMedia() << " : " - << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; + if(mDead) + { + // If the object has been marked dead, don't process media updates. + return; + } + + LLTextureEntry *te = getTE(texture_index); + if(!te) + { + return ; + } + + LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index + << " hasMedia = " << te->hasMedia() << " : " + << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; + + std::string previous_url; + LLMediaEntry* mep = te->getMediaData(); + if(mep) + { + // Save the "current url" from before the update so we can tell if + // it changes. + previous_url = mep->getCurrentURL(); + } + + if (merge) + { + te->mergeIntoMediaData(media_data); + } + else { + // XXX Question: what if the media data is undefined LLSD, but the + // update we got above said that we have media flags?? Here we clobber + // that, assuming the data from the service is more up-to-date. + te->updateMediaData(media_data); + } + + mep = te->getMediaData(); + if(mep) + { + bool update_from_self = false; + if (!ignore_agent) + { + LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL()); + update_from_self = (updating_agent == gAgent.getID()); + } + viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); + + addMediaImpl(media_impl, texture_index) ; + } + else + { + removeMediaImpl(texture_index); + } + + LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index + << " hasMedia = " << te->hasMedia() << " : " + << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; } void LLVOVolume::mediaNavigateBounceBack(U8 texture_index) { - // Find the media entry for this navigate - const LLMediaEntry* mep = NULL; - viewer_media_t impl = getMediaImpl(texture_index); - LLTextureEntry *te = getTE(texture_index); - if(te) - { - mep = te->getMediaData(); - } - - if (mep && impl) - { + // Find the media entry for this navigate + const LLMediaEntry* mep = NULL; + viewer_media_t impl = getMediaImpl(texture_index); + LLTextureEntry *te = getTE(texture_index); + if(te) + { + mep = te->getMediaData(); + } + + if (mep && impl) + { std::string url = mep->getCurrentURL(); - // Look for a ":", if not there, assume "http://" - if (!url.empty() && std::string::npos == url.find(':')) - { - url = "http://" + url; - } - // If the url we're trying to "bounce back" to is either empty or not - // allowed by the whitelist, try the home url. If *that* doesn't work, - // set the media as failed and unload it + // Look for a ":", if not there, assume "http://" + if (!url.empty() && std::string::npos == url.find(':')) + { + url = "http://" + url; + } + // If the url we're trying to "bounce back" to is either empty or not + // allowed by the whitelist, try the home url. If *that* doesn't work, + // set the media as failed and unload it if (url.empty() || !mep->checkCandidateUrl(url)) { url = mep->getHomeURL(); - // Look for a ":", if not there, assume "http://" - if (!url.empty() && std::string::npos == url.find(':')) - { - url = "http://" + url; - } + // Look for a ":", if not there, assume "http://" + if (!url.empty() && std::string::npos == url.find(':')) + { + url = "http://" + url; + } } if (url.empty() || !mep->checkCandidateUrl(url)) - { - // The url to navigate back to is not good, and we have nowhere else - // to go. - LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL; - impl->setMediaFailed(true); - } - // Make sure we are not bouncing to url we came from - else if (impl->getCurrentMediaURL() != url) - { - // Okay, navigate now + { + // The url to navigate back to is not good, and we have nowhere else + // to go. + LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL; + impl->setMediaFailed(true); + } + // Make sure we are not bouncing to url we came from + else if (impl->getCurrentMediaURL() != url) + { + // Okay, navigate now LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL; impl->navigateTo(url, "", false, true); } @@ -2672,153 +2672,153 @@ bool LLVOVolume::hasMediaPermission(const LLMediaEntry* media_entry, MediaPermTy { // NOTE: This logic ALMOST duplicates the logic in the server (in particular, in llmediaservice.cpp). if (NULL == media_entry ) return false; // XXX should we assert here? - + // The agent has permissions if: // - world permissions are on, or // - group permissions are on, and agent_id is in the group, or // - agent permissions are on, and agent_id is the owner - - // *NOTE: We *used* to check for modify permissions here (i.e. permissions were - // granted if permModify() was true). However, this doesn't make sense in the - // viewer: we don't want to show controls or allow interaction if the author - // has deemed it so. See DEV-42115. - + + // *NOTE: We *used* to check for modify permissions here (i.e. permissions were + // granted if permModify() was true). However, this doesn't make sense in the + // viewer: we don't want to show controls or allow interaction if the author + // has deemed it so. See DEV-42115. + U8 media_perms = (perm_type == MEDIA_PERM_INTERACT) ? media_entry->getPermsInteract() : media_entry->getPermsControl(); - + // World permissions - if (0 != (media_perms & LLMediaEntry::PERM_ANYONE)) + if (0 != (media_perms & LLMediaEntry::PERM_ANYONE)) { return true; } - + // Group permissions else if (0 != (media_perms & LLMediaEntry::PERM_GROUP)) { - LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); - if (obj_perm && gAgent.isInGroup(obj_perm->getGroup())) - { - return true; - } + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); + if (obj_perm && gAgent.isInGroup(obj_perm->getGroup())) + { + return true; + } } - + // Owner permissions - else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner()) + else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner()) { return true; } - + return false; - + } void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location) { - bool block_navigation = false; - // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed - // to deal with multiple face indices. - int face_index = getFaceIndexWithMediaImpl(impl, -1); - - // Find the media entry for this navigate - LLMediaEntry* mep = NULL; - LLTextureEntry *te = getTE(face_index); - if(te) - { - mep = te->getMediaData(); - } - - if(mep) - { - if(!mep->checkCandidateUrl(new_location)) - { - block_navigation = true; - } - if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT)) - { - block_navigation = true; - } - } - else - { - LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL; - } - - if(block_navigation) - { - LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL; - - // "bounce back" to the current URL from the media entry - mediaNavigateBounceBack(face_index); - } - else if (sObjectMediaNavigateClient) - { - - LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL; - - sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location); - } + bool block_navigation = false; + // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed + // to deal with multiple face indices. + int face_index = getFaceIndexWithMediaImpl(impl, -1); + + // Find the media entry for this navigate + LLMediaEntry* mep = NULL; + LLTextureEntry *te = getTE(face_index); + if(te) + { + mep = te->getMediaData(); + } + + if(mep) + { + if(!mep->checkCandidateUrl(new_location)) + { + block_navigation = true; + } + if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT)) + { + block_navigation = true; + } + } + else + { + LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL; + } + + if(block_navigation) + { + LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL; + + // "bounce back" to the current URL from the media entry + mediaNavigateBounceBack(face_index); + } + else if (sObjectMediaNavigateClient) + { + + LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL; + + sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location); + } } void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event) { - switch(event) - { - - case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: - { - switch(impl->getNavState()) - { - case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED: - { - // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. - mediaNavigated(impl, plugin, plugin->getLocation()); - } - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: - // This navigate didn't change the current URL. - LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: - // This is the first location changed event after the start of a server-directed nav. Don't broadcast it. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; - break; - - default: - // This is a subsequent location-changed due to a redirect. Don't broadcast. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL; - break; - } - } - break; - - case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: - { - switch(impl->getNavState()) - { - case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: - { - // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. - mediaNavigated(impl, plugin, plugin->getNavigateURI()); - } - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: - // This navigate didn't change the current URL. - LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: - // This is the the navigate complete event from a server-directed nav. Don't broadcast it. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; - break; - - default: - // For all other states, the navigate should have been handled by LOCATION_CHANGED events already. - break; - } - } - break; + switch(event) + { + + case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: + { + switch(impl->getNavState()) + { + case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED: + { + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getLocation()); + } + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: + // This navigate didn't change the current URL. + LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: + // This is the first location changed event after the start of a server-directed nav. Don't broadcast it. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; + break; + + default: + // This is a subsequent location-changed due to a redirect. Don't broadcast. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL; + break; + } + } + break; + + case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: + { + switch(impl->getNavState()) + { + case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: + { + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getNavigateURI()); + } + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: + // This navigate didn't change the current URL. + LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: + // This is the the navigate complete event from a server-directed nav. Don't broadcast it. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; + break; + + default: + // For all other states, the navigate should have been handled by LOCATION_CHANGED events already. + break; + } + } + break; case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD: { @@ -2830,233 +2830,233 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLNotificationsUtil::add("MediaFileDownloadUnsupported"); } break; - - default: - break; - } + + default: + break; + } } void LLVOVolume::sendMediaDataUpdate() { if (sObjectMediaClient) - sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false)); + sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false)); } void LLVOVolume::removeMediaImpl(S32 texture_index) { - if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull()) - { - return ; - } - - //make the face referencing to mMediaImplList[texture_index] to point back to the old texture. - if(mDrawable && texture_index < mDrawable->getNumFaces()) - { - LLFace* facep = mDrawable->getFace(texture_index) ; - if(facep) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->removeMediaFromFace(facep) ; - } - } - } - - //check if some other face(s) of this object reference(s)to this media impl. - S32 i ; - S32 end = (S32)mMediaImplList.size() ; - for(i = 0; i < end ; i++) - { - if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index]) - { - break ; - } - } - - if(i == end) //this object does not need this media impl. - { - mMediaImplList[texture_index]->removeObject(this) ; - } - - mMediaImplList[texture_index] = NULL ; - return ; + if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull()) + { + return ; + } + + //make the face referencing to mMediaImplList[texture_index] to point back to the old texture. + if(mDrawable && texture_index < mDrawable->getNumFaces()) + { + LLFace* facep = mDrawable->getFace(texture_index) ; + if(facep) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->removeMediaFromFace(facep) ; + } + } + } + + //check if some other face(s) of this object reference(s)to this media impl. + S32 i ; + S32 end = (S32)mMediaImplList.size() ; + for(i = 0; i < end ; i++) + { + if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index]) + { + break ; + } + } + + if(i == end) //this object does not need this media impl. + { + mMediaImplList[texture_index]->removeObject(this) ; + } + + mMediaImplList[texture_index] = NULL ; + return ; } void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) { - if((S32)mMediaImplList.size() < texture_index + 1) - { - mMediaImplList.resize(texture_index + 1) ; - } - - if(mMediaImplList[texture_index].notNull()) - { - if(mMediaImplList[texture_index] == media_impl) - { - return ; - } - - removeMediaImpl(texture_index) ; - } - - mMediaImplList[texture_index] = media_impl; - media_impl->addObject(this) ; - - //add the face to show the media if it is in playing - if(mDrawable) - { - LLFace* facep(NULL); - if( texture_index < mDrawable->getNumFaces() ) - { - facep = mDrawable->getFace(texture_index) ; - } - - if(facep) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->addMediaToFace(facep) ; - } - } - else //the face is not available now, start media on this face later. - { - media_impl->setUpdated(TRUE) ; - } - } - return ; + if((S32)mMediaImplList.size() < texture_index + 1) + { + mMediaImplList.resize(texture_index + 1) ; + } + + if(mMediaImplList[texture_index].notNull()) + { + if(mMediaImplList[texture_index] == media_impl) + { + return ; + } + + removeMediaImpl(texture_index) ; + } + + mMediaImplList[texture_index] = media_impl; + media_impl->addObject(this) ; + + //add the face to show the media if it is in playing + if(mDrawable) + { + LLFace* facep(NULL); + if( texture_index < mDrawable->getNumFaces() ) + { + facep = mDrawable->getFace(texture_index) ; + } + + if(facep) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->addMediaToFace(facep) ; + } + } + else //the face is not available now, start media on this face later. + { + media_impl->setUpdated(TRUE) ; + } + } + return ; } viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const { - if(mMediaImplList.size() > face_id) - { - return mMediaImplList[face_id]; - } - return NULL; + if(mMediaImplList.size() > face_id) + { + return mMediaImplList[face_id]; + } + return NULL; } F64 LLVOVolume::getTotalMediaInterest() const { - // If this object is currently focused, this object has "high" interest - if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID()) - return F64_MAX; - - F64 interest = (F64)-1.0; // means not interested; - - // If this object is selected, this object has "high" interest, but since - // there can be more than one, we still add in calculated impl interest - // XXX Sadly, 'contains()' doesn't take a const :( - if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this))) - interest = F64_MAX / 2.0; - - int i = 0; - const int end = getNumTEs(); - for ( ; i < end; ++i) - { - const viewer_media_t &impl = getMediaImpl(i); - if (!impl.isNull()) - { - if (interest == (F64)-1.0) interest = (F64)0.0; - interest += impl->getInterest(); - } - } - return interest; + // If this object is currently focused, this object has "high" interest + if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID()) + return F64_MAX; + + F64 interest = (F64)-1.0; // means not interested; + + // If this object is selected, this object has "high" interest, but since + // there can be more than one, we still add in calculated impl interest + // XXX Sadly, 'contains()' doesn't take a const :( + if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this))) + interest = F64_MAX / 2.0; + + int i = 0; + const int end = getNumTEs(); + for ( ; i < end; ++i) + { + const viewer_media_t &impl = getMediaImpl(i); + if (!impl.isNull()) + { + if (interest == (F64)-1.0) interest = (F64)0.0; + interest += impl->getInterest(); + } + } + return interest; } S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id) { - S32 end = (S32)mMediaImplList.size() ; - for(S32 face_id = start_face_id + 1; face_id < end; face_id++) - { - if(mMediaImplList[face_id] == media_impl) - { - return face_id ; - } - } - return -1 ; + S32 end = (S32)mMediaImplList.size() ; + for(S32 face_id = start_face_id + 1; face_id < end; face_id++) + { + if(mMediaImplList[face_id] == media_impl) + { + return face_id ; + } + } + return -1 ; } //---------------------------------------------------------------------------- void LLVOVolume::setLightTextureID(LLUUID id) { - LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary - if (id.notNull()) - { - if (!hasLightTexture()) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); - } - else if (old_texturep) - { - old_texturep->removeVolume(LLRender::LIGHT_TEX, this); - } - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getLightTexture() != id) - { - param_block->setLightTexture(id); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } - LLViewerTexture* tex = getLightTexture(); - if (tex) - { - tex->addVolume(LLRender::LIGHT_TEX, this); // new texture - } - else - { - LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL; - } - } - else if (hasLightTexture()) - { - if (old_texturep) - { - old_texturep->removeVolume(LLRender::LIGHT_TEX, this); - } - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - mLightTexture = NULL; - } + LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary + if (id.notNull()) + { + if (!hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); + } + else if (old_texturep) + { + old_texturep->removeVolume(LLRender::LIGHT_TEX, this); + } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getLightTexture() != id) + { + param_block->setLightTexture(id); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } + LLViewerTexture* tex = getLightTexture(); + if (tex) + { + tex->addVolume(LLRender::LIGHT_TEX, this); // new texture + } + else + { + LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL; + } + } + else if (hasLightTexture()) + { + if (old_texturep) + { + old_texturep->removeVolume(LLRender::LIGHT_TEX, this); + } + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + mLightTexture = NULL; + } } void LLVOVolume::setSpotLightParams(LLVector3 params) { - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getParams() != params) - { - param_block->setParams(params); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getParams() != params) + { + param_block->setParams(params); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } } - + void LLVOVolume::setIsLight(BOOL is_light) { - BOOL was_light = getIsLight(); - if (is_light != was_light) - { - if (is_light) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); - } - else - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true); - } - - if (is_light) - { - // Add it to the pipeline mLightSet - gPipeline.setLight(mDrawable, TRUE); - } - else - { - // Not a light. Remove it from the pipeline's light set. - gPipeline.setLight(mDrawable, FALSE); - } - } + BOOL was_light = getIsLight(); + if (is_light != was_light) + { + if (is_light) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true); + } + + if (is_light) + { + // Add it to the pipeline mLightSet + gPipeline.setLight(mDrawable, TRUE); + } + else + { + // Not a light. Remove it from the pipeline's light set. + gPipeline.setLight(mDrawable, FALSE); + } + } } void LLVOVolume::setLightSRGBColor(const LLColor3& color) @@ -3066,69 +3066,69 @@ void LLVOVolume::setLightSRGBColor(const LLColor3& color) void LLVOVolume::setLightLinearColor(const LLColor3& color) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getLinearColor() != color) - { - param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3])); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getLinearColor() != color) + { + param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3])); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + } } void LLVOVolume::setLightIntensity(F32 intensity) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getLinearColor().mV[3] != intensity) - { - param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity)); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getLinearColor().mV[3] != intensity) + { + param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity)); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightRadius(F32 radius) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getRadius() != radius) - { - param_block->setRadius(radius); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getRadius() != radius) + { + param_block->setRadius(radius); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightFalloff(F32 falloff) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getFalloff() != falloff) - { - param_block->setFalloff(falloff); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getFalloff() != falloff) + { + param_block->setFalloff(falloff); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightCutoff(F32 cutoff) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getCutoff() != cutoff) - { - param_block->setCutoff(cutoff); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getCutoff() != cutoff) + { + param_block->setCutoff(cutoff); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } //---------------------------------------------------------------------------- @@ -3151,15 +3151,15 @@ LLColor3 LLVOVolume::getLightSRGBBaseColor() const LLColor3 LLVOVolume::getLightLinearBaseColor() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return LLColor3(param_block->getLinearColor()); - } - else - { - return LLColor3(1,1,1); - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return LLColor3(param_block->getLinearColor()); + } + else + { + return LLColor3(1,1,1); + } } LLColor3 LLVOVolume::getLightLinearColor() const @@ -3184,36 +3184,36 @@ LLColor3 LLVOVolume::getLightSRGBColor() const LLUUID LLVOVolume::getLightTextureID() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getLightTexture(); - } - } - - return LLUUID::null; -} - - -LLVector3 LLVOVolume::getSpotLightParams() const + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getLightTexture(); + } + } + + return LLUUID::null; +} + + +LLVector3 LLVOVolume::getSpotLightParams() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getParams(); - } - } - - return LLVector3(); + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getParams(); + } + } + + return LLVector3(); } F32 LLVOVolume::getSpotLightPriority() const { - return mSpotLightPriority; + return mSpotLightPriority; } void LLVOVolume::updateSpotLightPriority() @@ -3224,104 +3224,104 @@ void LLVOVolume::updateSpotLightPriority() } F32 r = getLightRadius(); - LLVector3 pos = mDrawable->getPositionAgent(); + LLVector3 pos = mDrawable->getPositionAgent(); - LLVector3 at(0,0,-1); - at *= getRenderRotation(); - pos += at * r; + LLVector3 at(0,0,-1); + at *= getRenderRotation(); + pos += at * r; - at = LLViewerCamera::getInstance()->getAtAxis(); - pos -= at * r; + at = LLViewerCamera::getInstance()->getAtAxis(); + pos -= at * r; - mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); + mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); - if (mLightTexture.notNull()) - { - mLightTexture->addTextureStats(mSpotLightPriority); - } + if (mLightTexture.notNull()) + { + mLightTexture->addTextureStats(mSpotLightPriority); + } } bool LLVOVolume::isLightSpotlight() const { - LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - return params->isLightSpotlight(); - } - return false; + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return params->isLightSpotlight(); + } + return false; } LLViewerTexture* LLVOVolume::getLightTexture() { - LLUUID id = getLightTextureID(); + LLUUID id = getLightTextureID(); - if (id.notNull()) - { - if (mLightTexture.isNull() || id != mLightTexture->getID()) - { - mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); - } - } - else - { - mLightTexture = NULL; - } + if (id.notNull()) + { + if (mLightTexture.isNull() || id != mLightTexture->getID()) + { + mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); + } + } + else + { + mLightTexture = NULL; + } - return mLightTexture; + return mLightTexture; } F32 LLVOVolume::getLightIntensity() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getLinearColor().mV[3]; - } - else - { - return 1.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getLinearColor().mV[3]; + } + else + { + return 1.f; + } } F32 LLVOVolume::getLightRadius() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getRadius(); - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getRadius(); + } + else + { + return 0.f; + } } F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getFalloff() * fudge_factor; - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getFalloff() * fudge_factor; + } + else + { + return 0.f; + } } F32 LLVOVolume::getLightCutoff() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getCutoff(); - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getCutoff(); + } + else + { + return 0.f; + } } BOOL LLVOVolume::isReflectionProbe() const @@ -3424,10 +3424,10 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror) param_block->setIsMirror(is_mirror); parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); - if (!is_mirror) - gPipeline.mHeroProbeManager.unregisterViewerObject(this); - else - gPipeline.mHeroProbeManager.registerViewerObject(this); + if (!is_mirror) + gPipeline.mHeroProbeManager.unregisterViewerObject(this); + else + gPipeline.mHeroProbeManager.registerViewerObject(this); return true; } @@ -3469,7 +3469,7 @@ bool LLVOVolume::getReflectionProbeIsBox() const { return param_block->getIsBox(); } - + return false; } @@ -3498,68 +3498,68 @@ bool LLVOVolume::getReflectionProbeIsMirror() const U32 LLVOVolume::getVolumeInterfaceID() const { - if (mVolumeImpl) - { - return mVolumeImpl->getID(); - } + if (mVolumeImpl) + { + return mVolumeImpl->getID(); + } - return 0; + return 0; } BOOL LLVOVolume::isFlexible() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) - { - LLVolume* volume = getVolume(); - if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) - { - LLVolumeParams volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); - } - return TRUE; - } - else - { - return FALSE; - } + if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) + { + LLVolume* volume = getVolume(); + if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) + { + LLVolumeParams volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); + } + return TRUE; + } + else + { + return FALSE; + } } BOOL LLVOVolume::isSculpted() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) - { - return TRUE; - } - - return FALSE; + if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + return TRUE; + } + + return FALSE; } BOOL LLVOVolume::isMesh() const { - if (isSculpted()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - U8 sculpt_type = sculpt_params->getSculptType(); + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + U8 sculpt_type = sculpt_params->getSculptType(); - if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - // mesh is a mesh - { - return TRUE; - } - } + if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + // mesh is a mesh + { + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLVOVolume::hasLightTexture() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - return TRUE; - } + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return TRUE; + } - return FALSE; + return FALSE; } bool LLVOVolume::isFlexibleFast() const @@ -3589,67 +3589,67 @@ bool LLVOVolume::isAnimatedObjectFast() const BOOL LLVOVolume::isVolumeGlobal() const { - if (mVolumeImpl) - { - return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; - } - else if (mRiggedVolume.notNull()) - { - return TRUE; - } + if (mVolumeImpl) + { + return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; + } + else if (mRiggedVolume.notNull()) + { + return TRUE; + } - return FALSE; + return FALSE; } BOOL LLVOVolume::canBeFlexible() const { - U8 path = getVolume()->getParams().getPathParams().getCurveType(); - return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE); + U8 path = getVolume()->getParams().getPathParams().getCurveType(); + return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE); } BOOL LLVOVolume::setIsFlexible(BOOL is_flexible) { - BOOL res = FALSE; - BOOL was_flexible = isFlexible(); - LLVolumeParams volume_params; - if (is_flexible) - { - if (!was_flexible) - { - volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); - res = TRUE; - setFlags(FLAGS_USE_PHYSICS, FALSE); - setFlags(FLAGS_PHANTOM, TRUE); - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); - if (mDrawable) - { - mDrawable->makeActive(); - } - } - } - else - { - if (was_flexible) - { - volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE); - res = TRUE; - setFlags(FLAGS_PHANTOM, FALSE); - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true); - } - } - if (res) - { - res = setVolume(volume_params, 1); - if (res) - { - markForUpdate(); - } - } - return res; + BOOL res = FALSE; + BOOL was_flexible = isFlexible(); + LLVolumeParams volume_params; + if (is_flexible) + { + if (!was_flexible) + { + volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); + res = TRUE; + setFlags(FLAGS_USE_PHYSICS, FALSE); + setFlags(FLAGS_PHANTOM, TRUE); + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); + if (mDrawable) + { + mDrawable->makeActive(); + } + } + } + else + { + if (was_flexible) + { + volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE); + res = TRUE; + setFlags(FLAGS_PHANTOM, FALSE); + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true); + } + } + if (res) + { + res = setVolume(volume_params, 1); + if (res) + { + markForUpdate(); + } + } + return res; } const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const @@ -3673,16 +3673,16 @@ BOOL LLVOVolume::isRiggedMesh() const //---------------------------------------------------------------------------- U32 LLVOVolume::getExtendedMeshFlags() const { - const LLExtendedMeshParams *param_block = + const LLExtendedMeshParams *param_block = (const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH); - if (param_block) - { - return param_block->getFlags(); - } - else - { - return 0; - } + if (param_block) + { + return param_block->getFlags(); + } + else + { + return 0; + } } void LLVOVolume::onSetExtendedMeshFlags(U32 flags) @@ -3691,7 +3691,7 @@ void LLVOVolume::onSetExtendedMeshFlags(U32 flags) // The isAnySelected() check was needed at one point to prevent // graphics problems. These are now believed to be fixed so the // check has been disabled. - if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull()) + if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull()) { // Need to trigger rebuildGeom(), which is where control avatars get created/removed getRootEdit()->recursiveMarkForUpdate(); @@ -3719,7 +3719,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags) { bool in_use = true; setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true); - LLExtendedMeshParams *param_block = + LLExtendedMeshParams *param_block = (LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH); if (param_block) { @@ -3789,13 +3789,13 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare void LLVOVolume::afterReparent() { { - LL_DEBUGS("AnimatedObjects") << "new child added for parent " + LL_DEBUGS("AnimatedObjects") << "new child added for parent " << ((LLViewerObject*)getParent())->getID() << LL_ENDL; } - + if (isAnimatedObject() && getControlAvatar()) { - LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object " + LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object " << ((LLViewerObject*)getParent())->getID() << LL_ENDL; // MAINT-8239 - doing a full rebuild whenever parent is set @@ -3803,15 +3803,15 @@ void LLVOVolume::afterReparent() // addAttachmentOverrides should be sufficient, but in // practice doing a full rebuild helps compensate for // notifyMeshLoaded() not being called reliably enough. - + // was: getControlAvatar()->addAttachmentOverridesForObject(this); //getControlAvatar()->rebuildAttachmentOverrides(); getControlAvatar()->updateAnimations(); } else { - LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: " - << ((LLViewerObject*)getParent())->getID() + LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: " + << ((LLViewerObject*)getParent())->getID() << " isAnimated: " << isAnimatedObject() << " cav " << getControlAvatar() << LL_ENDL; } @@ -3844,8 +3844,8 @@ void LLVOVolume::updateRiggingInfo() } // Keep the highest LOD info available. mLastRiggingInfoLOD = getLOD(); - LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " - << this << " lod " << mLastRiggingInfoLOD + LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " + << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; } } @@ -3856,86 +3856,86 @@ void LLVOVolume::updateRiggingInfo() void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) { - LLVolume *volume = getVolume(); - - if (volume) - { - LLVector3 view_vector; - view_vector = view_point; - - //transform view vector into volume space - view_vector -= getRenderPosition(); - //mDrawable->mDistanceWRTCamera = view_vector.length(); - LLQuaternion worldRot = getRenderRotation(); - view_vector = view_vector * ~worldRot; - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - view_vector.scaleVec(invObjScale); - } - - updateRelativeXform(); - LLMatrix4 trans_mat = mRelativeXform; - if (mDrawable->isStatic()) - { - trans_mat.translate(getRegion()->getOriginAgent()); - } - - volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); - - nodep->mSilhouetteExists = TRUE; - } + LLVolume *volume = getVolume(); + + if (volume) + { + LLVector3 view_vector; + view_vector = view_point; + + //transform view vector into volume space + view_vector -= getRenderPosition(); + //mDrawable->mDistanceWRTCamera = view_vector.length(); + LLQuaternion worldRot = getRenderRotation(); + view_vector = view_vector * ~worldRot; + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + view_vector.scaleVec(invObjScale); + } + + updateRelativeXform(); + LLMatrix4 trans_mat = mRelativeXform; + if (mDrawable->isStatic()) + { + trans_mat.translate(getRegion()->getOriginAgent()); + } + + volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); + + nodep->mSilhouetteExists = TRUE; + } } void LLVOVolume::deleteFaces() { - S32 face_count = mNumFaces; - if (mDrawable.notNull()) - { - mDrawable->deleteFaces(0, face_count); - } + S32 face_count = mNumFaces; + if (mDrawable.notNull()) + { + mDrawable->deleteFaces(0, face_count); + } - mNumFaces = 0; + mNumFaces = 0; } void LLVOVolume::updateRadius() { - if (mDrawable.isNull()) - { - return; - } - - mVObjRadius = getScale().length(); - mDrawable->setRadius(mVObjRadius); + if (mDrawable.isNull()) + { + return; + } + + mVObjRadius = getScale().length(); + mDrawable->setRadius(mVObjRadius); } BOOL LLVOVolume::isAttachment() const { - return mAttachmentState != 0 ; + return mAttachmentState != 0 ; } BOOL LLVOVolume::isHUDAttachment() const { - // *NOTE: we assume hud attachment points are in defined range - // since this range is constant for backwards compatibility - // reasons this is probably a reasonable assumption to make - S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState); - return ( attachment_id >= 31 && attachment_id <= 38 ); + // *NOTE: we assume hud attachment points are in defined range + // since this range is constant for backwards compatibility + // reasons this is probably a reasonable assumption to make + S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState); + return ( attachment_id >= 31 && attachment_id <= 38 ); } const LLMatrix4 LLVOVolume::getRenderMatrix() const { - if (mDrawable->isActive() && !mDrawable->isRoot()) - { - return mDrawable->getParent()->getWorldMatrix(); - } - return mDrawable->getWorldMatrix(); + if (mDrawable->isActive() && !mDrawable->isRoot()) + { + return mDrawable->getParent()->getWorldMatrix(); + } + return mDrawable->getWorldMatrix(); } -//static +//static S32 LLVOVolume::getTextureCost(const LLViewerTexture* img) { static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested @@ -3977,57 +3977,57 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const * the official viewer for consideration. *****************************************************************/ - // Get access to params we'll need at various points. - // Skip if this is object doesn't have a volume (e.g. is an avatar). + // Get access to params we'll need at various points. + // Skip if this is object doesn't have a volume (e.g. is an avatar). if (getVolume() == NULL) { return 0; } - U32 num_triangles = 0; + U32 num_triangles = 0; - // per-prim costs - static const U32 ARC_PARTICLE_COST = 1; // determined experimentally - static const U32 ARC_PARTICLE_MAX = 2048; // default values - static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims - static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face + // per-prim costs + static const U32 ARC_PARTICLE_COST = 1; // determined experimentally + static const U32 ARC_PARTICLE_MAX = 2048; // default values + static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims + static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face - // per-prim multipliers - static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance - static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance - static const F32 ARC_FLEXI_MULT = 5; // tested based on performance - static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance - static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance - static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance + // per-prim multipliers + static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance + static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance + static const F32 ARC_FLEXI_MULT = 5; // tested based on performance + static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance + static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance + static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance - static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact - static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance - static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance + static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact + static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance + static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance - F32 shame = 0; + F32 shame = 0; - U32 invisi = 0; - U32 shiny = 0; - U32 glow = 0; - U32 alpha = 0; - U32 flexi = 0; - U32 animtex = 0; - U32 particles = 0; - U32 bump = 0; - U32 planar = 0; - U32 weighted_mesh = 0; - U32 produces_light = 0; - U32 media_faces = 0; + U32 invisi = 0; + U32 shiny = 0; + U32 glow = 0; + U32 alpha = 0; + U32 flexi = 0; + U32 animtex = 0; + U32 particles = 0; + U32 bump = 0; + U32 planar = 0; + U32 weighted_mesh = 0; + U32 produces_light = 0; + U32 media_faces = 0; - const LLDrawable* drawablep = mDrawable; - U32 num_faces = drawablep->getNumFaces(); + const LLDrawable* drawablep = mDrawable; + U32 num_faces = drawablep->getNumFaces(); - const LLVolumeParams& volume_params = getVolume()->getParams(); + const LLVolumeParams& volume_params = getVolume()->getParams(); LLMeshCostData costs; - if (getCostData(costs)) - { + if (getCostData(costs)) + { if (isAnimatedObjectFast() && isRiggedMeshFast()) { // Scaling here is to make animated object vs @@ -4040,58 +4040,58 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const F32 radius = getScale().length()*0.5f; num_triangles = costs.getRadiusWeightedTris(radius); } - } - - - if (num_triangles <= 0) - { - num_triangles = 4; - } - - if (isSculptedFast()) - { - if (isMeshFast()) - { - // base cost is dependent on mesh complexity - // note that 3 is the highest LOD as of the time of this coding. - S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); - if ( size > 0) - { - if (isRiggedMeshFast()) - { - // weighted attachment - 1 point for every 3 bytes - weighted_mesh = 1; - } - } - else - { - // something went wrong - user should know their content isn't render-free - return 0; - } - } - else - { + } + + + if (num_triangles <= 0) + { + num_triangles = 4; + } + + if (isSculptedFast()) + { + if (isMeshFast()) + { + // base cost is dependent on mesh complexity + // note that 3 is the highest LOD as of the time of this coding. + S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); + if ( size > 0) + { + if (isRiggedMeshFast()) + { + // weighted attachment - 1 point for every 3 bytes + weighted_mesh = 1; + } + } + else + { + // something went wrong - user should know their content isn't render-free + return 0; + } + } + else + { LLViewerFetchedTexture* texture = mSculptTexture; - if (texture && textures.find(texture) == textures.end()) - { + if (texture && textures.find(texture) == textures.end()) + { textures.insert(texture); - } - } - } + } + } + } - if (isFlexibleFast()) - { - flexi = 1; - } - if (isParticleSource()) - { - particles = 1; - } + if (isFlexibleFast()) + { + flexi = 1; + } + if (isParticleSource()) + { + particles = 1; + } - if (getIsLightFast()) - { - produces_light = 1; - } + if (getIsLightFast()) + { + produces_light = 1; + } { LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list"); @@ -4149,79 +4149,79 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } } - // shame currently has the "base" cost of 1 point per 15 triangles, min 2. - shame = num_triangles * 5.f; - shame = shame < 2.f ? 2.f : shame; - - // multiply by per-face modifiers - if (planar) - { - shame *= planar * ARC_PLANAR_COST; - } - - if (animtex) - { - shame *= animtex * ARC_ANIM_TEX_COST; - } - - if (alpha) - { - shame *= alpha * ARC_ALPHA_COST; - } - - if(invisi) - { - shame *= invisi * ARC_INVISI_COST; - } - - if (glow) - { - shame *= glow * ARC_GLOW_MULT; - } - - if (bump) - { - shame *= bump * ARC_BUMP_MULT; - } - - if (shiny) - { - shame *= shiny * ARC_SHINY_MULT; - } - - - // multiply shame by multipliers - if (weighted_mesh) - { - shame *= weighted_mesh * ARC_WEIGHTED_MESH; - } - - if (flexi) - { - shame *= flexi * ARC_FLEXI_MULT; - } - - - // add additional costs - if (particles) - { - const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); - const LLPartData *part_data = &(part_sys_data->mPartData); - U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); - num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; - F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; - shame += num_particles * part_size * ARC_PARTICLE_COST; - } - - if (produces_light) - { - shame += ARC_LIGHT_COST; - } - - if (media_faces) - { - shame += media_faces * ARC_MEDIA_FACE_COST; - } + // shame currently has the "base" cost of 1 point per 15 triangles, min 2. + shame = num_triangles * 5.f; + shame = shame < 2.f ? 2.f : shame; + + // multiply by per-face modifiers + if (planar) + { + shame *= planar * ARC_PLANAR_COST; + } + + if (animtex) + { + shame *= animtex * ARC_ANIM_TEX_COST; + } + + if (alpha) + { + shame *= alpha * ARC_ALPHA_COST; + } + + if(invisi) + { + shame *= invisi * ARC_INVISI_COST; + } + + if (glow) + { + shame *= glow * ARC_GLOW_MULT; + } + + if (bump) + { + shame *= bump * ARC_BUMP_MULT; + } + + if (shiny) + { + shame *= shiny * ARC_SHINY_MULT; + } + + + // multiply shame by multipliers + if (weighted_mesh) + { + shame *= weighted_mesh * ARC_WEIGHTED_MESH; + } + + if (flexi) + { + shame *= flexi * ARC_FLEXI_MULT; + } + + + // add additional costs + if (particles) + { + const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); + const LLPartData *part_data = &(part_sys_data->mPartData); + U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); + num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; + F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; + shame += num_particles * part_size * ARC_PARTICLE_COST; + } + + if (produces_light) + { + shame += ARC_LIGHT_COST; + } + + if (media_faces) + { + shame += media_faces * ARC_MEDIA_FACE_COST; + } // Streaming cost for animated objects includes a fixed cost // per linkset. Add a corresponding charge here translated into @@ -4231,35 +4231,35 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f; } - if (shame > mRenderComplexity_current) - { - mRenderComplexity_current = (S32)shame; - } + if (shame > mRenderComplexity_current) + { + mRenderComplexity_current = (S32)shame; + } - return (U32)shame; + return (U32)shame; } F32 LLVOVolume::getEstTrianglesMax() const { - if (isMeshFast() && getVolume()) - { - return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID()); - } + if (isMeshFast() && getVolume()) + { + return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID()); + } return 0.f; } F32 LLVOVolume::getEstTrianglesStreamingCost() const { - if (isMeshFast() && getVolume()) - { - return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); - } + if (isMeshFast() && getVolume()) + { + return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); + } return 0.f; } F32 LLVOVolume::getStreamingCost() const { - F32 radius = getScale().length()*0.5f; + F32 radius = getScale().length()*0.5f; F32 linkset_base_cost = 0.f; LLMeshCostData costs; @@ -4303,87 +4303,87 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const } else { - LLVolume* volume = getVolume(); - S32 counts[4]; - LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + LLVolume* volume = getVolume(); + S32 counts[4]; + LLVolume::getLoDTriangleCounts(volume->getParams(), counts); LLMeshHeader header; - header.mLodSize[0] = counts[0] * 10; - header.mLodSize[1] = counts[1] * 10; - header.mLodSize[2] = counts[2] * 10; - header.mLodSize[3] = counts[3] * 10; + header.mLodSize[0] = counts[0] * 10; + header.mLodSize[1] = counts[1] * 10; + header.mLodSize[2] = counts[2] * 10; + header.mLodSize[3] = counts[3] * 10; - return gMeshRepo.getCostData(header, costs); + return gMeshRepo.getCostData(header, costs); } } -//static +//static void LLVOVolume::updateRenderComplexity() { - mRenderComplexity_last = mRenderComplexity_current; - mRenderComplexity_current = 0; + mRenderComplexity_last = mRenderComplexity_current; + mRenderComplexity_current = 0; } U32 LLVOVolume::getTriangleCount(S32* vcount) const { - U32 count = 0; - LLVolume* volume = getVolume(); - if (volume) - { - count = volume->getNumTriangles(vcount); - } + U32 count = 0; + LLVolume* volume = getVolume(); + if (volume) + { + count = volume->getNumTriangles(vcount); + } - return count; + return count; } U32 LLVOVolume::getHighLODTriangleCount() { - U32 ret = 0; - - LLVolume* volume = getVolume(); - - if (!isSculpted()) - { - LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); - ret = ref->getNumTriangles(); - LLPrimitive::getVolumeManager()->unrefVolume(ref); - } - else if (isMesh()) - { - LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); - if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0) - { - gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); - } - ret = ref->getNumTriangles(); - LLPrimitive::getVolumeManager()->unrefVolume(ref); - } - else - { //default sculpts have a constant number of triangles - ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch - } - - return ret; + U32 ret = 0; + + LLVolume* volume = getVolume(); + + if (!isSculpted()) + { + LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); + ret = ref->getNumTriangles(); + LLPrimitive::getVolumeManager()->unrefVolume(ref); + } + else if (isMesh()) + { + LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); + if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0) + { + gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); + } + ret = ref->getNumTriangles(); + LLPrimitive::getVolumeManager()->unrefVolume(ref); + } + else + { //default sculpts have a constant number of triangles + ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch + } + + return ret; } //static void LLVOVolume::preUpdateGeom() { - sNumLODChanges = 0; + sNumLODChanges = 0; } void LLVOVolume::parameterChanged(U16 param_type, bool local_origin) { - LLViewerObject::parameterChanged(param_type, local_origin); + LLViewerObject::parameterChanged(param_type, local_origin); } void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) { - LLViewerObject::parameterChanged(param_type, data, in_use, local_origin); - if (mVolumeImpl) - { - mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin); - } + LLViewerObject::parameterChanged(param_type, data, in_use, local_origin); + if (mVolumeImpl) + { + mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin); + } if (!local_origin && param_type == LLNetworkData::PARAMS_EXTENDED_MESH) { U32 extended_mesh_flags = getExtendedMeshFlags(); @@ -4399,15 +4399,15 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u onSetExtendedMeshFlags(extended_mesh_flags); } } - if (mDrawable.notNull()) - { - BOOL is_light = getIsLight(); - if (is_light != mDrawable->isState(LLDrawable::LIGHT)) - { - gPipeline.setLight(mDrawable, is_light); - } - } - + if (mDrawable.notNull()) + { + BOOL is_light = getIsLight(); + if (is_light != mDrawable->isState(LLDrawable::LIGHT)) + { + gPipeline.setLight(mDrawable, is_light); + } + } + updateReflectionProbePtr(); } @@ -4420,13 +4420,13 @@ void LLVOVolume::updateReflectionProbePtr() mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this); } else if (mReflectionProbe.isNull() && getReflectionProbeIsMirror()) - { - // Geenz: This is a special case - what we want here is a hero probe. - // What we want to do here is instantiate a hero probe from the hero probe manager. - + { + // Geenz: This is a special case - what we want here is a hero probe. + // What we want to do here is instantiate a hero probe from the hero probe manager. + if (!mIsHeroProbe) mIsHeroProbe = gPipeline.mHeroProbeManager.registerViewerObject(this); - } + } } else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror()) { @@ -4435,7 +4435,7 @@ void LLVOVolume::updateReflectionProbePtr() mReflectionProbe = nullptr; } - if (getReflectionProbeIsMirror()) + if (getReflectionProbeIsMirror()) { gPipeline.mHeroProbeManager.unregisterViewerObject(this); } @@ -4444,7 +4444,7 @@ void LLVOVolume::updateReflectionProbePtr() void LLVOVolume::setSelected(BOOL sel) { - LLViewerObject::setSelected(sel); + LLViewerObject::setSelected(sel); if (isAnimatedObject()) { getRootEdit()->recursiveMarkForUpdate(); @@ -4459,7 +4459,7 @@ void LLVOVolume::setSelected(BOOL sel) } void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) -{ +{ } F32 LLVOVolume::getBinRadius() @@ -4524,104 +4524,104 @@ F32 LLVOVolume::getBinRadius() const LLVector3 LLVOVolume::getPivotPositionAgent() const { - if (mVolumeImpl) - { - return mVolumeImpl->getPivotPosition(); - } - return LLViewerObject::getPivotPositionAgent(); + if (mVolumeImpl) + { + return mVolumeImpl->getPivotPosition(); + } + return LLViewerObject::getPivotPositionAgent(); } void LLVOVolume::onShift(const LLVector4a &shift_vector) { - if (mVolumeImpl) - { - mVolumeImpl->onShift(shift_vector); - } + if (mVolumeImpl) + { + mVolumeImpl->onShift(shift_vector); + } - updateRelativeXform(); + updateRelativeXform(); } const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const { - if (mVolumeImpl) - { - return mVolumeImpl->getWorldMatrix(xform); - } - return xform->getWorldMatrix(); + if (mVolumeImpl) + { + return mVolumeImpl->getWorldMatrix(xform); + } + return xform->getWorldMatrix(); } void LLVOVolume::markForUpdate() -{ +{ if (mDrawable) { shrinkWrap(); } - LLViewerObject::markForUpdate(); - mVolumeChanged = TRUE; + LLViewerObject::markForUpdate(); + mVolumeChanged = TRUE; } LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const { - LLVector3 ret = pos - getRenderPosition(); - ret = ret * ~getRenderRotation(); - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); - } - - return ret; + LLVector3 ret = pos - getRenderPosition(); + ret = ret * ~getRenderRotation(); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + } + + return ret; } LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const { - LLVector3 ret = dir * ~getRenderRotation(); - - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - ret.scaleVec(objScale); + LLVector3 ret = dir * ~getRenderRotation(); - return ret; + LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); + ret.scaleVec(objScale); + + return ret; } LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const { - LLVector3 ret = dir; - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - ret.scaleVec(objScale); - } + LLVector3 ret = dir; + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + ret.scaleVec(objScale); + } - ret = ret * getRenderRotation(); - ret += getRenderPosition(); - - return ret; + ret = ret * getRenderRotation(); + ret += getRenderPosition(); + + return ret; } LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const { - LLVector3 ret = dir; - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); - ret = ret * getRenderRotation(); + LLVector3 ret = dir; + LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + ret = ret * getRenderRotation(); - return ret; + return ret; } BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) - + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + { - if (!mbCanSelect - || mDrawable->isDead() - || !gPipeline.hasRenderType(mDrawable->getRenderType())) - { - return FALSE; - } + if (!mbCanSelect + || mDrawable->isDead() + || !gPipeline.hasRenderType(mDrawable->getRenderType())) + { + return FALSE; + } if (!pick_unselectable) { @@ -4636,203 +4636,203 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& return FALSE; } - BOOL ret = FALSE; + BOOL ret = FALSE; - LLVolume* volume = getVolume(); + LLVolume* volume = getVolume(); - bool transform = true; + bool transform = true; - if (mDrawable->isState(LLDrawable::RIGGED)) - { - if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) - { - updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); - volume = mRiggedVolume; - transform = false; - } - else - { //cannot pick rigged attachments on other avatars or when not in build mode - return FALSE; - } - } - - if (volume) - { - LLVector4a local_start = start; - LLVector4a local_end = end; - - if (transform) - { - LLVector3 v_start(start.getF32ptr()); - LLVector3 v_end(end.getF32ptr()); - - v_start = agentPositionToVolume(v_start); - v_end = agentPositionToVolume(v_end); - - local_start.load3(v_start.mV); - local_end.load3(v_end.mV); - } - - LLVector4a p; - LLVector4a n; - LLVector2 tc; - LLVector4a tn; - - if (intersection != NULL) - { - p = *intersection; - } - - if (tex_coord != NULL) - { - tc = *tex_coord; - } - - if (normal != NULL) - { - n = *normal; - } - - if (tangent != NULL) - { - tn = *tangent; - } - - S32 face_hit = -1; - - S32 start_face, end_face; - if (face == -1) - { - start_face = 0; - end_face = volume->getNumVolumeFaces(); - } - else - { - start_face = face; - end_face = face+1; - } - pick_transparent |= isHiglightedOrBeacon(); + if (mDrawable->isState(LLDrawable::RIGGED)) + { + if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) + { + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); + volume = mRiggedVolume; + transform = false; + } + else + { //cannot pick rigged attachments on other avatars or when not in build mode + return FALSE; + } + } + + if (volume) + { + LLVector4a local_start = start; + LLVector4a local_end = end; + + if (transform) + { + LLVector3 v_start(start.getF32ptr()); + LLVector3 v_end(end.getF32ptr()); + + v_start = agentPositionToVolume(v_start); + v_end = agentPositionToVolume(v_end); + + local_start.load3(v_start.mV); + local_end.load3(v_end.mV); + } + + LLVector4a p; + LLVector4a n; + LLVector2 tc; + LLVector4a tn; + + if (intersection != NULL) + { + p = *intersection; + } + + if (tex_coord != NULL) + { + tc = *tex_coord; + } + + if (normal != NULL) + { + n = *normal; + } + + if (tangent != NULL) + { + tn = *tangent; + } + + S32 face_hit = -1; + + S32 start_face, end_face; + if (face == -1) + { + start_face = 0; + end_face = volume->getNumVolumeFaces(); + } + else + { + start_face = face; + end_face = face+1; + } + pick_transparent |= isHiglightedOrBeacon(); // we *probably* shouldn't care about special cursor at all, but we *definitely* // don't care about special cursor for reflection probes -- makes alt-zoom // go through reflection probes on vehicles - bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); + bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); - for (S32 i = start_face; i < end_face; ++i) - { - if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) - { //don't attempt to pick completely transparent faces unless - //pick_transparent is true - continue; - } + for (S32 i = start_face; i < end_face; ++i) + { + if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) + { //don't attempt to pick completely transparent faces unless + //pick_transparent is true + continue; + } // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. updateRiggedVolume(true, i, false); - face_hit = volume->lineSegmentIntersect(local_start, local_end, i, - &p, &tc, &n, &tn); - - if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit) - { - LLFace* face = mDrawable->getFace(face_hit); - - bool ignore_alpha = false; - - const LLTextureEntry* te = face->getTextureEntry(); - if (te) - { - LLMaterial* mat = te->getMaterialParams(); - if (mat) - { - U8 mode = mat->getDiffuseAlphaMode(); - - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE - || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE - || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) - { - ignore_alpha = true; - } - } - } + face_hit = volume->lineSegmentIntersect(local_start, local_end, i, + &p, &tc, &n, &tn); + + if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit) + { + LLFace* face = mDrawable->getFace(face_hit); + + bool ignore_alpha = false; + + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + LLMaterial* mat = te->getMaterialParams(); + if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE + || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE + || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) + { + ignore_alpha = true; + } + } + } BOOL no_texture = !face->getTexture() || !face->getTexture()->hasGLTexture(); BOOL mask = no_texture ? FALSE : face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)); - if (face && - (ignore_alpha || pick_transparent || no_texture || mask)) - { - local_end = p; - if (face_hitp != NULL) - { - *face_hitp = face_hit; - } - - if (intersection != NULL) - { - if (transform) - { - LLVector3 v_p(p.getF32ptr()); - - intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space - } - else - { - *intersection = p; - } - } - - if (normal != NULL) - { - if (transform) - { - LLVector3 v_n(n.getF32ptr()); - normal->load3(volumeDirectionToAgent(v_n).mV); - } - else - { - *normal = n; - } - (*normal).normalize3fast(); - } - - if (tangent != NULL) - { - if (transform) - { - LLVector3 v_tn(tn.getF32ptr()); - - LLVector4a trans_tangent; - trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); - - LLVector4Logical mask; - mask.clear(); - mask.setElement<3>(); - - tangent->setSelectWithMask(mask, tn, trans_tangent); - } - else - { - *tangent = tn; - } - (*tangent).normalize3fast(); - } - - if (tex_coord != NULL) - { - *tex_coord = tc; - } - - ret = TRUE; - } - } - } - } - - return ret; + if (face && + (ignore_alpha || pick_transparent || no_texture || mask)) + { + local_end = p; + if (face_hitp != NULL) + { + *face_hitp = face_hit; + } + + if (intersection != NULL) + { + if (transform) + { + LLVector3 v_p(p.getF32ptr()); + + intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space + } + else + { + *intersection = p; + } + } + + if (normal != NULL) + { + if (transform) + { + LLVector3 v_n(n.getF32ptr()); + normal->load3(volumeDirectionToAgent(v_n).mV); + } + else + { + *normal = n; + } + (*normal).normalize3fast(); + } + + if (tangent != NULL) + { + if (transform) + { + LLVector3 v_tn(tn.getF32ptr()); + + LLVector4a trans_tangent; + trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + tangent->setSelectWithMask(mask, tn, trans_tangent); + } + else + { + *tangent = tn; + } + (*tangent).normalize3fast(); + } + + if (tex_coord != NULL) + { + *tex_coord = tc; + } + + ret = TRUE; + } + } + } + } + + return ret; } bool LLVOVolume::treatAsRigged() { - return isSelected() && + return isSelected() && (isAttachment() || isAnimatedObject()) && mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED); @@ -4840,52 +4840,52 @@ bool LLVOVolume::treatAsRigged() LLRiggedVolume* LLVOVolume::getRiggedVolume() { - return mRiggedVolume; + return mRiggedVolume; } void LLVOVolume::clearRiggedVolume() { - if (mRiggedVolume.notNull()) - { - mRiggedVolume = NULL; - updateRelativeXform(); - } + if (mRiggedVolume.notNull()) + { + mRiggedVolume = NULL; + updateRelativeXform(); + } } void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - //Update mRiggedVolume to match current animation frame of avatar. - //Also update position/size in octree. + //Update mRiggedVolume to match current animation frame of avatar. + //Also update position/size in octree. if ((!force_treat_as_rigged) && (!treatAsRigged())) - { - clearRiggedVolume(); - - return; - } - - LLVolume* volume = getVolume(); - const LLMeshSkinInfo* skin = getSkinInfo(); - if (!skin) - { - clearRiggedVolume(); - return; - } - - LLVOAvatar* avatar = getAvatar(); - if (!avatar) - { - clearRiggedVolume(); - return; - } - - if (!mRiggedVolume) - { - LLVolumeParams p; - mRiggedVolume = new LLRiggedVolume(p); - updateRelativeXform(); - } + { + clearRiggedVolume(); + + return; + } + + LLVolume* volume = getVolume(); + const LLMeshSkinInfo* skin = getSkinInfo(); + if (!skin) + { + clearRiggedVolume(); + return; + } + + LLVOAvatar* avatar = getAvatar(); + if (!avatar) + { + clearRiggedVolume(); + return; + } + + if (!mRiggedVolume) + { + LLVolumeParams p; + mRiggedVolume = new LLRiggedVolume(p); + updateRelativeXform(); + } mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } @@ -4898,47 +4898,47 @@ void LLRiggedVolume::update( bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - bool copy = false; - if (volume->getNumVolumeFaces() != getNumVolumeFaces()) - { - copy = true; - } - - for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) - { - const LLVolumeFace& src_face = volume->getVolumeFace(i); - const LLVolumeFace& dst_face = getVolumeFace(i); - - if (src_face.mNumIndices != dst_face.mNumIndices || - src_face.mNumVertices != dst_face.mNumVertices) - { - copy = true; - } - } - - if (copy) - { - copyVolumeFaces(volume); - } + bool copy = false; + if (volume->getNumVolumeFaces() != getNumVolumeFaces()) + { + copy = true; + } + + for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) + { + const LLVolumeFace& src_face = volume->getVolumeFace(i); + const LLVolumeFace& dst_face = getVolumeFace(i); + + if (src_face.mNumIndices != dst_face.mNumIndices || + src_face.mNumVertices != dst_face.mNumVertices) + { + copy = true; + } + } + + if (copy) + { + copyVolumeFaces(volume); + } else { bool is_paused = avatar && avatar->areAnimationsPaused(); - if (is_paused) - { + if (is_paused) + { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); if (frames_paused > 1) { return; } - } + } } - //build matrix palette - static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; + //build matrix palette + static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; - LLMatrix4a mat[kMaxJoints]; - U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLMatrix4a mat[kMaxJoints]; + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); const LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; @@ -4963,21 +4963,21 @@ void LLRiggedVolume::update( face_end = face_begin + 1; } for (S32 i = face_begin; i < face_end; ++i) - { - const LLVolumeFace& vol_face = volume->getVolumeFace(i); - - LLVolumeFace& dst_face = mVolumeFaces[i]; - - LLVector4a* weight = vol_face.mWeights; - - if ( weight ) - { + { + const LLVolumeFace& vol_face = volume->getVolumeFace(i); + + LLVolumeFace& dst_face = mVolumeFaces[i]; + + LLVector4a* weight = vol_face.mWeights; + + if ( weight ) + { LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); - LLVector4a* pos = dst_face.mPositions; + LLVector4a* pos = dst_face.mPositions; - if (pos && dst_face.mExtents) - { + if (pos && dst_face.mExtents) + { U32 max_joints = LLSkinningUtil::getMaxJointCount(); rigged_vert_count += dst_face.mNumVertices; rigged_face_count++; @@ -4989,71 +4989,71 @@ void LLRiggedVolume::update( U8* joint_indices_cursor = vol_face.mJointIndices; LLVector4a* just_weights = vol_face.mJustWeights; for (U32 j = 0; j < dst_face.mNumVertices; ++j) - { - LLMatrix4a final_mat; + { + LLMatrix4a final_mat; F32* w = just_weights[j].getF32ptr(); LLSkinningUtil::getPerVertexSkinMatrixWithIndices(w, joint_indices_cursor, mat, final_mat, src); joint_indices_cursor += 4; - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - } + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + } } else #endif { - for (U32 j = 0; j < dst_face.mNumVertices; ++j) - { - LLMatrix4a final_mat; + for (U32 j = 0; j < dst_face.mNumVertices; ++j) + { + LLMatrix4a final_mat; LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); - - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - } + + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + } } - //update bounding box - // VFExtents change - LLVector4a& min = dst_face.mExtents[0]; - LLVector4a& max = dst_face.mExtents[1]; + //update bounding box + // VFExtents change + LLVector4a& min = dst_face.mExtents[0]; + LLVector4a& max = dst_face.mExtents[1]; - min = pos[0]; - max = pos[1]; + min = pos[0]; + max = pos[1]; if (i==0) { box_min = min; box_max = max; } - for (U32 j = 1; j < dst_face.mNumVertices; ++j) - { - min.setMin(min, pos[j]); - max.setMax(max, pos[j]); - } + for (U32 j = 1; j < dst_face.mNumVertices; ++j) + { + min.setMin(min, pos[j]); + max.setMax(max, pos[j]); + } box_min.setMin(min,box_min); box_max.setMax(max,box_max); - dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); - dst_face.mCenter->mul(0.5f); + dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); + dst_face.mCenter->mul(0.5f); - } + } if (rebuild_face_octrees) - { + { dst_face.destroyOctree(); dst_face.createOctree(); - } - } - } + } + } + } mExtraDebugText = llformat("rigged %d/%d - box (%f %f %f) (%f %f %f)", rigged_face_count, rigged_vert_count, box_min[0], box_min[1], box_min[2], @@ -5062,111 +5062,111 @@ void LLRiggedVolume::update( U32 LLVOVolume::getPartitionType() const { - if (isHUDAttachment()) - { - return LLViewerRegion::PARTITION_HUD; - } - if (isAnimatedObject() && getControlAvatar()) - { - return LLViewerRegion::PARTITION_CONTROL_AV; - } - if (isAttachment()) - { - return LLViewerRegion::PARTITION_AVATAR; - } + if (isHUDAttachment()) + { + return LLViewerRegion::PARTITION_HUD; + } + if (isAnimatedObject() && getControlAvatar()) + { + return LLViewerRegion::PARTITION_CONTROL_AV; + } + if (isAttachment()) + { + return LLViewerRegion::PARTITION_AVATAR; + } - return LLViewerRegion::PARTITION_VOLUME; + return LLViewerRegion::PARTITION_VOLUME; } LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) : LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, regionp), LLVolumeGeometryManager() { - mLODPeriod = 32; - mDepthMask = FALSE; - mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLViewerRegion::PARTITION_VOLUME; - mSlopRatio = 0.25f; + mLODPeriod = 32; + mDepthMask = FALSE; + mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_VOLUME; + mSlopRatio = 0.25f; } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) : LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp), LLVolumeGeometryManager() { - mDepthMask = FALSE; - mLODPeriod = 32; - mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLViewerRegion::PARTITION_BRIDGE; - - mSlopRatio = 0.25f; + mDepthMask = FALSE; + mLODPeriod = 32; + mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_BRIDGE; + + mSlopRatio = 0.25f; } LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp) - : LLVolumeBridge(drawablep, regionp) + : LLVolumeBridge(drawablep, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; - mPartitionType = LLViewerRegion::PARTITION_AVATAR; + mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; + mPartitionType = LLViewerRegion::PARTITION_AVATAR; } LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp) - : LLVolumeBridge(drawablep, regionp) + : LLVolumeBridge(drawablep, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; - mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; + mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; + mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; } void LLControlAVBridge::updateSpatialExtents() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE - LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0); + LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0); - bool rootWasDirty = root->isDirty(); + bool rootWasDirty = root->isDirty(); - super::updateSpatialExtents(); // root becomes non-dirty here + super::updateSpatialExtents(); // root becomes non-dirty here - // SL-18251 "On-screen animesh characters using pelvis offset animations - // disappear when root goes off-screen" - // - // Expand extents to include Control Avatar placed outside of the bounds + // SL-18251 "On-screen animesh characters using pelvis offset animations + // disappear when root goes off-screen" + // + // Expand extents to include Control Avatar placed outside of the bounds LLControlAvatar* controlAvatar = getVObj() ? getVObj()->getControlAvatar() : NULL; if (controlAvatar && controlAvatar->mDrawable && controlAvatar->mDrawable->getEntry() && (rootWasDirty || controlAvatar->mPlaying)) - { - root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform()); - } + { + root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform()); + } } bool can_batch_texture(LLFace* facep) { - if (facep->getTextureEntry()->getBumpmap()) - { //bump maps aren't worked into texture batching yet - return false; - } - - if (facep->getTextureEntry()->getMaterialParams().notNull()) - { //materials don't work with texture batching yet - return false; - } - - if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) - { //can't batch invisiprims - return false; - } - - if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) - { //texture animation breaks batches - return false; - } - + if (facep->getTextureEntry()->getBumpmap()) + { //bump maps aren't worked into texture batching yet + return false; + } + + if (facep->getTextureEntry()->getMaterialParams().notNull()) + { //materials don't work with texture batching yet + return false; + } + + if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) + { //can't batch invisiprims + return false; + } + + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { //texture animation breaks batches + return false; + } + if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr) { // PBR materials break indexed texture batching return false; } - return true; + return true; } const static U32 MAX_FACE_COUNT = 4096U; @@ -5181,27 +5181,27 @@ LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL }; LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL }; LLVolumeGeometryManager::LLVolumeGeometryManager() - : LLGeometryManager() + : LLGeometryManager() { - llassert(sInstanceCount >= 0); - if (sInstanceCount == 0) - { - allocateFaces(MAX_FACE_COUNT); - } + llassert(sInstanceCount >= 0); + if (sInstanceCount == 0) + { + allocateFaces(MAX_FACE_COUNT); + } - ++sInstanceCount; + ++sInstanceCount; } LLVolumeGeometryManager::~LLVolumeGeometryManager() { - llassert(sInstanceCount > 0); - --sInstanceCount; + llassert(sInstanceCount > 0); + --sInstanceCount; - if (sInstanceCount <= 0) - { - freeFaces(); - sInstanceCount = 0; - } + if (sInstanceCount <= 0) + { + freeFaces(); + sInstanceCount = 0; + } } void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount) @@ -5246,22 +5246,22 @@ void LLVolumeGeometryManager::freeFaces() void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - if ( type == LLRenderPass::PASS_ALPHA - && facep->getTextureEntry()->getMaterialParams().notNull() - && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT) - && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1) - { - LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; - } + if ( type == LLRenderPass::PASS_ALPHA + && facep->getTextureEntry()->getMaterialParams().notNull() + && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT) + && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1) + { + LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + } - bool selected = facep->getViewerObject()->isSelected(); + bool selected = facep->getViewerObject()->isSelected(); - if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects) - { - return; - } + if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects) + { + return; + } - LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type)); + LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type)); U32 passType = type; @@ -5273,66 +5273,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, // See LLRenderPass PASS_foo enum passType += 1; } - //add face to drawmap - LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType]; + //add face to drawmap + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType]; - S32 idx = draw_vec.size()-1; + S32 idx = draw_vec.size()-1; - bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || - (type == LLRenderPass::PASS_INVISIBLE) || - (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || - (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || - (facep->getTextureEntry()->getFullbright()); - - if (!fullbright && - type != LLRenderPass::PASS_GLOW && + bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || + (type == LLRenderPass::PASS_INVISIBLE) || + (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || + (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || + (facep->getTextureEntry()->getFullbright()); + + if (!fullbright && + type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) - { + { llassert(false); - LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL; - return; - } + LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL; + return; + } - const LLMatrix4* tex_mat = NULL; - if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) - { - tex_mat = facep->mTextureMatrix; - } + const LLMatrix4* tex_mat = NULL; + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { + tex_mat = facep->mTextureMatrix; + } - const LLMatrix4* model_mat = NULL; + const LLMatrix4* model_mat = NULL; + + LLDrawable* drawable = facep->getDrawable(); - LLDrawable* drawable = facep->getDrawable(); - if (rigged) { // rigged meshes ignore their model matrix model_mat = nullptr; } - else if (drawable->isState(LLDrawable::ANIMATED_CHILD)) - { - model_mat = &drawable->getWorldMatrix(); - } - else if (drawable->isActive()) - { - model_mat = &drawable->getRenderMatrix(); - } - else - { - model_mat = &(drawable->getRegion()->mRenderMatrix); - } - - //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); + else if (drawable->isState(LLDrawable::ANIMATED_CHILD)) + { + model_mat = &drawable->getWorldMatrix(); + } + else if (drawable->isActive()) + { + model_mat = &drawable->getRenderMatrix(); + } + else + { + model_mat = &(drawable->getRegion()->mRenderMatrix); + } + + //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); const LLTextureEntry* te = facep->getTextureEntry(); - U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0; - U8 shiny = te->getShiny(); - - LLViewerTexture* tex = facep->getTexture(); + U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0; + U8 shiny = te->getShiny(); + + LLViewerTexture* tex = facep->getTexture(); - U8 index = facep->getTextureIndex(); + U8 index = facep->getTextureIndex(); LLMaterial* mat = nullptr; - + LLUUID mat_id; auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); @@ -5354,110 +5354,110 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - bool batchable = false; - - U32 shader_mask = 0xFFFFFFFF; //no shader - - if (mat) - { - BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE; - if (type == LLRenderPass::PASS_ALPHA) - { - shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); - } - else - { - shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); - } - } - - if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) - { - if (mat || gltf_mat || draw_vec[idx]->mMaterial) - { //can't batch textures when materials are present (yet) - batchable = false; - } - else if (index < draw_vec[idx]->mTextureList.size()) - { - if (draw_vec[idx]->mTextureList[index].isNull()) - { - batchable = true; - draw_vec[idx]->mTextureList[index] = tex; - } - else if (draw_vec[idx]->mTextureList[index] == tex) - { //this face's texture index can be used with this batch - batchable = true; - } - } - else - { //texture list can be expanded to fit this texture index - batchable = true; - } - } + bool batchable = false; + + U32 shader_mask = 0xFFFFFFFF; //no shader + + if (mat) + { + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE; + if (type == LLRenderPass::PASS_ALPHA) + { + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); + } + else + { + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); + } + } + + if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) + { + if (mat || gltf_mat || draw_vec[idx]->mMaterial) + { //can't batch textures when materials are present (yet) + batchable = false; + } + else if (index < draw_vec[idx]->mTextureList.size()) + { + if (draw_vec[idx]->mTextureList[index].isNull()) + { + batchable = true; + draw_vec[idx]->mTextureList[index] = tex; + } + else if (draw_vec[idx]->mTextureList[index] == tex) + { //this face's texture index can be used with this batch + batchable = true; + } + } + else + { //texture list can be expanded to fit this texture index + batchable = true; + } + } LLDrawInfo* info = idx >= 0 ? draw_vec[idx] : nullptr; - if (info && - info->mVertexBuffer == facep->getVertexBuffer() && - info->mEnd == facep->getGeomIndex()-1 && - (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) && + if (info && + info->mVertexBuffer == facep->getVertexBuffer() && + info->mEnd == facep->getGeomIndex()-1 && + (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) && #if LL_DARWIN - info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && - info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && + info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && + info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - info->mMaterialID == mat_id && - info->mFullbright == fullbright && - info->mBump == bump && - (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different - info->mTextureMatrix == tex_mat && - info->mModelMatrix == model_mat && - info->mShaderMask == shader_mask && + info->mMaterialID == mat_id && + info->mFullbright == fullbright && + info->mBump == bump && + (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different + info->mTextureMatrix == tex_mat && + info->mModelMatrix == model_mat && + info->mShaderMask == shader_mask && info->mAvatar == facep->mAvatar && info->getSkinHash() == facep->getSkinHash()) - { - info->mCount += facep->getIndicesCount(); - info->mEnd += facep->getGeomCount(); - - if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size()) - { - info->mTextureList.resize(index+1); - info->mTextureList[index] = tex; - } - info->validate(); - } - else - { - U32 start = facep->getGeomIndex(); - U32 end = start + facep->getGeomCount()-1; - U32 offset = facep->getIndicesStart(); - U32 count = facep->getIndicesCount(); - LLPointer draw_info = new LLDrawInfo(start,end,count,offset, tex, - facep->getVertexBuffer(), fullbright, bump); + { + info->mCount += facep->getIndicesCount(); + info->mEnd += facep->getGeomCount(); + + if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size()) + { + info->mTextureList.resize(index+1); + info->mTextureList[index] = tex; + } + info->validate(); + } + else + { + U32 start = facep->getGeomIndex(); + U32 end = start + facep->getGeomCount()-1; + U32 offset = facep->getIndicesStart(); + U32 count = facep->getIndicesCount(); + LLPointer draw_info = new LLDrawInfo(start,end,count,offset, tex, + facep->getVertexBuffer(), fullbright, bump); info = draw_info; - draw_vec.push_back(draw_info); - draw_info->mTextureMatrix = tex_mat; - draw_info->mModelMatrix = model_mat; - - draw_info->mBump = bump; - draw_info->mShiny = shiny; - - static const float alpha[4] = - { - 0.00f, - 0.25f, - 0.5f, - 0.75f - }; - float spec = alpha[shiny & TEM_SHINY_MASK]; - LLVector4 specColor(spec, spec, spec, spec); - draw_info->mSpecColor = specColor; - draw_info->mEnvIntensity = spec; - draw_info->mSpecularMap = NULL; - draw_info->mMaterial = mat; + draw_vec.push_back(draw_info); + draw_info->mTextureMatrix = tex_mat; + draw_info->mModelMatrix = model_mat; + + draw_info->mBump = bump; + draw_info->mShiny = shiny; + + static const float alpha[4] = + { + 0.00f, + 0.25f, + 0.5f, + 0.75f + }; + float spec = alpha[shiny & TEM_SHINY_MASK]; + LLVector4 specColor(spec, spec, spec, spec); + draw_info->mSpecColor = specColor; + draw_info->mEnvIntensity = spec; + draw_info->mSpecularMap = NULL; + draw_info->mMaterial = mat; draw_info->mGLTFMaterial = gltf_mat; - draw_info->mShaderMask = shader_mask; + draw_info->mShaderMask = shader_mask; draw_info->mAvatar = facep->mAvatar; draw_info->mSkinInfo = facep->mSkinInfo; @@ -5467,58 +5467,58 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mMaterialID = mat_id; } else if (mat) - { - draw_info->mMaterialID = mat_id; - - // We have a material. Update our draw info accordingly. - - if (!mat->getSpecularID().isNull()) - { - LLVector4 specColor; - specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); - specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); - specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); - specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); - draw_info->mSpecColor = specColor; - draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); - draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); - } - - draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); - draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); - draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); - } - else - { - if (type == LLRenderPass::PASS_GRASS) - { - draw_info->mAlphaMaskCutoff = 0.5f; - } - else - { - draw_info->mAlphaMaskCutoff = 0.33f; - } - } - - // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr - { //for alpha sorting - facep->setDrawInfo(draw_info); - } - - if (index < FACE_DO_NOT_BATCH_TEXTURES) - { //initialize texture list for texture batching - draw_info->mTextureList.resize(index+1); - draw_info->mTextureList[index] = tex; - } - draw_info->validate(); - } + { + draw_info->mMaterialID = mat_id; + + // We have a material. Update our draw info accordingly. + + if (!mat->getSpecularID().isNull()) + { + LLVector4 specColor; + specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); + specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); + specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); + specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); + draw_info->mSpecColor = specColor; + draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); + draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); + } + + draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); + draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); + draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); + } + else + { + if (type == LLRenderPass::PASS_GRASS) + { + draw_info->mAlphaMaskCutoff = 0.5f; + } + else + { + draw_info->mAlphaMaskCutoff = 0.33f; + } + } + + // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr + { //for alpha sorting + facep->setDrawInfo(draw_info); + } + + if (index < FACE_DO_NOT_BATCH_TEXTURES) + { //initialize texture list for texture batching + draw_info->mTextureList.resize(index+1); + draw_info->mTextureList[index] = tex; + } + draw_info->validate(); + } llassert(info->mGLTFMaterial == nullptr || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED || info->mGLTFMaterial != nullptr); - + llassert(type != LLRenderPass::PASS_BUMP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0); llassert(type != LLRenderPass::PASS_NORMSPEC || info->mNormalMap.notNull()); llassert(type != LLRenderPass::PASS_SPECMAP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TEXCOORD2) != 0); @@ -5561,104 +5561,104 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) return; } - if (group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - } + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + } + + group->mLastUpdateViewAngle = group->mViewAngle; - group->mLastUpdateViewAngle = group->mViewAngle; + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) + { + if (group->hasState(LLSpatialGroup::MESH_DIRTY)) + { + rebuildMesh(group); + } + return; + } - if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) - { - if (group->hasState(LLSpatialGroup::MESH_DIRTY)) - { - rebuildMesh(group); - } - return; - } + group->mBuilt = 1.f; - group->mBuilt = 1.f; - - LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); LLViewerObject *vobj = NULL; LLVOVolume *vol_obj = NULL; - if (bridge) - { + if (bridge) + { vobj = bridge->mDrawable->getVObj(); vol_obj = dynamic_cast(vobj); - } + } if (vol_obj) { vol_obj->updateVisualComplexity(); } - group->mGeometryBytes = 0; - group->mSurfaceArea = 0; - - //cache object box size since it might be used for determining visibility - const LLVector4a* bounds = group->getObjectBounds(); - group->mObjectBoxSize = bounds[1].getLength3().getF32(); + group->mGeometryBytes = 0; + group->mSurfaceArea = 0; + + //cache object box size since it might be used for determining visibility + const LLVector4a* bounds = group->getObjectBounds(); + group->mObjectBoxSize = bounds[1].getLength3().getF32(); - group->clearDrawMap(); + group->clearDrawMap(); U32 fullbright_count[2] = { 0 }; - U32 bump_count[2] = { 0 }; - U32 simple_count[2] = { 0 }; - U32 alpha_count[2] = { 0 }; - U32 norm_count[2] = { 0 }; - U32 spec_count[2] = { 0 }; - U32 normspec_count[2] = { 0 }; - U32 pbr_count[2] = { 0 }; - - static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); - static LLCachedControl max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); - U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - max_vertices = llmin(max_vertices, (U32) 65535); - - U32 cur_total = 0; - - bool emissive = false; - - //Determine if we've received skininfo that contains an - //alternate bind matrix - if it does then apply the translational component - //to the joints of the avatar. + U32 bump_count[2] = { 0 }; + U32 simple_count[2] = { 0 }; + U32 alpha_count[2] = { 0 }; + U32 norm_count[2] = { 0 }; + U32 spec_count[2] = { 0 }; + U32 normspec_count[2] = { 0 }; + U32 pbr_count[2] = { 0 }; + + static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + static LLCachedControl max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + max_vertices = llmin(max_vertices, (U32) 65535); + + U32 cur_total = 0; + + bool emissive = false; + + //Determine if we've received skininfo that contains an + //alternate bind matrix - if it does then apply the translational component + //to the joints of the avatar. #if 0 - bool pelvisGotSet = false; + bool pelvisGotSet = false; #endif - { + { LL_PROFILE_ZONE_NAMED("rebuildGeom - face list"); - //get all the faces into a list - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); + //get all the faces into a list + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) - { - continue; - } - - LLVOVolume* vobj = drawablep->getVOVolume(); - - if (!vobj || vobj->isDead()) - { - continue; - } + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - // HACK -- brute force this check every time a drawable gets rebuilt - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { - vobj->updateTEMaterialTextures(i); + continue; } - // apply any pending material overrides - gGLTFMaterialList.applyQueuedOverrides(vobj); + LLVOVolume* vobj = drawablep->getVOVolume(); - std::string vobj_name = llformat("Vol%p", vobj); + if (!vobj || vobj->isDead()) + { + continue; + } + + // HACK -- brute force this check every time a drawable gets rebuilt + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + vobj->updateTEMaterialTextures(i); + } + + // apply any pending material overrides + gGLTFMaterialList.applyQueuedOverrides(vobj); + + std::string vobj_name = llformat("Vol%p", vobj); bool is_mesh = vobj->isMesh(); if (is_mesh) @@ -5677,24 +5677,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - LLVolume* volume = vobj->getVolume(); - if (volume) - { - const LLVector3& scale = vobj->getScale(); - group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); - } + LLVolume* volume = vobj->getVolume(); + if (volume) + { + const LLVector3& scale = vobj->getScale(); + group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + - F32 est_tris = vobj->getEstTrianglesMax(); vobj->updateControlAvatar(); - + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() << " is_mesh " << is_mesh << " est_tris " << est_tris << " is_animated " << vobj->isAnimatedObject() - << " can_animate " << vobj->canBeAnimatedObject() - << " cav " << vobj->getControlAvatar() + << " can_animate " << vobj->canBeAnimatedObject() + << " cav " << vobj->getControlAvatar() << " lod " << vobj->getLOD() << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) << " drawable state " << drawablep->getState() @@ -5702,11 +5702,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) << " frame " << LLFrameTimer::getFrameCount() << LL_ENDL; - llassert_always(vobj); - vobj->updateTextureVirtualSize(true); - vobj->preRebuild(); + llassert_always(vobj); + vobj->updateTextureVirtualSize(true); + vobj->preRebuild(); - drawablep->clearState(LLDrawable::HAS_ALPHA); + drawablep->clearState(LLDrawable::HAS_ALPHA); LLVOAvatar* avatar = nullptr; const LLMeshSkinInfo* skinInfo = nullptr; @@ -5732,23 +5732,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } - // Standard rigged mesh attachments: - bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); + // Standard rigged mesh attachments: + bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to // exclude static objects in animated object linksets. - rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && + rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying); - bool any_rigged_face = false; + bool any_rigged_face = false; - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace* facep = drawablep->getFace(i); - if (!facep) - { - continue; - } + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + LLFace* facep = drawablep->getFace(i); + if (!facep) + { + continue; + } #if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); @@ -5762,12 +5762,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = gltf_mat != nullptr; #endif - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render - // batch, it will recover its vertex buffer reference from the spatial group - facep->setVertexBuffer(NULL); - - //sum up face verts and indices - drawablep->updateFaceSize(i); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render + // batch, it will recover its vertex buffer reference from the spatial group + facep->setVertexBuffer(NULL); + + //sum up face verts and indices + drawablep->updateFaceSize(i); if (rigged) { @@ -5784,7 +5784,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { if (facep->isState(LLFace::RIGGED)) - { + { //face is not rigged but used to be, remove from rigged face pool LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); if (pool) @@ -5797,84 +5797,84 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) - { - facep->clearVertexBuffer(); - continue; - } + if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) + { + facep->clearVertexBuffer(); + continue; + } - if (facep->hasGeometry() && + if (facep->hasGeometry() && (rigged || // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces - { + { cur_total += facep->getGeomCount(); - const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerTexture* tex = facep->getTexture(); + const LLTextureEntry* te = facep->getTextureEntry(); + LLViewerTexture* tex = facep->getTexture(); - if (te->getGlow() > 0.f) - { - emissive = true; - } + if (te->getGlow() > 0.f) + { + emissive = true; + } - if (facep->isState(LLFace::TEXTURE_ANIM)) - { - if (!vobj->mTexAnimMode) - { - facep->clearState(LLFace::TEXTURE_ANIM); - } - } + if (facep->isState(LLFace::TEXTURE_ANIM)) + { + if (!vobj->mTexAnimMode) + { + facep->clearState(LLFace::TEXTURE_ANIM); + } + } - BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND) { type = LLDrawPool::POOL_GLTF_PBR; } else - if (type != LLDrawPool::POOL_ALPHA && force_simple) - { - type = LLDrawPool::POOL_SIMPLE; - } - facep->setPoolType(type); - - if (vobj->isHUDAttachment() && !is_pbr) - { - facep->setState(LLFace::FULLBRIGHT); - } - - if (vobj->mTextureAnimp && vobj->mTexAnimMode) - { - if (vobj->mTextureAnimp->mFace <= -1) - { - S32 face; - for (face = 0; face < vobj->getNumTEs(); face++) - { - LLFace * facep = drawablep->getFace(face); - if (facep) - { - facep->setState(LLFace::TEXTURE_ANIM); - } - } - } - else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) - { - LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); - if (facep) - { - facep->setState(LLFace::TEXTURE_ANIM); - } - } - } - - if (type == LLDrawPool::POOL_ALPHA) - { - if (facep->canRenderAsMask()) - { //can be treated as alpha mask + if (type != LLDrawPool::POOL_ALPHA && force_simple) + { + type = LLDrawPool::POOL_SIMPLE; + } + facep->setPoolType(type); + + if (vobj->isHUDAttachment() && !is_pbr) + { + facep->setState(LLFace::FULLBRIGHT); + } + + if (vobj->mTextureAnimp && vobj->mTexAnimMode) + { + if (vobj->mTextureAnimp->mFace <= -1) + { + S32 face; + for (face = 0; face < vobj->getNumTEs(); face++) + { + LLFace * facep = drawablep->getFace(face); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + { + LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + + if (type == LLDrawPool::POOL_ALPHA) + { + if (facep->canRenderAsMask()) + { //can be treated as alpha mask add_face(sSimpleFaces, simple_count, facep); - } - else - { + } + else + { F32 alpha; if (is_pbr) { @@ -5885,33 +5885,33 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) alpha = te->getColor().mV[3]; } if (alpha > 0.f || te->getGlow() > 0.f) - { //only treat as alpha in the pipeline if < 100% transparent - drawablep->setState(LLDrawable::HAS_ALPHA); - add_face(sAlphaFaces, alpha_count, facep); - } - else if (LLDrawPoolAlpha::sShowDebugAlpha || - (gPipeline.sRenderHighlight && !drawablep->getParent() && - //only root objects are highlighted with red color in this case - drawablep->getVObj() && drawablep->getVObj()->flagScripted() && - (LLPipeline::getRenderScriptedBeacons() || - (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch())))) - { //draw the transparent face for debugging purposes using a custom texture - add_face(sAlphaFaces, alpha_count, facep); - } - } - } - else - { - if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) - { - facep->mLastUpdateTime = gFrameTimeSeconds; - } - - { + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + add_face(sAlphaFaces, alpha_count, facep); + } + else if (LLDrawPoolAlpha::sShowDebugAlpha || + (gPipeline.sRenderHighlight && !drawablep->getParent() && + //only root objects are highlighted with red color in this case + drawablep->getVObj() && drawablep->getVObj()->flagScripted() && + (LLPipeline::getRenderScriptedBeacons() || + (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch())))) + { //draw the transparent face for debugging purposes using a custom texture + add_face(sAlphaFaces, alpha_count, facep); + } + } + } + else + { + if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + { + facep->mLastUpdateTime = gFrameTimeSeconds; + } + + { LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); - if (gltf_mat != nullptr || (te->getMaterialParams().notNull())) - { + if (gltf_mat != nullptr || (te->getMaterialParams().notNull())) + { if (gltf_mat != nullptr) { add_face(sPbrFaces, pbr_count, facep); @@ -5940,91 +5940,91 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) add_face(sSimpleFaces, simple_count, facep); } } - } - else if (te->getBumpmap()) - { //needs normal + tangent + } + else if (te->getBumpmap()) + { //needs normal + tangent add_face(sBumpFaces, bump_count, facep); - } - else if (te->getShiny() || !te->getFullbright()) - { //needs normal + } + else if (te->getShiny() || !te->getFullbright()) + { //needs normal add_face(sSimpleFaces, simple_count, facep); - } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); add_face(sFullbrightFaces, fullbright_count, facep); - } - } - } - } - else - { //face has no renderable geometry - facep->clearVertexBuffer(); - } - } - - if (any_rigged_face) - { - if (!drawablep->isState(LLDrawable::RIGGED)) - { - drawablep->setState(LLDrawable::RIGGED); + } + } + } + } + else + { //face has no renderable geometry + facep->clearVertexBuffer(); + } + } + + if (any_rigged_face) + { + if (!drawablep->isState(LLDrawable::RIGGED)) + { + drawablep->setState(LLDrawable::RIGGED); LLDrawable* root = drawablep->getRoot(); if (root != drawablep) { root->setState(LLDrawable::RIGGED_CHILD); } - //first time this is drawable is being marked as rigged, - // do another LoD update to use avatar bounding box - vobj->updateLOD(); - } - } - else - { - drawablep->clearState(LLDrawable::RIGGED); + //first time this is drawable is being marked as rigged, + // do another LoD update to use avatar bounding box + vobj->updateLOD(); + } + } + else + { + drawablep->clearState(LLDrawable::RIGGED); vobj->updateRiggedVolume(false); - } - } - } - - //PROCESS NON-ALPHA FACES - U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO - U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - - U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; - U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; - U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; - - U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT; - - if (emissive) - { //emissive faces are present, include emissive byte to preserve batching - simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE; - bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE; - fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; - norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; - normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; - spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; + } + } + } + + //PROCESS NON-ALPHA FACES + U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO + U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + + U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; + U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; + U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; + + U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT; + + if (emissive) + { //emissive faces are present, include emissive byte to preserve batching + simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE; + bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE; + fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; + norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; + normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; + spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE; - } + } - BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; // add extra vertex data for deferred rendering (not necessarily for batching textures) - if (batch_textures) - { - bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; - simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; - fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - } + if (batch_textures) + { + bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; + simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; + fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; + } - group->mGeometryBytes = 0; + group->mGeometryBytes = 0; - U32 geometryBytes = 0; + U32 geometryBytes = 0; // generate render batches for static geometry U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX; @@ -6046,70 +6046,70 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) rigged = TRUE; } - group->mGeometryBytes = geometryBytes; + group->mGeometryBytes = geometryBytes; - { - //drawables have been rebuilt, clear rebuild status - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(drawablep) - { + { + //drawables have been rebuilt, clear rebuild status + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(drawablep) + { drawablep->clearState(LLDrawable::REBUILD_ALL); } } - } + } - group->mLastUpdateTime = gFrameTimeSeconds; - group->mBuilt = 1.f; - group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY); + group->mLastUpdateTime = gFrameTimeSeconds; + group->mBuilt = 1.f; + group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY); } void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - llassert(group); - if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) - { - { + llassert(group); + if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) + { + { LL_PROFILE_ZONE_NAMED("rebuildMesh - gen draw info"); group->mBuilt = 1.f; - - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; + + U32 buffer_count = 0; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) - { - LLVOVolume* vobj = drawablep->getVOVolume(); - - if (!vobj) continue; - - if (vobj->isNoLOD()) continue; - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } - - LLVolume* volume = vobj->getVolume(); - if (!volume) continue; - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) - { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) - { + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) + { + LLVOVolume* vobj = drawablep->getVOVolume(); + + if (!vobj) continue; + + if (vobj->isNoLOD()) continue; + + vobj->preRebuild(); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + + LLVolume* volume = vobj->getVolume(); + if (!volume) continue; + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { if (!face->getGeometryVolume(*volume, // volume face->getTEOffset(), // face_index vobj->getRelativeXform(), // mat_vert_in @@ -6124,72 +6124,72 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } buff->unmapBuffer(); - } - } - } + } + } + } - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(); - } + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } - drawablep->clearState(LLDrawable::REBUILD_ALL); - } - } + drawablep->clearState(LLDrawable::REBUILD_ALL); + } + } - { + { LL_PROFILE_ZONE_NAMED("rebuildMesh - flush"); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->unmapBuffer(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull()) - { - group->mVertexBuffer->unmapBuffer(); - } - } - - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } - } + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) + { + (*iter)->unmapBuffer(); + } + + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull()) + { + group->mVertexBuffer->unmapBuffer(); + } + } + + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); + } + } } struct CompareBatchBreaker { - bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) - { - const LLTextureEntry* lte = lhs->getTextureEntry(); - const LLTextureEntry* rte = rhs->getTextureEntry(); + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + const LLTextureEntry* lte = lhs->getTextureEntry(); + const LLTextureEntry* rte = rhs->getTextureEntry(); if (lte->getBumpmap() != rte->getBumpmap()) - { - return lte->getBumpmap() < rte->getBumpmap(); - } - else if (lte->getFullbright() != rte->getFullbright()) - { - return lte->getFullbright() < rte->getFullbright(); - } + { + return lte->getBumpmap() < rte->getBumpmap(); + } + else if (lte->getFullbright() != rte->getFullbright()) + { + return lte->getFullbright() < rte->getFullbright(); + } else if (lte->getMaterialID() != rte->getMaterialID()) { return lte->getMaterialID() < rte->getMaterialID(); } - else if (lte->getShiny() != rte->getShiny()) - { - return lte->getShiny() < rte->getShiny(); - } + else if (lte->getShiny() != rte->getShiny()) + { + return lte->getShiny() < rte->getShiny(); + } else if (lhs->getTexture() != rhs->getTexture()) - { - return lhs->getTexture() < rhs->getTexture(); - } - else + { + return lhs->getTexture() < rhs->getTexture(); + } + else { // all else being equal, maintain consistent draw order return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); } - } + } }; struct CompareBatchBreakerRigged @@ -6217,16 +6217,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - U32 geometryBytes = 0; - - //calculate maximum number of vertices to store in a single buffer - static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); - U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - max_vertices = llmin(max_vertices, (U32) 65535); + U32 geometryBytes = 0; + + //calculate maximum number of vertices to store in a single buffer + static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + max_vertices = llmin(max_vertices, (U32) 65535); - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - sort"); - + if (rigged) { if (!distance_sort) // <--- alpha "sort" rigged faces by maintaining original draw order @@ -6240,277 +6240,277 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, not including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreaker()); } - else - { - //sort faces by distance - std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); - } - } - - bool hud_group = group->isHUDGroup() ; - LLFace** face_iter = faces; - LLFace** end_faces = faces+face_count; - - LLSpatialGroup::buffer_map_t buffer_map; - - LLViewerTexture* last_tex = NULL; - - S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels; - - bool flexi = false; - - while (face_iter != end_faces) - { - //pull off next face - LLFace* facep = *face_iter; - LLViewerTexture* tex = facep->getTexture(); + else + { + //sort faces by distance + std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); + } + } + + bool hud_group = group->isHUDGroup() ; + LLFace** face_iter = faces; + LLFace** end_faces = faces+face_count; + + LLSpatialGroup::buffer_map_t buffer_map; + + LLViewerTexture* last_tex = NULL; + + S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels; + + bool flexi = false; + + while (face_iter != end_faces) + { + //pull off next face + LLFace* facep = *face_iter; + LLViewerTexture* tex = facep->getTexture(); const LLTextureEntry* te = facep->getTextureEntry(); - LLMaterialPtr mat = te->getMaterialParams(); + LLMaterialPtr mat = te->getMaterialParams(); LLMaterialID matId = te->getMaterialID(); - if (distance_sort) - { - tex = NULL; - } + if (distance_sort) + { + tex = NULL; + } + + if (last_tex != tex) + { + last_tex = tex; + } + + bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); - if (last_tex != tex) - { - last_tex = tex; - } + U32 index_count = facep->getIndicesCount(); + U32 geom_count = facep->getGeomCount(); - bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - U32 index_count = facep->getIndicesCount(); - U32 geom_count = facep->getGeomCount(); + //sum up vertices needed for this render batch + LLFace** i = face_iter; + ++i; - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + const U32 MAX_TEXTURE_COUNT = 32; + LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; - //sum up vertices needed for this render batch - LLFace** i = face_iter; - ++i; - - const U32 MAX_TEXTURE_COUNT = 32; - LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; - - U32 texture_count = 0; + U32 texture_count = 0; - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - face size"); - if (batch_textures) - { - U8 cur_tex = 0; - facep->setTextureIndex(cur_tex); - if (texture_count < MAX_TEXTURE_COUNT) - { - texture_list[texture_count++] = tex; - } - - if (can_batch_texture(facep)) - { //populate texture_list with any textures that can be batched - //move i to the next unbatchable face - while (i != end_faces) - { - facep = *i; - - if (!can_batch_texture(facep)) - { //face is bump mapped or has an animated texture matrix -- can't - //batch more than 1 texture at a time - facep->setTextureIndex(0); - break; - } - - if (facep->getTexture() != tex) - { - if (distance_sort) - { //textures might be out of order, see if texture exists in current batch - bool found = false; - for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx) - { - if (facep->getTexture() == texture_list[tex_idx]) - { - cur_tex = tex_idx; - found = true; - break; - } - } - - if (!found) - { - cur_tex = texture_count; - } - } - else - { - cur_tex++; - } - - if (cur_tex >= texture_index_channels) - { //cut batches when index channels are depleted - break; - } - - tex = facep->getTexture(); - - if (texture_count < MAX_TEXTURE_COUNT) - { - texture_list[texture_count++] = tex; - } - } - - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } - - ++i; - - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); - - facep->setTextureIndex(cur_tex); - } - } - else - { - facep->setTextureIndex(0); - } - - tex = texture_list[0]; - } - else - { - while (i != end_faces && - (LLPipeline::sTextureBindTest || - (distance_sort || - ((*i)->getTexture() == tex)))) - { - facep = *i; + if (batch_textures) + { + U8 cur_tex = 0; + facep->setTextureIndex(cur_tex); + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } + + if (can_batch_texture(facep)) + { //populate texture_list with any textures that can be batched + //move i to the next unbatchable face + while (i != end_faces) + { + facep = *i; + + if (!can_batch_texture(facep)) + { //face is bump mapped or has an animated texture matrix -- can't + //batch more than 1 texture at a time + facep->setTextureIndex(0); + break; + } + + if (facep->getTexture() != tex) + { + if (distance_sort) + { //textures might be out of order, see if texture exists in current batch + bool found = false; + for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx) + { + if (facep->getTexture() == texture_list[tex_idx]) + { + cur_tex = tex_idx; + found = true; + break; + } + } + + if (!found) + { + cur_tex = texture_count; + } + } + else + { + cur_tex++; + } + + if (cur_tex >= texture_index_channels) + { //cut batches when index channels are depleted + break; + } + + tex = facep->getTexture(); + + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } + } + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } + + ++i; + + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + + facep->setTextureIndex(cur_tex); + } + } + else + { + facep->setTextureIndex(0); + } + + tex = texture_list[0]; + } + else + { + while (i != end_faces && + (LLPipeline::sTextureBindTest || + (distance_sort || + ((*i)->getTexture() == tex)))) + { + facep = *i; const LLTextureEntry* nextTe = facep->getTextureEntry(); if (nextTe->getMaterialID() != matId) { break; } - //face has no texture index - facep->mDrawInfo = NULL; - facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } - ++i; - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - } - } - } + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + } + } + } - //create vertex buffer - LLPointer buffer; + //create vertex buffer + LLPointer buffer; - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate"); - buffer = new LLVertexBuffer(mask); - if(!buffer->allocateBuffer(geom_count, index_count)) - { - LL_WARNS() << "Failed to allocate group Vertex Buffer to " - << geom_count << " vertices and " - << index_count << " indices" << LL_ENDL; - buffer = NULL; - } - } - - if (buffer) - { - geometryBytes += buffer->getSize() + buffer->getIndicesSize(); - buffer_map[mask][*face_iter].push_back(buffer); - } - - //add face geometry - - U32 indices_index = 0; - U16 index_offset = 0; + buffer = new LLVertexBuffer(mask); + if(!buffer->allocateBuffer(geom_count, index_count)) + { + LL_WARNS() << "Failed to allocate group Vertex Buffer to " + << geom_count << " vertices and " + << index_count << " indices" << LL_ENDL; + buffer = NULL; + } + } + + if (buffer) + { + geometryBytes += buffer->getSize() + buffer->getIndicesSize(); + buffer_map[mask][*face_iter].push_back(buffer); + } + + //add face geometry + + U32 indices_index = 0; + U16 index_offset = 0; while (face_iter < i) - { - //update face indices for new buffer - facep = *face_iter; - - if (buffer.isNull()) - { - // Bulk allocation failed - facep->setVertexBuffer(buffer); - facep->setSize(0, 0); // mark as no geometry - ++face_iter; - continue; - } - facep->setIndicesIndex(indices_index); - facep->setGeomIndex(index_offset); - facep->setVertexBuffer(buffer); - - if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES) - { - LL_ERRS() << "Invalid texture index." << LL_ENDL; - } - - { - //for debugging, set last time face was updated vs moved - facep->updateRebuildFlags(); - - { //copy face geometry into vertex buffer - LLDrawable* drawablep = facep->getDrawable(); - LLVOVolume* vobj = drawablep->getVOVolume(); - LLVolume* volume = vobj->getVolume(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } - - U32 te_idx = facep->getTEOffset(); - - if (!facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) - { - LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL; - } - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(false); - } - } - } - - index_offset += facep->getGeomCount(); - indices_index += facep->getIndicesCount(); - - //append face to appropriate render batch - - BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; - BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); - if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) - { //paranoia check to make sure GL doesn't try to read non-existant normals - fullbright = TRUE; - } + { + //update face indices for new buffer + facep = *face_iter; + + if (buffer.isNull()) + { + // Bulk allocation failed + facep->setVertexBuffer(buffer); + facep->setSize(0, 0); // mark as no geometry + ++face_iter; + continue; + } + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + + if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES) + { + LL_ERRS() << "Invalid texture index." << LL_ENDL; + } + + { + //for debugging, set last time face was updated vs moved + facep->updateRebuildFlags(); + + { //copy face geometry into vertex buffer + LLDrawable* drawablep = facep->getDrawable(); + LLVOVolume* vobj = drawablep->getVOVolume(); + LLVolume* volume = vobj->getVolume(); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + + U32 te_idx = facep->getTEOffset(); + + if (!facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) + { + LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL; + } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(false); + } + } + } + + index_offset += facep->getGeomCount(); + indices_index += facep->getIndicesCount(); + + //append face to appropriate render batch + + BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; + BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); + if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) + { //paranoia check to make sure GL doesn't try to read non-existant normals + fullbright = TRUE; + } const LLTextureEntry* te = facep->getTextureEntry(); LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); - if (hud_group && gltf_mat == nullptr) - { //all hud attachments are fullbright - fullbright = TRUE; - } - - tex = facep->getTexture(); + if (hud_group && gltf_mat == nullptr) + { //all hud attachments are fullbright + fullbright = TRUE; + } + + tex = facep->getTexture(); - BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; LLMaterial* mat = nullptr; bool can_be_shiny = false; @@ -6530,8 +6530,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } F32 blinn_phong_alpha = te->getColor().mV[3]; - bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); - bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f; + bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); + bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f; bool blinn_phong_transparent = blinn_phong_alpha < 0.999f; if (!gltf_mat) @@ -6539,9 +6539,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace is_alpha = (is_alpha || blinn_phong_transparent) ? TRUE : FALSE; } - if (gltf_mat || (mat && !hud_group)) - { - bool material_pass = false; + if (gltf_mat || (mat && !hud_group)) + { + bool material_pass = false; if (gltf_mat) { // all other parameters ignored if gltf material is present @@ -6559,82 +6559,82 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } } else - // do NOT use 'fullbright' for this logic or you risk sending - // things without normals down the materials pipeline and will - // render poorly if not crash NORSPEC-240,314 - // - if (te->getFullbright()) - { - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - if (blinn_phong_opaque) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - } - else if (is_alpha) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else - { - if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0) - { - material_pass = true; - } - else - { + // do NOT use 'fullbright' for this logic or you risk sending + // things without normals down the materials pipeline and will + // render poorly if not crash NORSPEC-240,314 + // + if (te->getFullbright()) + { + if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + if (blinn_phong_opaque) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + } + else if (is_alpha) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else + { + if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0) + { + material_pass = true; + } + else + { if (blinn_phong_opaque) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); } else { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } - } - } - } - else if (blinn_phong_transparent) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else if (use_legacy_bump) - { + } + } + } + else if (blinn_phong_transparent) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else if (use_legacy_bump) + { llassert(mask & LLVertexBuffer::MAP_TANGENT); - // we have a material AND legacy bump settings, but no normal map - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { - material_pass = true; - } - - if (material_pass) - { - static const U32 pass[] = - { - LLRenderPass::PASS_MATERIAL, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, - LLRenderPass::PASS_MATERIAL_ALPHA_MASK, - LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, - LLRenderPass::PASS_SPECMAP, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, - LLRenderPass::PASS_SPECMAP_MASK, - LLRenderPass::PASS_SPECMAP_EMISSIVE, - LLRenderPass::PASS_NORMMAP, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, - LLRenderPass::PASS_NORMMAP_MASK, - LLRenderPass::PASS_NORMMAP_EMISSIVE, - LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, - LLRenderPass::PASS_NORMSPEC_MASK, - LLRenderPass::PASS_NORMSPEC_EMISSIVE, - }; + // we have a material AND legacy bump settings, but no normal map + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { + material_pass = true; + } + + if (material_pass) + { + static const U32 pass[] = + { + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, + LLRenderPass::PASS_MATERIAL_ALPHA_MASK, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, + LLRenderPass::PASS_SPECMAP_MASK, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, + LLRenderPass::PASS_NORMMAP_MASK, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, + LLRenderPass::PASS_NORMSPEC_MASK, + LLRenderPass::PASS_NORMSPEC_EMISSIVE, + }; U32 alpha_mode = mat->getDiffuseAlphaMode(); if (!distance_sort && alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) @@ -6645,180 +6645,180 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 vb_mask = facep->getVertexBuffer()->getTypeMask(); - // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now + // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now // even though it didn't appear to have a specmap when the face was added to the list of faces if ((mask & 0x4) && !(vb_mask & LLVertexBuffer::MAP_TEXCOORD2)) { mask &= ~0x4; } - llassert(mask < sizeof(pass)/sizeof(U32)); + llassert(mask < sizeof(pass)/sizeof(U32)); - mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); + mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); // if this is going into alpha pool, distance sort MUST be true llassert(pass[mask] == LLRenderPass::PASS_ALPHA ? distance_sort : true); - registerFace(group, facep, pass[mask]); - } - } - else if (mat) - { - U8 mode = mat->getDiffuseAlphaMode(); + registerFace(group, facep, pass[mask]); + } + } + else if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); - if (is_alpha) - { - mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - } - - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); - } - else if (is_alpha ) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else if (gPipeline.shadersLoaded() - && te->getShiny() - && can_be_shiny) - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); - } - else - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); - } - } - else if (is_alpha) - { - // can we safely treat this as an alpha mask? - if (facep->getFaceColor().mV[3] <= 0.f) - { //100% transparent, don't render unless we're highlighting transparent - registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); - } - else if (facep->canRenderAsMask() && !hud_group) - { - if (te->getFullbright() || LLPipeline::sNoAlpha) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); - } - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - } - else if (gPipeline.shadersLoaded() - && te->getShiny() - && can_be_shiny) - { //shiny - if (tex->getPrimaryFormat() == GL_ALPHA) - { //invisiprim+shiny - registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); - } - else if (!hud_group) - { //deferred rendering - if (te->getFullbright()) - { //register in post deferred fullbright shiny pass - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); - if (te->getBumpmap()) - { //register in post deferred bump pass - registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); - } - } - else if (use_legacy_bump) - { //register in deferred bump pass + if (is_alpha) + { + mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); + } + else if (is_alpha ) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else if (gPipeline.shadersLoaded() + && te->getShiny() + && can_be_shiny) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); + } + else + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); + } + } + else if (is_alpha) + { + // can we safely treat this as an alpha mask? + if (facep->getFaceColor().mV[3] <= 0.f) + { //100% transparent, don't render unless we're highlighting transparent + registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); + } + else if (facep->canRenderAsMask() && !hud_group) + { + if (te->getFullbright() || LLPipeline::sNoAlpha) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + } + else if (gPipeline.shadersLoaded() + && te->getShiny() + && can_be_shiny) + { //shiny + if (tex->getPrimaryFormat() == GL_ALPHA) + { //invisiprim+shiny + registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (!hud_group) + { //deferred rendering + if (te->getFullbright()) + { //register in post deferred fullbright shiny pass + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); + if (te->getBumpmap()) + { //register in post deferred bump pass + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else if (use_legacy_bump) + { //register in deferred bump pass llassert(mask& LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { //register in deferred simple pass (deferred simple includes shiny) - llassert(mask & LLVertexBuffer::MAP_NORMAL); - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } - } - else if (fullbright) - { //not deferred, register in standard fullbright shiny pass - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); - } - else - { //not deferred or fullbright, register in standard shiny pass - registerFace(group, facep, LLRenderPass::PASS_SHINY); - } - } - else - { //not alpha and not shiny - if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) - { //invisiprim - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); - } - else if (fullbright || bake_sunlight) - { //fullbright - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); - } - if (!hud_group && use_legacy_bump) - { //if this is the deferred render and a bump map is present, register in post deferred bump - registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); - } - } - else - { - if (use_legacy_bump) - { //non-shiny or fullbright deferred bump + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { //register in deferred simple pass (deferred simple includes shiny) + llassert(mask & LLVertexBuffer::MAP_NORMAL); + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + } + else if (fullbright) + { //not deferred, register in standard fullbright shiny pass + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); + } + else + { //not deferred or fullbright, register in standard shiny pass + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } + } + else + { //not alpha and not shiny + if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) + { //invisiprim + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (fullbright || bake_sunlight) + { //fullbright + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + } + if (!hud_group && use_legacy_bump) + { //if this is the deferred render and a bump map is present, register in post deferred bump + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else + { + if (use_legacy_bump) + { //non-shiny or fullbright deferred bump llassert(mask& LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { //all around simple - llassert(mask & LLVertexBuffer::MAP_NORMAL); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { //material alpha mask can be respected in non-deferred - registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } - } - } - - - if (!gPipeline.shadersLoaded() && - !is_alpha && - te->getShiny()) - { //shiny as an extra pass when shaders are disabled - registerFace(group, facep, LLRenderPass::PASS_SHINY); - } - } - - //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010 - if (!is_alpha && hud_group) - { - llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); - facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); - - if (!force_simple && use_legacy_bump) - { + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { //all around simple + llassert(mask & LLVertexBuffer::MAP_NORMAL); + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { //material alpha mask can be respected in non-deferred + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + } + } + + + if (!gPipeline.shadersLoaded() && + !is_alpha && + te->getShiny()) + { //shiny as an extra pass when shaders are disabled + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } + } + + //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010 + if (!is_alpha && hud_group) + { + llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); + facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); + + if (!force_simple && use_legacy_bump) + { llassert(mask & LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - } + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + } - if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) - { + if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) + { if (gltf_mat) { registerFace(group, facep, LLRenderPass::PASS_GLTF_GLOW); @@ -6827,24 +6827,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { registerFace(group, facep, LLRenderPass::PASS_GLOW); } - } - - ++face_iter; - } + } - if (buffer) - { - buffer->unmapBuffer(); - } - } + ++face_iter; + } - group->mBufferMap[mask].clear(); - for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i) - { - group->mBufferMap[mask][i->first] = i->second; - } + if (buffer) + { + buffer->unmapBuffer(); + } + } + + group->mBufferMap[mask].clear(); + for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i) + { + group->mBufferMap[mask][i->first] = i->second; + } - return geometryBytes; + return geometryBytes; } void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) @@ -6862,57 +6862,57 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte } void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) -{ +{ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //clear off any old faces mFaceList.clear(); - //for each drawable - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (!drawablep || drawablep->isDead()) - { - continue; - } - - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - //sum up face verts and indices - drawablep->updateFaceSize(i); - LLFace* facep = drawablep->getFace(i); - if (facep) - { - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && - facep->getGeomCount() + vertex_count <= 65536) - { - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - - //remember face (for sorting) - mFaceList.push_back(facep); - } - else - { - facep->clearVertexBuffer(); - } - } - } - } + //for each drawable + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (!drawablep || drawablep->isDead()) + { + continue; + } + + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + //sum up face verts and indices + drawablep->updateFaceSize(i); + LLFace* facep = drawablep->getFace(i); + if (facep) + { + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && + facep->getGeomCount() + vertex_count <= 65536) + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + + //remember face (for sorting) + mFaceList.push_back(facep); + } + else + { + facep->clearVertexBuffer(); + } + } + } + } } LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp) { - mPartitionType = LLViewerRegion::PARTITION_HUD; - mDrawableType = LLPipeline::RENDER_TYPE_HUD; - mSlopRatio = 0.f; - mLODPeriod = 1; + mPartitionType = LLViewerRegion::PARTITION_HUD; + mDrawableType = LLPipeline::RENDER_TYPE_HUD; + mSlopRatio = 0.f; + mLODPeriod = 1; } void LLHUDPartition::shift(const LLVector4a &offset) { - //HUD objects don't shift with region crossing. That would be silly. + //HUD objects don't shift with region crossing. That would be silly. } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index cac09609b3..44a964a363 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -1,25 +1,25 @@ -/** +/** * @file llvovolume.h * @brief LLVOVolume class header file * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,8 +32,8 @@ #include "llviewermedia.h" #include "llframetimer.h" #include "lllocalbitmaps.h" -#include "m3math.h" // LLMatrix3 -#include "m4math.h" // LLMatrix4 +#include "m3math.h" // LLMatrix3 +#include "m4math.h" // LLMatrix4 #include #include @@ -51,7 +51,7 @@ typedef std::vector media_list_t; enum LLVolumeInterfaceType { - INTERFACE_FLEXIBLE = 1, + INTERFACE_FLEXIBLE = 1, }; const F32 MAX_LOD_FACTOR = 4.0f; @@ -60,10 +60,10 @@ const F32 MAX_LOD_FACTOR = 4.0f; class LLRiggedVolume : public LLVolume { public: - LLRiggedVolume(const LLVolumeParams& params) - : LLVolume(params, 0.f) - { - } + LLRiggedVolume(const LLVolumeParams& params) + : LLVolume(params, 0.f) + { + } using FaceIndex = S32; static const FaceIndex UPDATE_ALL_FACES = -1; @@ -82,218 +82,218 @@ public: class LLVolumeInterface { public: - virtual ~LLVolumeInterface() { } - virtual LLVolumeInterfaceType getInterfaceType() const = 0; - virtual void doIdleUpdate() = 0; - virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; - virtual LLVector3 getPivotPosition() const = 0; - virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; - virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0; - virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0; - virtual void onShift(const LLVector4a &shift_vector) = 0; - virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance? - virtual bool isVolumeGlobal() const = 0; // Are we in global space? - virtual bool isActive() const = 0; // Is this object currently active? - virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; - virtual void updateRelativeXform(bool force_identity = false) = 0; - virtual U32 getID() const = 0; - virtual void preRebuild() = 0; + virtual ~LLVolumeInterface() { } + virtual LLVolumeInterfaceType getInterfaceType() const = 0; + virtual void doIdleUpdate() = 0; + virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; + virtual LLVector3 getPivotPosition() const = 0; + virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; + virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0; + virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0; + virtual void onShift(const LLVector4a &shift_vector) = 0; + virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance? + virtual bool isVolumeGlobal() const = 0; // Are we in global space? + virtual bool isActive() const = 0; // Is this object currently active? + virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; + virtual void updateRelativeXform(bool force_identity = false) = 0; + virtual U32 getID() const = 0; + virtual void preRebuild() = 0; }; // Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME) class LLVOVolume : public LLViewerObject { - LOG_CLASS(LLVOVolume); + LOG_CLASS(LLVOVolume); protected: - virtual ~LLVOVolume(); + virtual ~LLVOVolume(); public: - static void initClass(); - static void cleanupClass(); - static void preUpdateGeom(); - - enum - { - VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | - (1 << LLVertexBuffer::TYPE_NORMAL) | - (1 << LLVertexBuffer::TYPE_TEXCOORD0) | - (1 << LLVertexBuffer::TYPE_TEXCOORD1) | - (1 << LLVertexBuffer::TYPE_COLOR) - }; + static void initClass(); + static void cleanupClass(); + static void preUpdateGeom(); + + enum + { + VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | + (1 << LLVertexBuffer::TYPE_NORMAL) | + (1 << LLVertexBuffer::TYPE_TEXCOORD0) | + (1 << LLVertexBuffer::TYPE_TEXCOORD1) | + (1 << LLVertexBuffer::TYPE_COLOR) + }; public: - LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - void markDead() override; // Override (and call through to parent) to clean up media references - - LLDrawable* createDrawable(LLPipeline *pipeline) override; - - void deleteFaces(); - - void animateTextures(); - - BOOL isVisible() const ; - BOOL isActive() const override; - BOOL isAttachment() const override; - BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object - BOOL isHUDAttachment() const override; - - void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); - /*virtual*/ BOOL setParent(LLViewerObject* parent) override; - S32 getLOD() const override { return mLOD; } - void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; } - bool isNoLOD() const { return NO_LOD == mLOD; } - const LLVector3 getPivotPositionAgent() const override; - const LLMatrix4& getRelativeXform() const { return mRelativeXform; } - const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } - /*virtual*/ const LLMatrix4 getRenderMatrix() const override; - typedef std::unordered_set texture_cost_t; + LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + void markDead() override; // Override (and call through to parent) to clean up media references + + LLDrawable* createDrawable(LLPipeline *pipeline) override; + + void deleteFaces(); + + void animateTextures(); + + BOOL isVisible() const ; + BOOL isActive() const override; + BOOL isAttachment() const override; + BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object + BOOL isHUDAttachment() const override; + + void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); + /*virtual*/ BOOL setParent(LLViewerObject* parent) override; + S32 getLOD() const override { return mLOD; } + void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; } + bool isNoLOD() const { return NO_LOD == mLOD; } + const LLVector3 getPivotPositionAgent() const override; + const LLMatrix4& getRelativeXform() const { return mRelativeXform; } + const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } + /*virtual*/ const LLMatrix4 getRenderMatrix() const override; + typedef std::unordered_set texture_cost_t; static S32 getTextureCost(const LLViewerTexture* img); - U32 getRenderCost(texture_cost_t &textures) const; - /*virtual*/ F32 getEstTrianglesMax() const override; - /*virtual*/ F32 getEstTrianglesStreamingCost() const override; - /* virtual*/ F32 getStreamingCost() const override; + U32 getRenderCost(texture_cost_t &textures) const; + /*virtual*/ F32 getEstTrianglesMax() const override; + /*virtual*/ F32 getEstTrianglesStreamingCost() const override; + /* virtual*/ F32 getStreamingCost() const override; /*virtual*/ bool getCostData(LLMeshCostData& costs) const override; - /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override; - /*virtual*/ U32 getHighLODTriangleCount() override; - /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face = -1, // which face to check, -1 = ALL_SIDES - BOOL pick_transparent = FALSE, - BOOL pick_rigged = FALSE, + /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override; + /*virtual*/ U32 getHighLODTriangleCount() override; + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + BOOL pick_transparent = FALSE, + BOOL pick_rigged = FALSE, BOOL pick_unselectable = TRUE, - S32* face_hit = NULL, // which face was hit - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ) override; - - LLVector3 agentPositionToVolume(const LLVector3& pos) const; - LLVector3 agentDirectionToVolume(const LLVector3& dir) const; - LLVector3 volumePositionToAgent(const LLVector3& dir) const; - LLVector3 volumeDirectionToAgent(const LLVector3& dir) const; - - - BOOL getVolumeChanged() const { return mVolumeChanged; } - - F32 getVObjRadius() const override { return mVObjRadius; }; - const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override; - - void markForUpdate() override; - void faceMappingChanged() override { mFaceMappingChanged=TRUE; } - - /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts - - /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override; - /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override; + S32* face_hit = NULL, // which face was hit + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ) override; + + LLVector3 agentPositionToVolume(const LLVector3& pos) const; + LLVector3 agentDirectionToVolume(const LLVector3& dir) const; + LLVector3 volumePositionToAgent(const LLVector3& dir) const; + LLVector3 volumeDirectionToAgent(const LLVector3& dir) const; + + + BOOL getVolumeChanged() const { return mVolumeChanged; } + + F32 getVObjRadius() const override { return mVObjRadius; }; + const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override; + + void markForUpdate() override; + void faceMappingChanged() override { mFaceMappingChanged=TRUE; } + + /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts + + /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override; + /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override; // update mReflectionProbe based on isReflectionProbe() void updateReflectionProbePtr(); - /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, const EObjectUpdateType update_type, - LLDataPacker *dp) override; - - /*virtual*/ void setSelected(BOOL sel) override; - /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override; - - /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override; - - /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override; - /*virtual*/ void setNumTEs(const U8 num_tes) override; - /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override; - /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override; - /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override; - /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override; - /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override; - /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override; - /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override; - /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override; - /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override; - /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override; - /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override; - - static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); - - /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override; + /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, const EObjectUpdateType update_type, + LLDataPacker *dp) override; + + /*virtual*/ void setSelected(BOOL sel) override; + /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override; + + /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override; + + /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override; + /*virtual*/ void setNumTEs(const U8 num_tes) override; + /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override; + /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override; + /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override; + /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override; + /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override; + /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override; + /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override; + /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override; + /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override; + /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override; + /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override; + + static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); + + /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override; S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override; - /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override; - /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override; - /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override; - /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override; - /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override; - /*virtual*/ BOOL setMaterial(const U8 material) override; - - void setTexture(const S32 face); - S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];} - /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override; - void updateSculptTexture(); - void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;} - void sculpt(); - static void rebuildMeshAssetCallback(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status); - - void updateRelativeXform(bool force_identity = false); - /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override; - /*virtual*/ void updateFaceSize(S32 idx) override; - /*virtual*/ BOOL updateLOD() override; - void updateRadius() override; - /*virtual*/ void updateTextures() override; - void updateTextureVirtualSize(bool forced = false); - - void updateFaceFlags(); - void regenFaces(); + /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override; + /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override; + /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override; + /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override; + /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override; + /*virtual*/ BOOL setMaterial(const U8 material) override; + + void setTexture(const S32 face); + S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];} + /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override; + void updateSculptTexture(); + void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;} + void sculpt(); + static void rebuildMeshAssetCallback(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status); + + void updateRelativeXform(bool force_identity = false); + /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override; + /*virtual*/ void updateFaceSize(S32 idx) override; + /*virtual*/ BOOL updateLOD() override; + void updateRadius() override; + /*virtual*/ void updateTextures() override; + void updateTextureVirtualSize(bool forced = false); + + void updateFaceFlags(); + void regenFaces(); BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE); - void preRebuild(); - virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override; - virtual F32 getBinRadius() override; - - virtual U32 getPartitionType() const override; - - // For Lights - void setIsLight(BOOL is_light); + void preRebuild(); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override; + virtual F32 getBinRadius() override; + + virtual U32 getPartitionType() const override; + + // For Lights + void setIsLight(BOOL is_light); //set the gamma-corrected (sRGB) color of this light - void setLightSRGBColor(const LLColor3& color); + void setLightSRGBColor(const LLColor3& color); //set the linear color of this light void setLightLinearColor(const LLColor3& color); - void setLightIntensity(F32 intensity); - void setLightRadius(F32 radius); - void setLightFalloff(F32 falloff); - void setLightCutoff(F32 cutoff); - void setLightTextureID(LLUUID id); - void setSpotLightParams(LLVector3 params); + void setLightIntensity(F32 intensity); + void setLightRadius(F32 radius); + void setLightFalloff(F32 falloff); + void setLightCutoff(F32 cutoff); + void setLightTextureID(LLUUID id); + void setSpotLightParams(LLVector3 params); - BOOL getIsLight() const; + BOOL getIsLight() const; bool getIsLightFast() const; // Get the light color in sRGB color space NOT scaled by intensity. - LLColor3 getLightSRGBBaseColor() const; + LLColor3 getLightSRGBBaseColor() const; // Get the light color in linear color space NOT scaled by intensity. LLColor3 getLightLinearBaseColor() const; - - // Get the light color in linear color space scaled by intensity + + // Get the light color in linear color space scaled by intensity // this is the value that should be fed into shaders LLColor3 getLightLinearColor() const; // Get the light color in sRGB color space scaled by intensity. - LLColor3 getLightSRGBColor() const; + LLColor3 getLightSRGBColor() const; - LLUUID getLightTextureID() const; - bool isLightSpotlight() const; - LLVector3 getSpotLightParams() const; - void updateSpotLightPriority(); - F32 getSpotLightPriority() const; + LLUUID getLightTextureID() const; + bool isLightSpotlight() const; + LLVector3 getSpotLightParams() const; + void updateSpotLightPriority(); + F32 getSpotLightPriority() const; - LLViewerTexture* getLightTexture(); - F32 getLightIntensity() const; - F32 getLightRadius() const; - F32 getLightFalloff(const F32 fudge_factor = 1.f) const; - F32 getLightCutoff() const; + LLViewerTexture* getLightTexture(); + F32 getLightIntensity() const; + F32 getLightRadius() const; + F32 getLightFalloff(const F32 fudge_factor = 1.f) const; + F32 getLightCutoff() const; // Reflection Probes bool setIsReflectionProbe(BOOL is_probe); @@ -310,13 +310,13 @@ public: bool getReflectionProbeIsDynamic() const; bool getReflectionProbeIsMirror() const; - // Flexible Objects - U32 getVolumeInterfaceID() const; - virtual BOOL isFlexible() const override; - virtual BOOL isSculpted() const override; - virtual BOOL isMesh() const override; - virtual BOOL isRiggedMesh() const override; - virtual BOOL hasLightTexture() const override; + // Flexible Objects + U32 getVolumeInterfaceID() const; + virtual BOOL isFlexible() const override; + virtual BOOL isSculpted() const override; + virtual BOOL isMesh() const override; + virtual BOOL isRiggedMesh() const override; + virtual BOOL hasLightTexture() const override; // fast variants above that use state that is filled in later // not reliable early in the life of an object, but should be used after @@ -327,16 +327,16 @@ public: bool isRiggedMeshFast() const; bool isAnimatedObjectFast() const; - BOOL isVolumeGlobal() const; - BOOL canBeFlexible() const; - BOOL setIsFlexible(BOOL is_flexible); + BOOL isVolumeGlobal() const; + BOOL canBeFlexible() const; + BOOL setIsFlexible(BOOL is_flexible); const LLMeshSkinInfo* getSkinInfo() const; const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; } //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); } - + // Extended Mesh Properties U32 getExtendedMeshFlags() const; void onSetExtendedMeshFlags(U32 flags); @@ -349,58 +349,58 @@ public: //virtual void updateRiggingInfo() override; S32 mLastRiggingInfoLOD; - + // Functions that deal with media, or media navigation - + // Update this object's media data with the given media data array // (typically this is only called upon a response from a server request) - void updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version); - + void updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version); + // Bounce back media at the given index to its current URL (or home URL, if current URL is empty) - void mediaNavigateBounceBack(U8 texture_index); - - // Returns whether or not this object has permission to navigate or control - // the given media entry - enum MediaPermType { - MEDIA_PERM_INTERACT, MEDIA_PERM_CONTROL - }; + void mediaNavigateBounceBack(U8 texture_index); + + // Returns whether or not this object has permission to navigate or control + // the given media entry + enum MediaPermType { + MEDIA_PERM_INTERACT, MEDIA_PERM_CONTROL + }; bool hasMediaPermission(const LLMediaEntry* media_entry, MediaPermType perm_type); - - void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location); - void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event); - - - // Sync the given media data with the impl and the given te - void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent); - - // Send media data update to the simulator. - void sendMediaDataUpdate(); - - viewer_media_t getMediaImpl(U8 face_id) const; - S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id); - F64 getTotalMediaInterest() const; - - bool hasMedia() const; - - LLVector3 getApproximateFaceNormal(U8 face_id); + + void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location); + void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event); + + + // Sync the given media data with the impl and the given te + void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent); + + // Send media data update to the simulator. + void sendMediaDataUpdate(); + + viewer_media_t getMediaImpl(U8 face_id) const; + S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id); + F64 getTotalMediaInterest() const; + + bool hasMedia() const; + + LLVector3 getApproximateFaceNormal(U8 face_id); // Flag any corresponding avatars as needing update. void updateVisualComplexity(); - - void notifyMeshLoaded(); - void notifySkinInfoLoaded(const LLMeshSkinInfo* skin); - void notifySkinInfoUnavailable(); - - // Returns 'true' iff the media data for this object is in flight - bool isMediaDataBeingFetched() const; - - // Returns the "last fetched" media version, or -1 if not fetched yet - S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; } - - void addMDCImpl() { ++mMDCImplCount; } - void removeMDCImpl() { --mMDCImplCount; } - S32 getMDCImplCount() { return mMDCImplCount; } - + + void notifyMeshLoaded(); + void notifySkinInfoLoaded(const LLMeshSkinInfo* skin); + void notifySkinInfoUnavailable(); + + // Returns 'true' iff the media data for this object is in flight + bool isMediaDataBeingFetched() const; + + // Returns the "last fetched" media version, or -1 if not fetched yet + S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; } + + void addMDCImpl() { ++mMDCImplCount; } + void removeMDCImpl() { --mMDCImplCount; } + S32 getMDCImplCount() { return mMDCImplCount; } + // Rigged volume update (for raycasting) // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting @@ -408,69 +408,69 @@ public: bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); - LLRiggedVolume* getRiggedVolume(); + LLRiggedVolume* getRiggedVolume(); - //returns true if volume should be treated as a rigged volume - // - Build tools are open - // - object is an attachment - // - object is attached to self - // - object is rendered as rigged - bool treatAsRigged(); + //returns true if volume should be treated as a rigged volume + // - Build tools are open + // - object is an attachment + // - object is attached to self + // - object is rendered as rigged + bool treatAsRigged(); - //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates - void clearRiggedVolume(); + //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates + void clearRiggedVolume(); protected: - S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor); - BOOL calcLOD(); - LLFace* addFace(S32 face_index); - - // stats tracking for render complexity - static S32 mRenderComplexity_last; - static S32 mRenderComplexity_current; + S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor); + BOOL calcLOD(); + LLFace* addFace(S32 face_index); + + // stats tracking for render complexity + static S32 mRenderComplexity_last; + static S32 mRenderComplexity_current; void onDrawableUpdateFromServer(); - void requestMediaDataUpdate(bool isNew); - void cleanUpMediaImpls(); - void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ; - void removeMediaImpl(S32 texture_index) ; + void requestMediaDataUpdate(bool isNew); + void cleanUpMediaImpls(); + void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ; + void removeMediaImpl(S32 texture_index) ; private: bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds); public: - static S32 getRenderComplexityMax() {return mRenderComplexity_last;} - static void updateRenderComplexity(); + static S32 getRenderComplexityMax() {return mRenderComplexity_last;} + static void updateRenderComplexity(); - LLViewerTextureAnim *mTextureAnimp; - U8 mTexAnimMode; + LLViewerTextureAnim *mTextureAnimp; + U8 mTexAnimMode; F32 mLODDistance; F32 mLODAdjustedDistance; F32 mLODRadius; private: - friend class LLDrawable; - friend class LLFace; - - BOOL mFaceMappingChanged; - LLFrameTimer mTextureUpdateTimer; - S32 mLOD; - BOOL mLODChanged; - BOOL mSculptChanged; - BOOL mColorChanged; - F32 mSpotLightPriority; - LLMatrix4 mRelativeXform; - LLMatrix3 mRelativeXformInvTrans; - BOOL mVolumeChanged; - F32 mVObjRadius; - LLVolumeInterface *mVolumeImpl; - LLPointer mSculptTexture; - LLPointer mLightTexture; - media_list_t mMediaImplList; - S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 + friend class LLDrawable; + friend class LLFace; + + BOOL mFaceMappingChanged; + LLFrameTimer mTextureUpdateTimer; + S32 mLOD; + BOOL mLODChanged; + BOOL mSculptChanged; + BOOL mColorChanged; + F32 mSpotLightPriority; + LLMatrix4 mRelativeXform; + LLMatrix3 mRelativeXformInvTrans; + BOOL mVolumeChanged; + F32 mVObjRadius; + LLVolumeInterface *mVolumeImpl; + LLPointer mSculptTexture; + LLPointer mLightTexture; + media_list_t mMediaImplList; + S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 U32 mServerDrawableUpdateCount; - S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; - S32 mMDCImplCount; + S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; + S32 mMDCImplCount; // cached value of getIsLight to avoid redundant map lookups // accessed by getIsLightFast @@ -479,24 +479,24 @@ private: // cached value of getIsAnimatedObject to avoid redundant map lookups // accessed by getIsAnimatedObjectFast mutable bool mIsAnimatedObject = false; - bool mResetDebugText; + bool mResetDebugText; - LLPointer mRiggedVolume; + LLPointer mRiggedVolume; - bool mSkinInfoUnavaliable; - LLConstPointer mSkinInfo; - // statics + bool mSkinInfoUnavaliable; + LLConstPointer mSkinInfo; + // statics public: - static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop - static F32 sLODFactor; // LOD scale factor - static F32 sDistanceFactor; // LOD distance factor + static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop + static F32 sLODFactor; // LOD scale factor + static F32 sDistanceFactor; // LOD distance factor - static LLPointer sObjectMediaClient; - static LLPointer sObjectMediaNavigateClient; + static LLPointer sObjectMediaClient; + static LLPointer sObjectMediaNavigateClient; protected: - static S32 sNumLODChanges; + static S32 sNumLODChanges; - friend class LLVolumeImplFlexible; + friend class LLVolumeImplFlexible; }; #endif // LL_LLVOVOLUME_H diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 461d556946..1148e81fd5 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -3,25 +3,25 @@ * @author Nat Goodspeed * @date 2009-03-18 * @brief Implementation for llxmlrpclistener. - * + * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -88,13 +88,13 @@ class StatusMapper: public StatusMapperBase public: StatusMapper(): StatusMapperBase("Status") { - mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted"; - mMap[LLXMLRPCTransaction::StatusStarted] = "Started"; - mMap[LLXMLRPCTransaction::StatusDownloading] = "Downloading"; - mMap[LLXMLRPCTransaction::StatusComplete] = "Complete"; - mMap[LLXMLRPCTransaction::StatusCURLError] = "CURLError"; - mMap[LLXMLRPCTransaction::StatusXMLRPCError] = "XMLRPCError"; - mMap[LLXMLRPCTransaction::StatusOtherError] = "OtherError"; + mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted"; + mMap[LLXMLRPCTransaction::StatusStarted] = "Started"; + mMap[LLXMLRPCTransaction::StatusDownloading] = "Downloading"; + mMap[LLXMLRPCTransaction::StatusComplete] = "Complete"; + mMap[LLXMLRPCTransaction::StatusCURLError] = "CURLError"; + mMap[LLXMLRPCTransaction::StatusXMLRPCError] = "XMLRPCError"; + mMap[LLXMLRPCTransaction::StatusOtherError] = "OtherError"; } }; @@ -285,7 +285,7 @@ public: XMLRPC_RequestSetData(request, xparams); mTransaction.reset(new LLXMLRPCTransaction(mUri, request, true, command.has("http_params")? LLSD(command["http_params"]) : LLSD())); - mPreviousStatus = mTransaction->status(NULL); + mPreviousStatus = mTransaction->status(NULL); // Free the XMLRPC_REQUEST object and the attached data values. XMLRPC_RequestFree(request, 1); @@ -323,42 +323,42 @@ public: data["error"] = ""; data["transfer_rate"] = 0.0; LLEventPump& replyPump(LLEventPumps::instance().obtain(mReplyPump)); - if (! done) + if (! done) { // Not done yet, carry on. - if (status == LLXMLRPCTransaction::StatusDownloading - && status != mPreviousStatus) - { - // If a response has been received, send the - // 'downloading' status if it hasn't been sent. - replyPump.post(data); - } - - mPreviousStatus = status; + if (status == LLXMLRPCTransaction::StatusDownloading + && status != mPreviousStatus) + { + // If a response has been received, send the + // 'downloading' status if it hasn't been sent. + replyPump.post(data); + } + + mPreviousStatus = status; return false; } // Here the transaction is complete. Check status. data["error"] = mTransaction->statusMessage(); - data["transfer_rate"] = mTransaction->transferRate(); + data["transfer_rate"] = mTransaction->transferRate(); LL_INFOS("LLXMLRPCListener") << mMethod << " result from " << mUri << ": status " << data["status"].asString() << ", errorcode " << data["errorcode"].asString() << " (" << data["error"].asString() << ")" << LL_ENDL; - - switch (curlcode) - { + + switch (curlcode) + { #if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT - case CURLE_SSL_PEER_CERTIFICATE: + case CURLE_SSL_PEER_CERTIFICATE: #endif - case CURLE_SSL_CACERT: + case CURLE_SSL_CACERT: data["certificate"] = mTransaction->getErrorCertData(); - break; + break; - default: - break; - } + default: + break; + } // values of 'curlcode': // CURLE_COULDNT_RESOLVE_HOST, // CURLE_SSL_PEER_CERTIFICATE, @@ -547,7 +547,7 @@ private: const std::string mReplyPump; LLTempBoundListener mBoundListener; std::unique_ptr mTransaction; - LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes. + LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes. }; bool LLXMLRPCListener::process(const LLSD& command) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8b1e46343b..65307fe279 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1,25 +1,25 @@ -/** +/** * @file pipeline.cpp * @brief Rendering pipeline. * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,11 +40,11 @@ #include "llvolume.h" #include "material_codes.h" #include "v3color.h" -#include "llui.h" +#include "llui.h" #include "llglheaders.h" #include "llrender.h" #include "llstartup.h" -#include "llwindow.h" // swapBuffers() +#include "llwindow.h" // swapBuffers() // newview includes #include "llagent.h" @@ -219,9 +219,9 @@ extern BOOL gDebugGL; extern BOOL gCubeSnapshot; extern BOOL gSnapshotNoPost; -bool gAvatarBacklight = false; +bool gAvatarBacklight = false; -bool gDebugPipeline = false; +bool gDebugPipeline = false; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; @@ -280,42 +280,42 @@ LLVertexBuffer* ll_create_cube_vb(U32 type_mask); void display_update_camera(); //---------------------------------------- -S32 LLPipeline::sCompiles = 0; - -bool LLPipeline::sPickAvatar = true; -bool LLPipeline::sDynamicLOD = true; -bool LLPipeline::sShowHUDAttachments = true; -bool LLPipeline::sRenderMOAPBeacons = false; -bool LLPipeline::sRenderPhysicalBeacons = true; -bool LLPipeline::sRenderScriptedBeacons = false; -bool LLPipeline::sRenderScriptedTouchBeacons = true; -bool LLPipeline::sRenderParticleBeacons = false; -bool LLPipeline::sRenderSoundBeacons = false; -bool LLPipeline::sRenderBeacons = false; -bool LLPipeline::sRenderHighlight = true; +S32 LLPipeline::sCompiles = 0; + +bool LLPipeline::sPickAvatar = true; +bool LLPipeline::sDynamicLOD = true; +bool LLPipeline::sShowHUDAttachments = true; +bool LLPipeline::sRenderMOAPBeacons = false; +bool LLPipeline::sRenderPhysicalBeacons = true; +bool LLPipeline::sRenderScriptedBeacons = false; +bool LLPipeline::sRenderScriptedTouchBeacons = true; +bool LLPipeline::sRenderParticleBeacons = false; +bool LLPipeline::sRenderSoundBeacons = false; +bool LLPipeline::sRenderBeacons = false; +bool LLPipeline::sRenderHighlight = true; LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP; -bool LLPipeline::sForceOldBakedUpload = false; -S32 LLPipeline::sUseOcclusion = 0; -bool LLPipeline::sAutoMaskAlphaDeferred = true; -bool LLPipeline::sAutoMaskAlphaNonDeferred = false; -bool LLPipeline::sRenderTransparentWater = true; -bool LLPipeline::sBakeSunlight = false; -bool LLPipeline::sNoAlpha = false; -bool LLPipeline::sUseFarClip = true; -bool LLPipeline::sShadowRender = false; -bool LLPipeline::sRenderGlow = false; -bool LLPipeline::sReflectionRender = false; +bool LLPipeline::sForceOldBakedUpload = false; +S32 LLPipeline::sUseOcclusion = 0; +bool LLPipeline::sAutoMaskAlphaDeferred = true; +bool LLPipeline::sAutoMaskAlphaNonDeferred = false; +bool LLPipeline::sRenderTransparentWater = true; +bool LLPipeline::sBakeSunlight = false; +bool LLPipeline::sNoAlpha = false; +bool LLPipeline::sUseFarClip = true; +bool LLPipeline::sShadowRender = false; +bool LLPipeline::sRenderGlow = false; +bool LLPipeline::sReflectionRender = false; bool LLPipeline::sDistortionRender = false; -bool LLPipeline::sImpostorRender = false; -bool LLPipeline::sImpostorRenderAlphaDepthPass = false; -bool LLPipeline::sUnderWaterRender = false; -bool LLPipeline::sTextureBindTest = false; -bool LLPipeline::sRenderAttachedLights = true; -bool LLPipeline::sRenderAttachedParticles = true; -bool LLPipeline::sRenderDeferred = false; -bool LLPipeline::sReflectionProbesEnabled = false; -S32 LLPipeline::sVisibleLightCount = 0; -bool LLPipeline::sRenderingHUDs; +bool LLPipeline::sImpostorRender = false; +bool LLPipeline::sImpostorRenderAlphaDepthPass = false; +bool LLPipeline::sUnderWaterRender = false; +bool LLPipeline::sTextureBindTest = false; +bool LLPipeline::sRenderAttachedLights = true; +bool LLPipeline::sRenderAttachedParticles = true; +bool LLPipeline::sRenderDeferred = false; +bool LLPipeline::sReflectionProbesEnabled = false; +S32 LLPipeline::sVisibleLightCount = 0; +bool LLPipeline::sRenderingHUDs; F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; // EventHost API LLPipeline listener. @@ -337,29 +337,29 @@ bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false) } LLPipeline::LLPipeline() : - mBackfaceCull(false), - mMatrixOpCount(0), - mTextureMatrixOps(0), - mNumVisibleNodes(0), - mNumVisibleFaces(0), - mPoissonOffset(0), - - mInitialized(false), - mShadersLoaded(false), - mTransformFeedbackPrimitives(0), - mRenderDebugFeatureMask(0), - mRenderDebugMask(0), - mOldRenderDebugMask(0), - mMeshDirtyQueryObject(0), - mGroupQ1Locked(false), - mResetVertexBuffers(false), - mLastRebuildPool(NULL), - mLightMask(0), - mLightMovingMask(0) -{ - mNoiseMap = 0; - mTrueNoiseMap = 0; - mLightFunc = 0; + mBackfaceCull(false), + mMatrixOpCount(0), + mTextureMatrixOps(0), + mNumVisibleNodes(0), + mNumVisibleFaces(0), + mPoissonOffset(0), + + mInitialized(false), + mShadersLoaded(false), + mTransformFeedbackPrimitives(0), + mRenderDebugFeatureMask(0), + mRenderDebugMask(0), + mOldRenderDebugMask(0), + mMeshDirtyQueryObject(0), + mGroupQ1Locked(false), + mResetVertexBuffers(false), + mLastRebuildPool(NULL), + mLightMask(0), + mLightMovingMask(0) +{ + mNoiseMap = 0; + mTrueNoiseMap = 0; + mLightFunc = 0; for(U32 i = 0; i < 8; i++) { @@ -369,99 +369,99 @@ LLPipeline::LLPipeline() : void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) { - LLPointer cntrl_ptr = gSavedSettings.getControl(name); - if ( cntrl_ptr.isNull() ) - { - LL_WARNS() << "Global setting name not found:" << name << LL_ENDL; - } - else - { - cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - } + LLPointer cntrl_ptr = gSavedSettings.getControl(name); + if ( cntrl_ptr.isNull() ) + { + LL_WARNS() << "Global setting name not found:" << name << LL_ENDL; + } + else + { + cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + } } void LLPipeline::init() { - refreshCachedSettings(); + refreshCachedSettings(); mRT = &mMainRT; - gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); - gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); - sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); - sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); - sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); + sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); + sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); + sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); mInitialized = true; - - stop_glerror(); - //create render pass pools - getPool(LLDrawPool::POOL_ALPHA_PRE_WATER); + stop_glerror(); + + //create render pass pools + getPool(LLDrawPool::POOL_ALPHA_PRE_WATER); getPool(LLDrawPool::POOL_ALPHA_POST_WATER); - getPool(LLDrawPool::POOL_SIMPLE); - getPool(LLDrawPool::POOL_ALPHA_MASK); - getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK); - getPool(LLDrawPool::POOL_GRASS); - getPool(LLDrawPool::POOL_FULLBRIGHT); - getPool(LLDrawPool::POOL_BUMP); - getPool(LLDrawPool::POOL_MATERIALS); - getPool(LLDrawPool::POOL_GLOW); - getPool(LLDrawPool::POOL_GLTF_PBR); + getPool(LLDrawPool::POOL_SIMPLE); + getPool(LLDrawPool::POOL_ALPHA_MASK); + getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK); + getPool(LLDrawPool::POOL_GRASS); + getPool(LLDrawPool::POOL_FULLBRIGHT); + getPool(LLDrawPool::POOL_BUMP); + getPool(LLDrawPool::POOL_MATERIALS); + getPool(LLDrawPool::POOL_GLOW); + getPool(LLDrawPool::POOL_GLTF_PBR); getPool(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK); - resetFrameStats(); - - if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) - { - clearAllRenderDebugFeatures(); - } - else - { - setAllRenderDebugFeatures(); // By default, all debugging features on - } - clearAllRenderDebugDisplays(); // All debug displays off - - if (gSavedSettings.getBOOL("DisableAllRenderTypes")) - { - clearAllRenderTypes(); - } - else if (gNonInteractive) - { - clearAllRenderTypes(); - } - else - { - setAllRenderTypes(); // By default, all rendering types start enabled - } - - // make sure RenderPerformanceTest persists (hackity hack hack) - // disables non-object rendering (UI, sky, water, etc) - if (gSavedSettings.getBOOL("RenderPerformanceTest")) - { - gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); - gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); - } - - mOldRenderDebugMask = mRenderDebugMask; - - mBackfaceCull = true; - - // Enable features - LLViewerShaderMgr::instance()->setShaders(); - - for (U32 i = 0; i < 2; ++i) - { - mSpotLightFade[i] = 1.f; - } - - if (mCubeVB.isNull()) - { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); - } - - mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK); - mDeferredVB->allocateBuffer(8, 0); + resetFrameStats(); + + if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) + { + clearAllRenderDebugFeatures(); + } + else + { + setAllRenderDebugFeatures(); // By default, all debugging features on + } + clearAllRenderDebugDisplays(); // All debug displays off + + if (gSavedSettings.getBOOL("DisableAllRenderTypes")) + { + clearAllRenderTypes(); + } + else if (gNonInteractive) + { + clearAllRenderTypes(); + } + else + { + setAllRenderTypes(); // By default, all rendering types start enabled + } + + // make sure RenderPerformanceTest persists (hackity hack hack) + // disables non-object rendering (UI, sky, water, etc) + if (gSavedSettings.getBOOL("RenderPerformanceTest")) + { + gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); + gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); + } + + mOldRenderDebugMask = mRenderDebugMask; + + mBackfaceCull = true; + + // Enable features + LLViewerShaderMgr::instance()->setShaders(); + + for (U32 i = 0; i < 2; ++i) + { + mSpotLightFade[i] = 1.f; + } + + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); + } + + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK); + mDeferredVB->allocateBuffer(8, 0); { mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX); @@ -476,83 +476,83 @@ void LLPipeline::init() mScreenTriangleVB->unmapBuffer(); } - // - // Update all settings to trigger a cached settings refresh - // - connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); - connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); - connectRefreshCachedSettingsSafe("RenderUseFarClip"); - connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); - connectRefreshCachedSettingsSafe("UseOcclusion"); - // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); - // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred"); - connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); - connectRefreshCachedSettingsSafe("RenderFSAASamples"); - connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); - connectRefreshCachedSettingsSafe("RenderUIBuffer"); - connectRefreshCachedSettingsSafe("RenderShadowDetail"); + // + // Update all settings to trigger a cached settings refresh + // + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); + connectRefreshCachedSettingsSafe("RenderUseFarClip"); + connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); + connectRefreshCachedSettingsSafe("UseOcclusion"); + // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); + // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred"); + connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); + connectRefreshCachedSettingsSafe("RenderFSAASamples"); + connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); + connectRefreshCachedSettingsSafe("RenderUIBuffer"); + connectRefreshCachedSettingsSafe("RenderShadowDetail"); connectRefreshCachedSettingsSafe("RenderShadowSplits"); - connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); - connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); - connectRefreshCachedSettingsSafe("RenderDelayCreation"); - connectRefreshCachedSettingsSafe("RenderAnimateRes"); - connectRefreshCachedSettingsSafe("FreezeTime"); - connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); - connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); - connectRefreshCachedSettingsSafe("RenderHighlightColor"); - connectRefreshCachedSettingsSafe("RenderHighlightThickness"); - connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); - connectRefreshCachedSettingsSafe("PreviewAmbientColor"); - connectRefreshCachedSettingsSafe("PreviewDiffuse0"); - connectRefreshCachedSettingsSafe("PreviewSpecular0"); - connectRefreshCachedSettingsSafe("PreviewDiffuse1"); - connectRefreshCachedSettingsSafe("PreviewSpecular1"); - connectRefreshCachedSettingsSafe("PreviewDiffuse2"); - connectRefreshCachedSettingsSafe("PreviewSpecular2"); - connectRefreshCachedSettingsSafe("PreviewDirection0"); - connectRefreshCachedSettingsSafe("PreviewDirection1"); - connectRefreshCachedSettingsSafe("PreviewDirection2"); - connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); - connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); - connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); - connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); - connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); - connectRefreshCachedSettingsSafe("RenderGlowIterations"); - connectRefreshCachedSettingsSafe("RenderGlowWidth"); - connectRefreshCachedSettingsSafe("RenderGlowStrength"); - connectRefreshCachedSettingsSafe("RenderGlowNoise"); - connectRefreshCachedSettingsSafe("RenderDepthOfField"); - connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); - connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); - connectRefreshCachedSettingsSafe("CameraFNumber"); - connectRefreshCachedSettingsSafe("CameraFocalLength"); - connectRefreshCachedSettingsSafe("CameraFieldOfView"); - connectRefreshCachedSettingsSafe("RenderShadowNoise"); - connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); - connectRefreshCachedSettingsSafe("RenderSSAOScale"); - connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); - connectRefreshCachedSettingsSafe("RenderSSAOFactor"); - connectRefreshCachedSettingsSafe("RenderSSAOEffect"); - connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); - connectRefreshCachedSettingsSafe("RenderShadowBiasError"); - connectRefreshCachedSettingsSafe("RenderShadowOffset"); - connectRefreshCachedSettingsSafe("RenderShadowBias"); - connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); - connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); - connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); - connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); - connectRefreshCachedSettingsSafe("RenderShadowGaussian"); - connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); - connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); - connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); - connectRefreshCachedSettingsSafe("RenderFarClip"); - connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); - connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); - connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); - connectRefreshCachedSettingsSafe("CameraOffset"); - connectRefreshCachedSettingsSafe("CameraMaxCoF"); - connectRefreshCachedSettingsSafe("CameraDoFResScale"); - connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); + connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); + connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); + connectRefreshCachedSettingsSafe("RenderDelayCreation"); + connectRefreshCachedSettingsSafe("RenderAnimateRes"); + connectRefreshCachedSettingsSafe("FreezeTime"); + connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); + connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); + connectRefreshCachedSettingsSafe("RenderHighlightColor"); + connectRefreshCachedSettingsSafe("RenderHighlightThickness"); + connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); + connectRefreshCachedSettingsSafe("PreviewAmbientColor"); + connectRefreshCachedSettingsSafe("PreviewDiffuse0"); + connectRefreshCachedSettingsSafe("PreviewSpecular0"); + connectRefreshCachedSettingsSafe("PreviewDiffuse1"); + connectRefreshCachedSettingsSafe("PreviewSpecular1"); + connectRefreshCachedSettingsSafe("PreviewDiffuse2"); + connectRefreshCachedSettingsSafe("PreviewSpecular2"); + connectRefreshCachedSettingsSafe("PreviewDirection0"); + connectRefreshCachedSettingsSafe("PreviewDirection1"); + connectRefreshCachedSettingsSafe("PreviewDirection2"); + connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); + connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); + connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); + connectRefreshCachedSettingsSafe("RenderGlowIterations"); + connectRefreshCachedSettingsSafe("RenderGlowWidth"); + connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderGlowNoise"); + connectRefreshCachedSettingsSafe("RenderDepthOfField"); + connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); + connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); + connectRefreshCachedSettingsSafe("CameraFNumber"); + connectRefreshCachedSettingsSafe("CameraFocalLength"); + connectRefreshCachedSettingsSafe("CameraFieldOfView"); + connectRefreshCachedSettingsSafe("RenderShadowNoise"); + connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); + connectRefreshCachedSettingsSafe("RenderSSAOScale"); + connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); + connectRefreshCachedSettingsSafe("RenderSSAOFactor"); + connectRefreshCachedSettingsSafe("RenderSSAOEffect"); + connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); + connectRefreshCachedSettingsSafe("RenderShadowBiasError"); + connectRefreshCachedSettingsSafe("RenderShadowOffset"); + connectRefreshCachedSettingsSafe("RenderShadowBias"); + connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); + connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); + connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); + connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowGaussian"); + connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); + connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); + connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); + connectRefreshCachedSettingsSafe("RenderFarClip"); + connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); + connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); + connectRefreshCachedSettingsSafe("CameraOffset"); + connectRefreshCachedSettingsSafe("CameraMaxCoF"); + connectRefreshCachedSettingsSafe("CameraDoFResScale"); + connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflections"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionIterations"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionRayStep"); @@ -560,11 +560,11 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionDepthRejectBias"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionAdaptiveStepMultiplier"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples"); - connectRefreshCachedSettingsSafe("RenderBufferVisualization"); + connectRefreshCachedSettingsSafe("RenderBufferVisualization"); connectRefreshCachedSettingsSafe("RenderMirrors"); connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate"); connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier"); - gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } LLPipeline::~LLPipeline() @@ -573,78 +573,78 @@ LLPipeline::~LLPipeline() void LLPipeline::cleanup() { - assertInitialized(); - - mGroupQ1.clear() ; - - for(pool_set_t::iterator iter = mPools.begin(); - iter != mPools.end(); ) - { - pool_set_t::iterator curiter = iter++; - LLDrawPool* poolp = *curiter; - if (poolp->isFacePool()) - { - LLFacePool* face_pool = (LLFacePool*) poolp; - if (face_pool->mReferences.empty()) - { - mPools.erase(curiter); - removeFromQuickLookup( poolp ); - delete poolp; - } - } - else - { - mPools.erase(curiter); - removeFromQuickLookup( poolp ); - delete poolp; - } - } - - if (!mTerrainPools.empty()) - { - LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL; - } - if (!mTreePools.empty()) - { - LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL; - } - - delete mAlphaPoolPreWater; + assertInitialized(); + + mGroupQ1.clear() ; + + for(pool_set_t::iterator iter = mPools.begin(); + iter != mPools.end(); ) + { + pool_set_t::iterator curiter = iter++; + LLDrawPool* poolp = *curiter; + if (poolp->isFacePool()) + { + LLFacePool* face_pool = (LLFacePool*) poolp; + if (face_pool->mReferences.empty()) + { + mPools.erase(curiter); + removeFromQuickLookup( poolp ); + delete poolp; + } + } + else + { + mPools.erase(curiter); + removeFromQuickLookup( poolp ); + delete poolp; + } + } + + if (!mTerrainPools.empty()) + { + LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL; + } + if (!mTreePools.empty()) + { + LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL; + } + + delete mAlphaPoolPreWater; mAlphaPoolPreWater = nullptr; delete mAlphaPoolPostWater; mAlphaPoolPostWater = nullptr; - delete mSkyPool; - mSkyPool = NULL; - delete mTerrainPool; - mTerrainPool = NULL; - delete mWaterPool; - mWaterPool = NULL; - delete mSimplePool; - mSimplePool = NULL; - delete mFullbrightPool; - mFullbrightPool = NULL; - delete mGlowPool; - mGlowPool = NULL; - delete mBumpPool; - mBumpPool = NULL; - // don't delete wl sky pool it was handled above in the for loop - //delete mWLSkyPool; - mWLSkyPool = NULL; - - releaseGLBuffers(); - - mFaceSelectImagep = NULL; + delete mSkyPool; + mSkyPool = NULL; + delete mTerrainPool; + mTerrainPool = NULL; + delete mWaterPool; + mWaterPool = NULL; + delete mSimplePool; + mSimplePool = NULL; + delete mFullbrightPool; + mFullbrightPool = NULL; + delete mGlowPool; + mGlowPool = NULL; + delete mBumpPool; + mBumpPool = NULL; + // don't delete wl sky pool it was handled above in the for loop + //delete mWLSkyPool; + mWLSkyPool = NULL; + + releaseGLBuffers(); + + mFaceSelectImagep = NULL; mMovedList.clear(); mMovedBridge.clear(); mShiftList.clear(); - mInitialized = false; + mInitialized = false; - mDeferredVB = NULL; + mDeferredVB = NULL; mScreenTriangleVB = nullptr; - mCubeVB = NULL; + mCubeVB = NULL; mReflectionMapManager.cleanup(); mHeroProbeManager.cleanup(); @@ -652,21 +652,21 @@ void LLPipeline::cleanup() //============================================================================ -void LLPipeline::destroyGL() +void LLPipeline::destroyGL() { - stop_glerror(); - unloadShaders(); - mHighlightFaces.clear(); - - resetDrawOrders(); + stop_glerror(); + unloadShaders(); + mHighlightFaces.clear(); + + resetDrawOrders(); - releaseGLBuffers(); + releaseGLBuffers(); - if (mMeshDirtyQueryObject) - { - glDeleteQueries(1, &mMeshDirtyQueryObject); - mMeshDirtyQueryObject = 0; - } + if (mMeshDirtyQueryObject) + { + glDeleteQueries(1, &mMeshDirtyQueryObject); + mMeshDirtyQueryObject = 0; + } } void LLPipeline::requestResizeScreenTexture() @@ -689,86 +689,86 @@ void LLPipeline::resizeShadowTexture() void LLPipeline::resizeScreenTexture() { - if (gPipeline.shadersLoaded()) - { - GLuint resX = gViewerWindow->getWorldViewWidthRaw(); - GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - - if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight())) - { - releaseScreenBuffers(); + if (gPipeline.shadersLoaded()) + { + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight())) + { + releaseScreenBuffers(); releaseSunShadowTargets(); releaseSpotShadowTargets(); - allocateScreenBuffer(resX,resY); + allocateScreenBuffer(resX,resY); gResizeScreenTexture = FALSE; - } - } + } + } } bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + eFBOStatus ret = doAllocateScreenBuffer(resX, resY); - return ret == FBO_SUCCESS_FULLRES; + return ret == FBO_SUCCESS_FULLRES; } LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - // try to allocate screen buffers at requested resolution and samples - // - on failure, shrink number of samples and try again - // - if not multisampled, shrink resolution and try again (favor X resolution over Y) - // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + // try to allocate screen buffers at requested resolution and samples + // - on failure, shrink number of samples and try again + // - if not multisampled, shrink resolution and try again (favor X resolution over Y) + // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state // refresh cached settings here to protect against inconsistent event handling order refreshCachedSettings(); - U32 samples = RenderFSAASamples; - - eFBOStatus ret = FBO_SUCCESS_FULLRES; - if (!allocateScreenBuffer(resX, resY, samples)) - { - //failed to allocate at requested specification, return false - ret = FBO_FAILURE; - - releaseScreenBuffers(); - //reduce number of samples - while (samples > 0) - { - samples /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { //success - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); - } - - samples = 0; - - //reduce resolution - while (resY > 0 && resX > 0) - { - resY /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); - - resX /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); - } - - LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL; - } - - return ret; + U32 samples = RenderFSAASamples; + + eFBOStatus ret = FBO_SUCCESS_FULLRES; + if (!allocateScreenBuffer(resX, resY, samples)) + { + //failed to allocate at requested specification, return false + ret = FBO_FAILURE; + + releaseScreenBuffers(); + //reduce number of samples + while (samples > 0) + { + samples /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { //success + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + } + + samples = 0; + + //reduce resolution + while (resY > 0 && resX > 0) + { + resY /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + + resX /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + } + + LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL; + } + + return ret; } bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) @@ -791,7 +791,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled allocateScreenBuffer(res, res, samples); - if (RenderMirrors) + if (RenderMirrors) { mHeroProbeManager.initReflectionMaps(); res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it. @@ -803,59 +803,59 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) gCubeSnapshot = FALSE; } - // remember these dimensions - mRT->width = resX; - mRT->height = resY; - - U32 res_mod = RenderResolutionDivisor; + // remember these dimensions + mRT->width = resX; + mRT->height = resY; + + U32 res_mod = RenderResolutionDivisor; - if (res_mod > 1 && res_mod < resX && res_mod < resY) - { - resX /= res_mod; - resY /= res_mod; - } + if (res_mod > 1 && res_mod < resX && res_mod < resY) + { + resX /= res_mod; + resY /= res_mod; + } //water reflection texture (always needed as scratch space whether or not transparent water is enabled) mWaterDis.allocate(resX, resY, GL_RGBA16F, true); - if (RenderUIBuffer) - { - if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA)) - { - return false; - } - } - - S32 shadow_detail = RenderShadowDetail; - bool ssao = RenderDeferredSSAO; - - //allocate deferred rendering color buffers - if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false; - if (!addDeferredAttachments(mRT->deferredScreen)) return false; - - GLuint screenFormat = GL_RGBA16F; - - if (!mRT->screen.allocate(resX, resY, screenFormat)) return false; + if (RenderUIBuffer) + { + if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA)) + { + return false; + } + } + + S32 shadow_detail = RenderShadowDetail; + bool ssao = RenderDeferredSSAO; + + //allocate deferred rendering color buffers + if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false; + if (!addDeferredAttachments(mRT->deferredScreen)) return false; + + GLuint screenFormat = GL_RGBA16F; + + if (!mRT->screen.allocate(resX, resY, screenFormat)) return false; mRT->deferredScreen.shareDepthBuffer(mRT->screen); - if (samples > 0) - { - if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false; - } - else - { - mRT->fxaaBuffer.release(); - } - - if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) - { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa - if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false; - } - else - { - mRT->deferredLight.release(); - } + if (samples > 0) + { + if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false; + } + else + { + mRT->fxaaBuffer.release(); + } + + if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) + { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa + if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false; + } + else + { + mRT->deferredLight.release(); + } allocateShadowBuffer(resX, resY); @@ -864,7 +864,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mSceneMap.allocate(resX, resY, GL_RGB, true); } - const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR"); + const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR"); const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA; mPostMap.allocate(resX, resY, post_color_fmt); @@ -876,9 +876,9 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) gGL.getTexUnit(0)->disable(); - stop_glerror(); + stop_glerror(); - return true; + return true; } // must be even to avoid a stripe in the horizontal shadow blur @@ -937,7 +937,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) // set up shadow map filtering and compare modes if (shadow_detail > 0) - { + { for (U32 i = 0; i < 4; i++) { LLRenderTarget* shadow_target = getSunShadowTarget(i); @@ -970,7 +970,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) } } - return true; + return true; } //static @@ -983,86 +983,86 @@ void LLPipeline::updateRenderTransparentWater() void LLPipeline::refreshCachedSettings() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); - LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); - LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); - LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors"); - LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); - - LLPipeline::sUseOcclusion = - (!gUseWireframe - && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0; - + LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); + LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); + LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); + LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors"); + LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); + + LLPipeline::sUseOcclusion = + (!gUseWireframe + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") + && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0; + WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred"); - RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); - RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0; - RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); - RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); - RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); + RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); + RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0; + RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); + RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); + RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits"); - RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); - RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); - RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); - RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); - FreezeTime = gSavedSettings.getBOOL("FreezeTime"); - DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); - RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); - RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor"); - RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness"); - RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"); - PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor"); - PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); - PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0"); - PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); - PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1"); - PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); - PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2"); - PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0"); - PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1"); - PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2"); - RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); - RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); - RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); - RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); - RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow"); - RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); - RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); - RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); - RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise"); - RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); - RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); - CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); - CameraFNumber = gSavedSettings.getF32("CameraFNumber"); - CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); - CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); - RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); - RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); - RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); - RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale"); - RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor"); - RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect"); - RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError"); - RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError"); - RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset"); - RenderShadowBias = gSavedSettings.getF32("RenderShadowBias"); - RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset"); - RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias"); - RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff"); - RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff"); - RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian"); - RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); - RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); - RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); - RenderFarClip = gSavedSettings.getF32("RenderFarClip"); - RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); - RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); - RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff"); - CameraOffset = gSavedSettings.getBOOL("CameraOffset"); - CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); - CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); - RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); + RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); + RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); + RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); + RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); + FreezeTime = gSavedSettings.getBOOL("FreezeTime"); + DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); + RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); + RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor"); + RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness"); + RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"); + PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor"); + PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); + PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0"); + PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); + PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1"); + PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); + PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2"); + PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0"); + PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1"); + PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2"); + RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); + RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); + RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); + RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); + RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow"); + RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); + RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); + RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); + RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise"); + RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); + RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); + CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); + CameraFNumber = gSavedSettings.getF32("CameraFNumber"); + CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); + CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); + RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); + RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); + RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); + RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale"); + RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor"); + RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect"); + RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError"); + RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError"); + RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset"); + RenderShadowBias = gSavedSettings.getF32("RenderShadowBias"); + RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset"); + RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias"); + RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff"); + RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff"); + RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian"); + RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); + RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); + RenderFarClip = gSavedSettings.getF32("RenderFarClip"); + RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); + RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); + RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff"); + CameraOffset = gSavedSettings.getBOOL("CameraOffset"); + CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); + CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); + RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); RenderScreenSpaceReflections = gSavedSettings.getBOOL("RenderScreenSpaceReflections"); RenderScreenSpaceReflectionIterations = gSavedSettings.getS32("RenderScreenSpaceReflectionIterations"); RenderScreenSpaceReflectionRayStep = gSavedSettings.getF32("RenderScreenSpaceReflectionRayStep"); @@ -1070,7 +1070,7 @@ void LLPipeline::refreshCachedSettings() RenderScreenSpaceReflectionDepthRejectBias = gSavedSettings.getF32("RenderScreenSpaceReflectionDepthRejectBias"); RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier"); RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples"); - RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization"); + RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization"); if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors) { RenderMirrors = gSavedSettings.getBOOL("RenderMirrors"); @@ -1081,57 +1081,57 @@ void LLPipeline::refreshCachedSettings() RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier"); sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); - RenderSpotLight = nullptr; + RenderSpotLight = nullptr; - if (gNonInteractive) - { - LLVOAvatar::sMaxNonImpostors = 1; - LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); - } + if (gNonInteractive) + { + LLVOAvatar::sMaxNonImpostors = 1; + LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); + } } void LLPipeline::releaseGLBuffers() { - assertInitialized(); - - if (mNoiseMap) - { - LLImageGL::deleteTextures(1, &mNoiseMap); - mNoiseMap = 0; - } + assertInitialized(); + + if (mNoiseMap) + { + LLImageGL::deleteTextures(1, &mNoiseMap); + mNoiseMap = 0; + } + + if (mTrueNoiseMap) + { + LLImageGL::deleteTextures(1, &mTrueNoiseMap); + mTrueNoiseMap = 0; + } - if (mTrueNoiseMap) - { - LLImageGL::deleteTextures(1, &mTrueNoiseMap); - mTrueNoiseMap = 0; - } + releaseLUTBuffers(); - releaseLUTBuffers(); + mWaterDis.release(); - mWaterDis.release(); - mSceneMap.release(); mPostMap.release(); - for (U32 i = 0; i < 3; i++) - { - mGlow[i].release(); - } + for (U32 i = 0; i < 3; i++) + { + mGlow[i].release(); + } - releaseScreenBuffers(); + releaseScreenBuffers(); - gBumpImageList.destroyGL(); - LLVOAvatar::resetImpostors(); + gBumpImageList.destroyGL(); + LLVOAvatar::resetImpostors(); } void LLPipeline::releaseLUTBuffers() { - if (mLightFunc) - { - LLImageGL::deleteTextures(1, &mLightFunc); - mLightFunc = 0; - } + if (mLightFunc) + { + LLImageGL::deleteTextures(1, &mLightFunc); + mLightFunc = 0; + } mPbrBrdfLut.release(); @@ -1155,11 +1155,11 @@ void LLPipeline::releaseScreenBuffers() mRT->deferredScreen.release(); mRT->deferredLight.release(); - mHeroProbeRT.uiScreen.release(); - mHeroProbeRT.screen.release(); - mHeroProbeRT.fxaaBuffer.release(); - mHeroProbeRT.deferredScreen.release(); - mHeroProbeRT.deferredLight.release(); + mHeroProbeRT.uiScreen.release(); + mHeroProbeRT.screen.release(); + mHeroProbeRT.fxaaBuffer.release(); + mHeroProbeRT.deferredScreen.release(); + mHeroProbeRT.deferredLight.release(); } void LLPipeline::releaseSunShadowTarget(U32 index) @@ -1170,10 +1170,10 @@ void LLPipeline::releaseSunShadowTarget(U32 index) void LLPipeline::releaseSunShadowTargets() { - for (U32 i = 0; i < 4; i++) - { + for (U32 i = 0; i < 4; i++) + { releaseSunShadowTarget(i); - } + } } void LLPipeline::releaseSpotShadowTargets() @@ -1191,16 +1191,16 @@ void LLPipeline::createGLBuffers() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; stop_glerror(); - assertInitialized(); + assertInitialized(); - stop_glerror(); + stop_glerror(); - GLuint resX = gViewerWindow->getWorldViewWidthRaw(); - GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); // allocate screen space glow buffers const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); - const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR"); + const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR"); const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA; for (U32 i = 0; i < 3; i++) { @@ -1211,100 +1211,100 @@ void LLPipeline::createGLBuffers() mRT->width = 0; mRT->height = 0; - - if (!mNoiseMap) - { - const U32 noiseRes = 128; - LLVector3 noise[noiseRes*noiseRes]; - - F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; - for (U32 i = 0; i < noiseRes*noiseRes; ++i) - { - noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); - noise[i].normVec(); - noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; - } - - LLImageGL::generateTextures(1, &mNoiseMap); - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - if (!mTrueNoiseMap) - { - const U32 noiseRes = 128; - F32 noise[noiseRes*noiseRes*3]; - for (U32 i = 0; i < noiseRes*noiseRes*3; i++) - { - noise[i] = ll_frand()*2.0-1.0; - } - - LLImageGL::generateTextures(1, &mTrueNoiseMap); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - createLUTBuffers(); - - gBumpImageList.restoreGL(); + + if (!mNoiseMap) + { + const U32 noiseRes = 128; + LLVector3 noise[noiseRes*noiseRes]; + + F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; + for (U32 i = 0; i < noiseRes*noiseRes; ++i) + { + noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); + noise[i].normVec(); + noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; + } + + LLImageGL::generateTextures(1, &mNoiseMap); + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + if (!mTrueNoiseMap) + { + const U32 noiseRes = 128; + F32 noise[noiseRes*noiseRes*3]; + for (U32 i = 0; i < noiseRes*noiseRes*3; i++) + { + noise[i] = ll_frand()*2.0-1.0; + } + + LLImageGL::generateTextures(1, &mTrueNoiseMap); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + createLUTBuffers(); + + gBumpImageList.restoreGL(); } F32 lerpf(F32 a, F32 b, F32 w) { - return a + w * (b - a); + return a + w * (b - a); } void LLPipeline::createLUTBuffers() { - if (!mLightFunc) - { - U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); - U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - F32* ls = new F32[lightResX*lightResY]; - F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); + if (!mLightFunc) + { + U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); + U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); + F32* ls = new F32[lightResX*lightResY]; + F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) - for (U32 y = 0; y < lightResY; ++y) - { - for (U32 x = 0; x < lightResX; ++x) - { - ls[y*lightResX+x] = 0; - F32 sa = (F32) x/(lightResX-1); - F32 spec = (F32) y/(lightResY-1); - F32 n = spec * spec * specExp; - - // Nothing special here. Just your typical blinn-phong term. - spec = powf(sa, n); - - // Apply our normalization function. - // Note: This is the full equation that applies the full normalization curve, not an approximation. - // This is fine, given we only need to create our LUT once per buffer initialization. - spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); - - // Since we use R16F, we no longer have a dynamic range issue we need to work around here. - // Though some older drivers may not like this, newer drivers shouldn't have this problem. - ls[y*lightResX+x] = spec; - } - } - - U32 pix_format = GL_R16F; + for (U32 y = 0; y < lightResY; ++y) + { + for (U32 x = 0; x < lightResX; ++x) + { + ls[y*lightResX+x] = 0; + F32 sa = (F32) x/(lightResX-1); + F32 spec = (F32) y/(lightResY-1); + F32 n = spec * spec * specExp; + + // Nothing special here. Just your typical blinn-phong term. + spec = powf(sa, n); + + // Apply our normalization function. + // Note: This is the full equation that applies the full normalization curve, not an approximation. + // This is fine, given we only need to create our LUT once per buffer initialization. + spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + + // Since we use R16F, we no longer have a dynamic range issue we need to work around here. + // Though some older drivers may not like this, newer drivers shouldn't have this problem. + ls[y*lightResX+x] = spec; + } + } + + U32 pix_format = GL_R16F; #if LL_DARWIN - // Need to work around limited precision with 10.6.8 and older drivers - // - pix_format = GL_R32F; + // Need to work around limited precision with 10.6.8 and older drivers + // + pix_format = GL_R32F; #endif - LLImageGL::generateTextures(1, &mLightFunc); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - delete [] ls; - } + LLImageGL::generateTextures(1, &mLightFunc); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + delete [] ls; + } mPbrBrdfLut.allocate(512, 512, GL_RG16F); mPbrBrdfLut.bindTarget(); @@ -1336,23 +1336,23 @@ void LLPipeline::createLUTBuffers() void LLPipeline::restoreGL() { - assertInitialized(); + assertInitialized(); - LLViewerShaderMgr::instance()->setShaders(); + LLViewerShaderMgr::instance()->setShaders(); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->restoreGL(); - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->restoreGL(); + } + } + } } bool LLPipeline::shadersLoaded() @@ -1367,338 +1367,338 @@ bool LLPipeline::canUseWindLightShaders() const bool LLPipeline::canUseAntiAliasing() const { - return true; + return true; } void LLPipeline::unloadShaders() { - LLViewerShaderMgr::instance()->unloadShaders(); - mShadersLoaded = false; + LLViewerShaderMgr::instance()->unloadShaders(); + mShadersLoaded = false; } void LLPipeline::assertInitializedDoError() { - LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL; + LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL; } //============================================================================ void LLPipeline::enableShadows(const bool enable_shadows) { - //should probably do something here to wrangle shadows.... + //should probably do something here to wrangle shadows.... } class LLOctreeDirtyTexture : public OctreeTraveler { public: - const std::set& mTextures; - - LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } - - virtual void visit(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) - { - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) - { - LLDrawInfo* params = *j; - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); - if (tex && mTextures.find(tex) != mTextures.end()) - { - group->setState(LLSpatialGroup::GEOM_DIRTY); - } - } - } - } - - for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) - { - LLSpatialBridge* bridge = *i; - traverse(bridge->mOctree); - } - } + const std::set& mTextures; + + LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } + + virtual void visit(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) + { + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + LLDrawInfo* params = *j; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); + if (tex && mTextures.find(tex) != mTextures.end()) + { + group->setState(LLSpatialGroup::GEOM_DIRTY); + } + } + } + } + + for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) + { + LLSpatialBridge* bridge = *i; + traverse(bridge->mOctree); + } + } }; // Called when a texture changes # of channels (causes faces to move to alpha pool) void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - - // *TODO: This is inefficient and causes frame spikes; need a better way to do this - // Most of the time is spent in dirty.traverse. - - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (poolp->isFacePool()) - { - ((LLFacePool*) poolp)->dirtyTextures(textures); - } - } - - LLOctreeDirtyTexture dirty(textures); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - dirty.traverse(part->mOctree); - } - } - } + assertInitialized(); + + // *TODO: This is inefficient and causes frame spikes; need a better way to do this + // Most of the time is spent in dirty.traverse. + + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (poolp->isFacePool()) + { + ((LLFacePool*) poolp)->dirtyTextures(textures); + } + } + + LLOctreeDirtyTexture dirty(textures); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + dirty.traverse(part->mOctree); + } + } + } } LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) { - assertInitialized(); - - LLDrawPool *poolp = NULL; - switch( type ) - { - case LLDrawPool::POOL_SIMPLE: - poolp = mSimplePool; - break; - - case LLDrawPool::POOL_GRASS: - poolp = mGrassPool; - break; - - case LLDrawPool::POOL_ALPHA_MASK: - poolp = mAlphaMaskPool; - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - poolp = mFullbrightAlphaMaskPool; - break; - - case LLDrawPool::POOL_FULLBRIGHT: - poolp = mFullbrightPool; - break; - - case LLDrawPool::POOL_GLOW: - poolp = mGlowPool; - break; - - case LLDrawPool::POOL_TREE: - poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); - break; - - case LLDrawPool::POOL_TERRAIN: - poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); - break; - - case LLDrawPool::POOL_BUMP: - poolp = mBumpPool; - break; - case LLDrawPool::POOL_MATERIALS: - poolp = mMaterialsPool; - break; - case LLDrawPool::POOL_ALPHA_PRE_WATER: - poolp = mAlphaPoolPreWater; - break; + assertInitialized(); + + LLDrawPool *poolp = NULL; + switch( type ) + { + case LLDrawPool::POOL_SIMPLE: + poolp = mSimplePool; + break; + + case LLDrawPool::POOL_GRASS: + poolp = mGrassPool; + break; + + case LLDrawPool::POOL_ALPHA_MASK: + poolp = mAlphaMaskPool; + break; + + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + poolp = mFullbrightAlphaMaskPool; + break; + + case LLDrawPool::POOL_FULLBRIGHT: + poolp = mFullbrightPool; + break; + + case LLDrawPool::POOL_GLOW: + poolp = mGlowPool; + break; + + case LLDrawPool::POOL_TREE: + poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); + break; + + case LLDrawPool::POOL_TERRAIN: + poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); + break; + + case LLDrawPool::POOL_BUMP: + poolp = mBumpPool; + break; + case LLDrawPool::POOL_MATERIALS: + poolp = mMaterialsPool; + break; + case LLDrawPool::POOL_ALPHA_PRE_WATER: + poolp = mAlphaPoolPreWater; + break; case LLDrawPool::POOL_ALPHA_POST_WATER: poolp = mAlphaPoolPostWater; break; - case LLDrawPool::POOL_AVATAR: - case LLDrawPool::POOL_CONTROL_AV: - break; // Do nothing + case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: + break; // Do nothing - case LLDrawPool::POOL_SKY: - poolp = mSkyPool; - break; + case LLDrawPool::POOL_SKY: + poolp = mSkyPool; + break; - case LLDrawPool::POOL_WATER: - poolp = mWaterPool; - break; + case LLDrawPool::POOL_WATER: + poolp = mWaterPool; + break; - case LLDrawPool::POOL_WL_SKY: - poolp = mWLSkyPool; - break; + case LLDrawPool::POOL_WL_SKY: + poolp = mWLSkyPool; + break; - case LLDrawPool::POOL_GLTF_PBR: - poolp = mPBROpaquePool; - break; + case LLDrawPool::POOL_GLTF_PBR: + poolp = mPBROpaquePool; + break; case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: poolp = mPBRAlphaMaskPool; break; - default: - llassert(0); - LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; - break; - } + default: + llassert(0); + LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; + break; + } - return poolp; + return poolp; } -LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) +LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) { - LLDrawPool *poolp = findPool(type, tex0); - if (poolp) - { - return poolp; - } + LLDrawPool *poolp = findPool(type, tex0); + if (poolp) + { + return poolp; + } - LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0); - addPool( new_poolp ); + LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0); + addPool( new_poolp ); - return new_poolp; + return new_poolp; } // static LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - U32 type = getPoolTypeFromTE(te, imagep); - return gPipeline.getPool(type, imagep); + U32 type = getPoolTypeFromTE(te, imagep); + return gPipeline.getPool(type, imagep); } -//static +//static U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - if (!te || !imagep) - { - return 0; - } - - LLMaterial* mat = te->getMaterialParams().get(); + if (!te || !imagep) + { + return 0; + } + + LLMaterial* mat = te->getMaterialParams().get(); LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); - bool color_alpha = te->getColor().mV[3] < 0.999f; - bool alpha = color_alpha; - if (imagep) - { - alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); - } - - if (alpha && mat) - { - switch (mat->getDiffuseAlphaMode()) - { - case 1: - alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. - break; - case 0: //alpha mode set to none, never go to alpha pool - case 3: //alpha mode set to emissive, never go to alpha pool - alpha = color_alpha; - break; - default: //alpha mode set to "mask", go to alpha pool if fullbright - alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. - break; - } - } - - if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)) - { - return LLDrawPool::POOL_ALPHA; - } - else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull())) - { - return LLDrawPool::POOL_BUMP; - } + bool color_alpha = te->getColor().mV[3] < 0.999f; + bool alpha = color_alpha; + if (imagep) + { + alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); + } + + if (alpha && mat) + { + switch (mat->getDiffuseAlphaMode()) + { + case 1: + alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. + break; + case 0: //alpha mode set to none, never go to alpha pool + case 3: //alpha mode set to emissive, never go to alpha pool + alpha = color_alpha; + break; + default: //alpha mode set to "mask", go to alpha pool if fullbright + alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. + break; + } + } + + if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)) + { + return LLDrawPool::POOL_ALPHA; + } + else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull())) + { + return LLDrawPool::POOL_BUMP; + } else if (gltf_mat) { return LLDrawPool::POOL_GLTF_PBR; } - else if (mat && !alpha) - { - return LLDrawPool::POOL_MATERIALS; - } - else - { - return LLDrawPool::POOL_SIMPLE; - } + else if (mat && !alpha) + { + return LLDrawPool::POOL_MATERIALS; + } + else + { + return LLDrawPool::POOL_SIMPLE; + } } void LLPipeline::addPool(LLDrawPool *new_poolp) { - assertInitialized(); - mPools.insert(new_poolp); - addToQuickLookup( new_poolp ); + assertInitialized(); + mPools.insert(new_poolp); + addToQuickLookup( new_poolp ); } void LLPipeline::allocDrawable(LLViewerObject *vobj) { - LLDrawable *drawable = new LLDrawable(vobj); - vobj->mDrawable = drawable; - - //encompass completely sheared objects by taking - //the most extreme point possible (<1,1,0.5>) - drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); - if (vobj->isOrphaned()) - { - drawable->setState(LLDrawable::FORCE_INVISIBLE); - } - drawable->updateXform(TRUE); -} + LLDrawable *drawable = new LLDrawable(vobj); + vobj->mDrawable = drawable; + + //encompass completely sheared objects by taking + //the most extreme point possible (<1,1,0.5>) + drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); + if (vobj->isOrphaned()) + { + drawable->setState(LLDrawable::FORCE_INVISIBLE); + } + drawable->updateXform(TRUE); +} void LLPipeline::unlinkDrawable(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - - LLPointer drawablep = drawable; // make sure this doesn't get deleted before we are done - - // Based on flags, remove the drawable from the queues that it's on. - if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); - if (iter != mMovedList.end()) - { - mMovedList.erase(iter); - } - } - - if (drawablep->getSpatialGroup()) - { - if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) - { + assertInitialized(); + + LLPointer drawablep = drawable; // make sure this doesn't get deleted before we are done + + // Based on flags, remove the drawable from the queues that it's on. + if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); + if (iter != mMovedList.end()) + { + mMovedList.erase(iter); + } + } + + if (drawablep->getSpatialGroup()) + { + if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) + { #ifdef LL_RELEASE_FOR_DOWNLOAD - LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL; + LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL; #else - LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL; + LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL; #endif - } - } - - mLights.erase(drawablep); - - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - if (iter->drawable == drawablep) - { - mNearbyLights.erase(iter); - break; - } - } - - for (U32 i = 0; i < 2; ++i) - { - if (mShadowSpotLight[i] == drawablep) - { - mShadowSpotLight[i] = NULL; - } - - if (mTargetShadowSpotLight[i] == drawablep) - { - mTargetShadowSpotLight[i] = NULL; - } - } + } + } + + mLights.erase(drawablep); + + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + if (iter->drawable == drawablep) + { + mNearbyLights.erase(iter); + break; + } + } + + for (U32 i = 0; i < 2; ++i) + { + if (mShadowSpotLight[i] == drawablep) + { + mShadowSpotLight[i] = NULL; + } + + if (mTargetShadowSpotLight[i] == drawablep) + { + mTargetShadowSpotLight[i] = NULL; + } + } } //static @@ -1726,239 +1726,239 @@ void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) U32 LLPipeline::addObject(LLViewerObject *vobj) { - if (RenderDelayCreation) - { - mCreateQ.push_back(vobj); - } - else - { - createObject(vobj); - } + if (RenderDelayCreation) + { + mCreateQ.push_back(vobj); + } + else + { + createObject(vobj); + } - return 1; + return 1; } void LLPipeline::createObjects(F32 max_dtime) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - LLTimer update_timer; + LLTimer update_timer; + + while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime) + { + LLViewerObject* vobj = mCreateQ.front(); + if (!vobj->isDead()) + { + createObject(vobj); + } + mCreateQ.pop_front(); + } - while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime) - { - LLViewerObject* vobj = mCreateQ.front(); - if (!vobj->isDead()) - { - createObject(vobj); - } - mCreateQ.pop_front(); - } - - //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter) - //{ - // createObject(*iter); - //} + //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter) + //{ + // createObject(*iter); + //} - //mCreateQ.clear(); + //mCreateQ.clear(); } void LLPipeline::createObject(LLViewerObject* vobj) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - LLDrawable* drawablep = vobj->mDrawable; - - if (!drawablep) - { - drawablep = vobj->createDrawable(this); - } - else - { - LL_ERRS() << "Redundant drawable creation!" << LL_ENDL; - } - - llassert(drawablep); - - if (vobj->getParent()) - { - vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 - } - else - { - vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 - } - - markRebuild(drawablep, LLDrawable::REBUILD_ALL); - - if (drawablep->getVOVolume() && RenderAnimateRes) - { - // fun animated res - drawablep->updateXform(TRUE); - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); - drawablep->setScale(LLVector3(0,0,0)); - drawablep->makeActive(); - } + LLDrawable* drawablep = vobj->mDrawable; + + if (!drawablep) + { + drawablep = vobj->createDrawable(this); + } + else + { + LL_ERRS() << "Redundant drawable creation!" << LL_ENDL; + } + + llassert(drawablep); + + if (vobj->getParent()) + { + vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 + } + else + { + vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 + } + + markRebuild(drawablep, LLDrawable::REBUILD_ALL); + + if (drawablep->getVOVolume() && RenderAnimateRes) + { + // fun animated res + drawablep->updateXform(TRUE); + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); + drawablep->setScale(LLVector3(0,0,0)); + drawablep->makeActive(); + } } void LLPipeline::resetFrameStats() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); + assertInitialized(); - sCompiles = 0; - mNumVisibleFaces = 0; + sCompiles = 0; + mNumVisibleFaces = 0; - if (mOldRenderDebugMask != mRenderDebugMask) - { - gObjectList.clearDebugText(); - mOldRenderDebugMask = mRenderDebugMask; - } + if (mOldRenderDebugMask != mRenderDebugMask) + { + gObjectList.clearDebugText(); + mOldRenderDebugMask = mRenderDebugMask; + } } //external functions for asynchronous updating void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) { LL_PROFILE_ZONE_SCOPED; - if (FreezeTime) - { - return; - } - if (!drawablep) - { - LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; - return; - } - if (drawablep->isState(LLDrawable::EARLY_MOVE)) - { - return; - } - - assertInitialized(); - - // update drawable now - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED - drawablep->updateMove(); // returns done - drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame - // Put on move list so that EARLY_MOVE gets cleared - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - mMovedList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } + if (FreezeTime) + { + return; + } + if (!drawablep) + { + LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; + return; + } + if (drawablep->isState(LLDrawable::EARLY_MOVE)) + { + return; + } + + assertInitialized(); + + // update drawable now + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED + drawablep->updateMove(); // returns done + drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame + // Put on move list so that EARLY_MOVE gets cleared + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + mMovedList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } } void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) { LL_PROFILE_ZONE_SCOPED; - if (FreezeTime) - { - return; - } - if (!drawablep) - { - LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; - return; - } - if (drawablep->isState(LLDrawable::EARLY_MOVE)) - { - return; - } - - assertInitialized(); - - // update drawable now - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED - drawablep->updateMove(); - drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame - // Put on move list so that EARLY_MOVE gets cleared - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - mMovedList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } + if (FreezeTime) + { + return; + } + if (!drawablep) + { + LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; + return; + } + if (drawablep->isState(LLDrawable::EARLY_MOVE)) + { + return; + } + + assertInitialized(); + + // update drawable now + drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED + drawablep->updateMove(); + drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame + // Put on move list so that EARLY_MOVE gets cleared + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + mMovedList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } } void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) { LL_PROFILE_ZONE_SCOPED; - for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); - iter != moved_list.end(); ) - { - LLDrawable::drawable_vector_t::iterator curiter = iter++; - LLDrawable *drawablep = *curiter; - bool done = true; - if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) - { - done = drawablep->updateMove(); - } - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); - if (done) - { - if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE)) - { - drawablep->makeStatic(); - } - drawablep->clearState(LLDrawable::ON_MOVE_LIST); - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { //will likely not receive any future world matrix updates - // -- this keeps attachments from getting stuck in space and falling off your avatar - drawablep->clearState(LLDrawable::ANIMATED_CHILD); - markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); - if (drawablep->getVObj()) - { - drawablep->getVObj()->dirtySpatialGroup(); - } - } - iter = moved_list.erase(curiter); - } - } + for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); + iter != moved_list.end(); ) + { + LLDrawable::drawable_vector_t::iterator curiter = iter++; + LLDrawable *drawablep = *curiter; + bool done = true; + if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) + { + done = drawablep->updateMove(); + } + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); + if (done) + { + if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE)) + { + drawablep->makeStatic(); + } + drawablep->clearState(LLDrawable::ON_MOVE_LIST); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { //will likely not receive any future world matrix updates + // -- this keeps attachments from getting stuck in space and falling off your avatar + drawablep->clearState(LLDrawable::ANIMATED_CHILD); + markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); + if (drawablep->getVObj()) + { + drawablep->getVObj()->dirtySpatialGroup(); + } + } + iter = moved_list.erase(curiter); + } + } } void LLPipeline::updateMove() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - if (FreezeTime) - { - return; - } - - assertInitialized(); - - for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); - iter != mRetexturedList.end(); ++iter) - { - LLDrawable* drawablep = *iter; - if (drawablep && !drawablep->isDead()) - { - drawablep->updateTexture(); - } - } - mRetexturedList.clear(); - - updateMovedList(mMovedList); - - //balance octrees - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->mOctree->balance(); - } - } - - //balance the VO Cache tree - LLVOCachePartition* vo_part = region->getVOCachePartition(); - if(vo_part) - { - vo_part->mOctree->balance(); - } - } + if (FreezeTime) + { + return; + } + + assertInitialized(); + + for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); + iter != mRetexturedList.end(); ++iter) + { + LLDrawable* drawablep = *iter; + if (drawablep && !drawablep->isDead()) + { + drawablep->updateTexture(); + } + } + mRetexturedList.clear(); + + updateMovedList(mMovedList); + + //balance octrees + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->mOctree->balance(); + } + } + + //balance the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->mOctree->balance(); + } + } } ///////////////////////////////////////////////////////////////////////////// @@ -1969,299 +1969,299 @@ void LLPipeline::updateMove() F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera) { llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots - LLVector3 lookAt = center - camera.getOrigin(); - F32 dist = lookAt.length(); + LLVector3 lookAt = center - camera.getOrigin(); + F32 dist = lookAt.length(); - //ramp down distance for nearby objects - //shrink dist by dist/16. - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } - //get area of circle around node - F32 app_angle = atanf(size.length()/dist); - F32 radius = app_angle*LLDrawable::sCurPixelAngle; - return radius*radius * F_PI; + //get area of circle around node + F32 app_angle = atanf(size.length()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; } //static F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) { - LLVector4a origin; - origin.load3(camera.getOrigin().mV); + LLVector4a origin; + origin.load3(camera.getOrigin().mV); - LLVector4a lookAt; - lookAt.setSub(center, origin); - F32 dist = lookAt.getLength3().getF32(); + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.getLength3().getF32(); - //ramp down distance for nearby objects - //shrink dist by dist/16. - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } - //get area of circle around node - F32 app_angle = atanf(size.getLength3().getF32()/dist); - F32 radius = app_angle*LLDrawable::sCurPixelAngle; - return radius*radius * F_PI; + //get area of circle around node + F32 app_angle = atanf(size.getLength3().getF32()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; } void LLPipeline::grabReferences(LLCullResult& result) { - sCull = &result; + sCull = &result; } void LLPipeline::clearReferences() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - sCull = NULL; - mGroupSaveQ1.clear(); + sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - if (drawable == drawablep) - { - LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL; - } - } + if (drawable == drawablep) + { + LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL; + } + } } void check_references(LLDrawable* drawable, LLFace* face) { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - if (drawable->getFace(i) == face) - { - LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } } void check_references(LLSpatialGroup* group, LLFace* face) { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(drawable) - { - check_references(drawable, face); - } + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(drawable) + { + check_references(drawable, face); + } } } void LLPipeline::checkReferences(LLFace* face) { #if 0 - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) - { - LLDrawable* drawable = *iter; - check_references(drawable, face); - } - } + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } #endif } void LLPipeline::checkReferences(LLDrawable* drawable) { #if 0 - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) - { - if (drawable == *iter) - { - LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } #endif } void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) { - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; - for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) - { - LLDrawInfo* params = *j; - if (params == draw_info) - { - LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } } void LLPipeline::checkReferences(LLDrawInfo* draw_info) { #if 0 - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - } + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } #endif } void LLPipeline::checkReferences(LLSpatialGroup* group) { #if CHECK_PIPELINE_REFERENCES - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } #endif } bool LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - if (part->visibleObjectsInFrustum(camera)) - { - return true; - } - } - } - } - } - - return false; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + if (part->visibleObjectsInFrustum(camera)) + { + return true; + } + } + } + } + } + + return false; } bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) { - const F32 X = 65536.f; + const F32 X = 65536.f; - min = LLVector3(X,X,X); - max = LLVector3(-X,-X,-X); + min = LLVector3(X,X,X); + max = LLVector3(-X,-X,-X); - LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - bool res = true; + bool res = true; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - if (!part->getVisibleExtents(camera, min, max)) - { - res = false; - } - } - } - } - } + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + if (!part->getVisibleExtents(camera, min, max)) + { + res = false; + } + } + } + } + } - LLViewerCamera::sCurCameraID = saved_camera_id; - return res; + LLViewerCamera::sCurCameraID = saved_camera_id; + return res; } static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); @@ -2270,7 +2270,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); bool LLPipeline::isWaterClip() { // We always pretend that we're not clipping water when rendering mirrors. - return (gPipeline.mHeroProbeManager.isMirrorPass()) ? false : (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs; + return (gPipeline.mHeroProbeManager.isMirrorPass()) ? false : (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs; } void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) @@ -2278,11 +2278,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out - bool water_clip = isWaterClip(); + bool water_clip = isWaterClip(); if (water_clip) { - + LLVector3 pnorm; F32 water_height = LLEnvironment::instance().getWaterHeight(); @@ -2297,7 +2297,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) //camera is above water, cull below water pnorm = LLVector3(0, 0, -1); } - + LLPlane plane; plane.setVec(LLVector3(0, 0, water_height), pnorm); @@ -2308,48 +2308,48 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) camera.disableUserClipPlane(); } - grabReferences(result); - - sCull->clear(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - part->cull(camera); - } - } - } - - //scan the VO Cache tree - LLVOCachePartition* vo_part = region->getVOCachePartition(); - if(vo_part) - { - vo_part->cull(camera, sUseOcclusion > 0); - } - } - - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && - gSky.mVOSkyp.notNull() && - gSky.mVOSkyp->mDrawable.notNull()) - { - gSky.mVOSkyp->mDrawable->setVisible(camera); - sCull->pushDrawable(gSky.mVOSkyp->mDrawable); - gSky.updateCull(); - stop_glerror(); - } - - if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) && + grabReferences(result); + + sCull->clear(); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->cull(camera); + } + } + } + + //scan the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->cull(camera, sUseOcclusion > 0); + } + } + + if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && + gSky.mVOSkyp.notNull() && + gSky.mVOSkyp->mDrawable.notNull()) + { + gSky.mVOSkyp->mDrawable->setVisible(camera); + sCull->pushDrawable(gSky.mVOSkyp->mDrawable); + gSky.updateCull(); + stop_glerror(); + } + + if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) && gPipeline.canUseWindLightShaders() && - gSky.mVOWLSkyp.notNull() && + gSky.mVOWLSkyp.notNull() && gSky.mVOWLSkyp->mDrawable.notNull()) { gSky.mVOWLSkyp->mDrawable->setVisible(camera); @@ -2359,60 +2359,60 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) { - if (group->isEmpty()) - { - return; - } - - group->setVisible(); - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) - { - group->updateDistance(camera); - } - - assertInitialized(); - - if (!group->getSpatialPartition()->mRenderByGroup) - { //render by drawable - sCull->pushDrawableGroup(group); - } - else - { //render by group - sCull->pushVisibleGroup(group); - } - - if (group->needsUpdate() || - group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1) + if (group->isEmpty()) { - // include this group in occlusion groups, not because it is an occluder, but because we want to run - // an occlusion query to find out if it's an occluder + return; + } + + group->setVisible(); + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) + { + group->updateDistance(camera); + } + + assertInitialized(); + + if (!group->getSpatialPartition()->mRenderByGroup) + { //render by drawable + sCull->pushDrawableGroup(group); + } + else + { //render by group + sCull->pushVisibleGroup(group); + } + + if (group->needsUpdate() || + group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1) + { + // include this group in occlusion groups, not because it is an occluder, but because we want to run + // an occlusion query to find out if it's an occluder markOccluder(group); } - mNumVisibleNodes++; + mNumVisibleNodes++; } void LLPipeline::markOccluder(LLSpatialGroup* group) { - if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION)) - { - LLSpatialGroup* parent = group->getParent(); - - if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //only mark top most occluders as active occlusion - sCull->pushOcclusionGroup(group); - group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); - - if (parent && - !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) && - parent->getElementCount() == 0 && - parent->needsUpdate()) - { - sCull->pushOcclusionGroup(group); - parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); - } - } - } + if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION)) + { + LLSpatialGroup* parent = group->getParent(); + + if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { //only mark top most occluders as active occlusion + sCull->pushOcclusionGroup(group); + group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); + + if (parent && + !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) && + parent->getElementCount() == 0 && + parent->needsUpdate()) + { + sCull->pushOcclusionGroup(group); + parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); + } + } + } } void LLPipeline::doOcclusion(LLCamera& camera) @@ -2440,7 +2440,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) gGL.setColorMask(true, true); } - + if (sReflectionProbesEnabled && sUseOcclusion > 1 && !LLPipeline::sShadowRender && !gCubeSnapshot) { gGL.setColorMask(false, false); @@ -2462,138 +2462,138 @@ void LLPipeline::doOcclusion(LLCamera& camera) } if (LLPipeline::sUseOcclusion > 1 && - (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) - { - LLVertexBuffer::unbind(); + (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) + { + LLVertexBuffer::unbind(); - gGL.setColorMask(false, false); + gGL.setColorMask(false, false); - LLGLDisable blend(GL_BLEND); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLGLDisable blend(GL_BLEND); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); + LLGLDisable cull(GL_CULL_FACE); gOcclusionCubeProgram.bind(); - if (mCubeVB.isNull()) - { //cube VB will be used for issuing occlusion queries - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); - } - mCubeVB->setBuffer(); + if (mCubeVB.isNull()) + { //cube VB will be used for issuing occlusion queries + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); + } + mCubeVB->setBuffer(); - for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) - { - LLSpatialGroup* group = *iter; + for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) + { + LLSpatialGroup* group = *iter; if (!group->isDead()) { group->doOcclusion(&camera); group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } - } - - //apply occlusion culling to object cache tree - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLVOCachePartition* vo_part = (*iter)->getVOCachePartition(); - if(vo_part) - { - vo_part->processOccluders(&camera); - } - } - - gGL.setColorMask(true, true); - } -} - + } + + //apply occlusion culling to object cache tree + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLVOCachePartition* vo_part = (*iter)->getVOCachePartition(); + if(vo_part) + { + vo_part->processOccluders(&camera); + } + } + + gGL.setColorMask(true, true); + } +} + bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep) { - bool update_complete = drawablep->updateGeometry(); - if (update_complete && assertInitialized()) - { - drawablep->setState(LLDrawable::BUILT); - } - return update_complete; + bool update_complete = drawablep->updateGeometry(); + if (update_complete && assertInitialized()) + { + drawablep->setState(LLDrawable::BUILT); + } + return update_complete; } void LLPipeline::updateGL() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - { - while (!LLGLUpdate::sGLQ.empty()) - { - LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); - glu->updateGL(); - glu->mInQ = FALSE; - LLGLUpdate::sGLQ.pop_front(); - } - } + { + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } + } } void LLPipeline::clearRebuildGroups() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - LLSpatialGroup::sg_vector_t hudGroups; - - mGroupQ1Locked = true; - // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); - iter != mGroupQ1.end(); ++iter) - { - LLSpatialGroup* group = *iter; - - // If the group contains HUD objects, save the group - if (group->isHUDGroup()) - { - hudGroups.push_back(group); - } - // Else, no HUD objects so clear the build state - else - { - group->clearState(LLSpatialGroup::IN_BUILD_Q1); - } - } - - // Clear the group - mGroupQ1.clear(); - - // Copy the saved HUD groups back in - mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); - mGroupQ1Locked = false; + LLSpatialGroup::sg_vector_t hudGroups; + + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + } + + // Clear the group + mGroupQ1.clear(); + + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ1Locked = false; } void LLPipeline::clearRebuildDrawables() { - // Clear all drawables on the priority build queue, - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); - iter != mBuildQ1.end(); ++iter) - { - LLDrawable* drawablep = *iter; - if (drawablep && !drawablep->isDead()) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q); - } - } - mBuildQ1.clear(); - - //clear all moving bridges - for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin(); - iter != mMovedBridge.end(); ++iter) - { - LLDrawable *drawablep = *iter; - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); - } - mMovedBridge.clear(); - - //clear all moving drawables - for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin(); - iter != mMovedList.end(); ++iter) - { - LLDrawable *drawablep = *iter; - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); - } - mMovedList.clear(); + // Clear all drawables on the priority build queue, + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); + iter != mBuildQ1.end(); ++iter) + { + LLDrawable* drawablep = *iter; + if (drawablep && !drawablep->isDead()) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q); + } + } + mBuildQ1.clear(); + + //clear all moving bridges + for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin(); + iter != mMovedBridge.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); + } + mMovedBridge.clear(); + + //clear all moving drawables + for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin(); + iter != mMovedList.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); + } + mMovedList.clear(); for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); ++iter) @@ -2609,305 +2609,305 @@ void LLPipeline::rebuildPriorityGroups() LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LL_PROFILE_GPU_ZONE("rebuildPriorityGroups"); - LLTimer update_timer; - assertInitialized(); + LLTimer update_timer; + assertInitialized(); - gMeshRepo.notifyLoadedMeshes(); + gMeshRepo.notifyLoadedMeshes(); - mGroupQ1Locked = true; - // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); - iter != mGroupQ1.end(); ++iter) - { - LLSpatialGroup* group = *iter; - group->rebuildGeom(); - group->clearState(LLSpatialGroup::IN_BUILD_Q1); - } + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->rebuildGeom(); + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } - mGroupSaveQ1 = mGroupQ1; - mGroupQ1.clear(); - mGroupQ1Locked = false; + mGroupSaveQ1 = mGroupQ1; + mGroupQ1.clear(); + mGroupQ1Locked = false; } void LLPipeline::updateGeom(F32 max_dtime) { - LLTimer update_timer; - LLPointer drawablep; + LLTimer update_timer; + LLPointer drawablep; - LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); + LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); if (gCubeSnapshot) { return; } - assertInitialized(); - - // notify various object types to reset internal cost metrics, etc. - // for now, only LLVOVolume does this to throttle LOD changes - LLVOVolume::preUpdateGeom(); - - // Iterate through all drawables on the priority build queue, - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); - iter != mBuildQ1.end();) - { - LLDrawable::drawable_list_t::iterator curiter = iter++; - LLDrawable* drawablep = *curiter; - if (drawablep && !drawablep->isDead()) - { - if (drawablep->isUnload()) - { - drawablep->unload(); - drawablep->clearState(LLDrawable::FOR_UNLOAD); - } - - if (updateDrawableGeom(drawablep)) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q); - mBuildQ1.erase(curiter); - } - } - else - { - mBuildQ1.erase(curiter); - } - } - - updateMovedList(mMovedBridge); + assertInitialized(); + + // notify various object types to reset internal cost metrics, etc. + // for now, only LLVOVolume does this to throttle LOD changes + LLVOVolume::preUpdateGeom(); + + // Iterate through all drawables on the priority build queue, + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); + iter != mBuildQ1.end();) + { + LLDrawable::drawable_list_t::iterator curiter = iter++; + LLDrawable* drawablep = *curiter; + if (drawablep && !drawablep->isDead()) + { + if (drawablep->isUnload()) + { + drawablep->unload(); + drawablep->clearState(LLDrawable::FOR_UNLOAD); + } + + if (updateDrawableGeom(drawablep)) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q); + mBuildQ1.erase(curiter); + } + } + else + { + mBuildQ1.erase(curiter); + } + } + + updateMovedList(mMovedBridge); } void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) { - if(drawablep && !drawablep->isDead()) - { - if (drawablep->isSpatialBridge()) - { - const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; - llassert(root); // trying to catch a bad assumption - - if (root && // // this test may not be needed, see above - root->getVObj()->isAttachment()) - { - LLDrawable* rootparent = root->getParent(); - if (rootparent) // this IS sometimes NULL - { - LLViewerObject *vobj = rootparent->getVObj(); - llassert(vobj); // trying to catch a bad assumption - if (vobj) // this test may not be needed, see above - { - LLVOAvatar* av = vobj->asAvatar(); - if (av && - ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass - || av->isInMuteList() - || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) )) - { - return; - } - } - } - } - sCull->pushBridge((LLSpatialBridge*) drawablep); - } - else - { - - sCull->pushDrawable(drawablep); - } - - drawablep->setVisible(camera); - } + if(drawablep && !drawablep->isDead()) + { + if (drawablep->isSpatialBridge()) + { + const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; + llassert(root); // trying to catch a bad assumption + + if (root && // // this test may not be needed, see above + root->getVObj()->isAttachment()) + { + LLDrawable* rootparent = root->getParent(); + if (rootparent) // this IS sometimes NULL + { + LLViewerObject *vobj = rootparent->getVObj(); + llassert(vobj); // trying to catch a bad assumption + if (vobj) // this test may not be needed, see above + { + LLVOAvatar* av = vobj->asAvatar(); + if (av && + ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass + || av->isInMuteList() + || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) )) + { + return; + } + } + } + } + sCull->pushBridge((LLSpatialBridge*) drawablep); + } + else + { + + sCull->pushDrawable(drawablep); + } + + drawablep->setVisible(camera); + } } void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion) { - if (!drawablep) - { - //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL; - return; - } - - if (drawablep->isDead()) - { - LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL; - return; - } - - if (drawablep->getParent()) - { - //ensure that parent drawables are moved first - markMoved(drawablep->getParent(), damped_motion); - } - - assertInitialized(); - - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - if (drawablep->isSpatialBridge()) - { - mMovedBridge.push_back(drawablep); - } - else - { - mMovedList.push_back(drawablep); - } - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } - if (! damped_motion) - { - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED - } - else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) - { - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); - } + if (!drawablep) + { + //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL; + return; + } + + if (drawablep->isDead()) + { + LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL; + return; + } + + if (drawablep->getParent()) + { + //ensure that parent drawables are moved first + markMoved(drawablep->getParent(), damped_motion); + } + + assertInitialized(); + + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + if (drawablep->isSpatialBridge()) + { + mMovedBridge.push_back(drawablep); + } + else + { + mMovedList.push_back(drawablep); + } + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } + if (! damped_motion) + { + drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED + } + else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) + { + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); + } } void LLPipeline::markShift(LLDrawable *drawablep) { - if (!drawablep || drawablep->isDead()) - { - return; - } + if (!drawablep || drawablep->isDead()) + { + return; + } - assertInitialized(); + assertInitialized(); - if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) - { - drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); - if (drawablep->getParent()) - { - markShift(drawablep->getParent()); - } - mShiftList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_SHIFT_LIST); - } + if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) + { + drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); + if (drawablep->getParent()) + { + markShift(drawablep->getParent()); + } + mShiftList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_SHIFT_LIST); + } } void LLPipeline::shiftObjects(const LLVector3 &offset) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - - glClear(GL_DEPTH_BUFFER_BIT); - gDepthDirty = true; - - LLVector4a offseta; - offseta.load3(offset.mV); - - for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); - iter != mShiftList.end(); iter++) - { - LLDrawable *drawablep = *iter; - if (drawablep->isDead()) - { - continue; - } - drawablep->shiftPos(offseta); - drawablep->clearState(LLDrawable::ON_SHIFT_LIST); - } - mShiftList.resize(0); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->shift(offseta); - } - } - } + assertInitialized(); + + glClear(GL_DEPTH_BUFFER_BIT); + gDepthDirty = true; + + LLVector4a offseta; + offseta.load3(offset.mV); + + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); iter++) + { + LLDrawable *drawablep = *iter; + if (drawablep->isDead()) + { + continue; + } + drawablep->shiftPos(offseta); + drawablep->clearState(LLDrawable::ON_SHIFT_LIST); + } + mShiftList.resize(0); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->shift(offseta); + } + } + } mReflectionMapManager.shift(offseta); - LLHUDText::shiftAll(offset); - LLHUDNameTag::shiftAll(offset); + LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); - display_update_camera(); + display_update_camera(); } void LLPipeline::markTextured(LLDrawable *drawablep) { - if (drawablep && !drawablep->isDead() && assertInitialized()) - { - mRetexturedList.insert(drawablep); - } + if (drawablep && !drawablep->isDead() && assertInitialized()) + { + mRetexturedList.insert(drawablep); + } } void LLPipeline::markGLRebuild(LLGLUpdate* glu) { - if (glu && !glu->mInQ) - { - LLGLUpdate::sGLQ.push_back(glu); - glu->mInQ = TRUE; - } + if (glu && !glu->mInQ) + { + LLGLUpdate::sGLQ.push_back(glu); + glu->mInQ = TRUE; + } } void LLPipeline::markPartitionMove(LLDrawable* drawable) { - if (!drawable->isState(LLDrawable::PARTITION_MOVE) && - !drawable->getPositionGroup().equals3(LLVector4a::getZero())) - { - drawable->setState(LLDrawable::PARTITION_MOVE); - mPartitionQ.push_back(drawable); - } + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().equals3(LLVector4a::getZero())) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } } void LLPipeline::processPartitionQ() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) - { - LLDrawable* drawable = *iter; - if (!drawable->isDead()) - { - drawable->updateBinRadius(); - drawable->movePartition(); - } - drawable->clearState(LLDrawable::PARTITION_MOVE); - } + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } - mPartitionQ.clear(); + mPartitionQ.clear(); } void LLPipeline::markMeshDirty(LLSpatialGroup* group) { - mMeshDirtyGroup.push_back(group); + mMeshDirtyGroup.push_back(group); } void LLPipeline::markRebuild(LLSpatialGroup* group) { - if (group && !group->isDead() && group->getSpatialPartition()) - { - if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) - { - llassert_always(!mGroupQ1Locked); + if (group && !group->isDead() && group->getSpatialPartition()) + { + if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) + { + llassert_always(!mGroupQ1Locked); - mGroupQ1.push_back(group); - group->setState(LLSpatialGroup::IN_BUILD_Q1); - } - } + mGroupQ1.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q1); + } + } } void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag) { - if (drawablep && !drawablep->isDead() && assertInitialized()) - { - if (!drawablep->isState(LLDrawable::IN_REBUILD_Q)) - { - mBuildQ1.push_back(drawablep); - drawablep->setState(LLDrawable::IN_REBUILD_Q); // mark drawable as being in priority queue - } + if (drawablep && !drawablep->isDead() && assertInitialized()) + { + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q)) + { + mBuildQ1.push_back(drawablep); + drawablep->setState(LLDrawable::IN_REBUILD_Q); // mark drawable as being in priority queue + } if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) - { - drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); - } - drawablep->setState(flag); - } + { + drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); + } + drawablep->setState(flag); + } } void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) @@ -2915,300 +2915,300 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LL_PROFILE_GPU_ZONE("stateSort"); - if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_CONTROL_AV, - LLPipeline::RENDER_TYPE_TERRAIN, - LLPipeline::RENDER_TYPE_TREE, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_WATER, - LLPipeline::END_RENDER_TYPES)) - { - //clear faces from face pools - gPipeline.resetDrawOrders(); - } - - //LLVertexBuffer::unbind(); - - grabReferences(result); - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; + if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::END_RENDER_TYPES)) + { + //clear faces from face pools + gPipeline.resetDrawOrders(); + } + + //LLVertexBuffer::unbind(); + + grabReferences(result); + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; if (group->isDead()) { continue; } - group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - markOccluder(group); - } - else - { - group->setVisible(); - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - markVisible(drawablep, camera); - } - - { //rebuild mesh as soon as we know it's visible - group->rebuildMesh(); - } - } - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) - { - LLSpatialGroup* last_group = NULL; - BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); - for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLCullResult::bridge_iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - - if (last_group == NULL) - { - last_group = group; - } - - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera, fov_changed); - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - last_group != group && last_group->changeLOD()) - { - last_group->mLastUpdateDistance = last_group->mDistance; - } - - last_group = group; - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - last_group && last_group->changeLOD()) - { - last_group->mLastUpdateDistance = last_group->mDistance; - } - } - - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; + markVisible(drawablep, camera); + } + + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); + } + } + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) + { + LLSpatialGroup* last_group = NULL; + BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + + if (last_group == NULL) + { + last_group = group; + } + + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera, fov_changed); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group != group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + + last_group = group; + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + } + + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; if (group->isDead()) { continue; } - group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - markOccluder(group); - } - else - { - group->setVisible(); - stateSort(group, camera); - - { //rebuild mesh as soon as we know it's visible - group->rebuildMesh(); - } - } - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE("stateSort"); // LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); - iter != sCull->endVisibleList(); ++iter) - { - LLDrawable *drawablep = *iter; - if (!drawablep->isDead()) - { - stateSort(drawablep, camera); - } - } - } - - postSort(camera); + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + stateSort(group, camera); + + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); + } + } + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE("stateSort"); // LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); + iter != sCull->endVisibleList(); ++iter) + { + LLDrawable *drawablep = *iter; + if (!drawablep->isDead()) + { + stateSort(drawablep, camera); + } + } + } + + postSort(camera); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { - if (group->changeLOD()) - { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - stateSort(drawablep, camera); - } + if (group->changeLOD()) + { + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); + stateSort(drawablep, camera); + } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) - { //avoid redundant stateSort calls - group->mLastUpdateDistance = group->mDistance; - } - } + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } + } } void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (bridge->getSpatialGroup()->changeLOD() || fov_changed) - { - bool force_update = false; - bridge->updateDistance(camera, force_update); - } + { + bool force_update = false; + bridge->updateDistance(camera, force_update); + } } void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (!drawablep - || drawablep->isDead() - || !hasRenderType(drawablep->getRenderType())) - { - return; - } - + || drawablep->isDead() + || !hasRenderType(drawablep->getRenderType())) + { + return; + } + // SL-11353 // ignore our own geo when rendering spotlight shadowmaps... - // + // if (RenderSpotLight && drawablep == RenderSpotLight) { return; } - if (LLSelectMgr::getInstance()->mHideSelectedObjects) - { - if (drawablep->getVObj().notNull() && - drawablep->getVObj()->isSelected()) - { - return; - } - } - - if (drawablep->isAvatar()) - { //don't draw avatars beyond render distance or if we don't have a spatial group. - if ((drawablep->getSpatialGroup() == NULL) || - (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) - { - return; - } - - LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get(); - if (!avatarp->isVisible()) - { - return; - } - } - - assertInitialized(); - - if (hasRenderType(drawablep->mRenderType)) - { - if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) - { - drawablep->setVisible(camera, NULL, FALSE); - } - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) - { - //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here - { - if (!drawablep->isActive()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); - } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } - } - } - - if (!drawablep->getVOVolume()) - { - for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); - iter != drawablep->mFaces.end(); iter++) - { - LLFace* facep = *iter; - - if (facep->hasGeometry()) - { - if (facep->getPool()) - { - facep->getPool()->enqueue(facep); - } - else - { - break; - } - } - } - } - - mNumVisibleFaces += drawablep->getNumFaces(); -} - - -void forAllDrawables(LLCullResult::sg_iterator begin, - LLCullResult::sg_iterator end, - void (*func)(LLDrawable*)) -{ - for (LLCullResult::sg_iterator i = begin; i != end; ++i) - { - LLSpatialGroup* group = *i; - if (group->isDead()) + if (LLSelectMgr::getInstance()->mHideSelectedObjects) + { + if (drawablep->getVObj().notNull() && + drawablep->getVObj()->isSelected()) + { + return; + } + } + + if (drawablep->isAvatar()) + { //don't draw avatars beyond render distance or if we don't have a spatial group. + if ((drawablep->getSpatialGroup() == NULL) || + (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) + { + return; + } + + LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get(); + if (!avatarp->isVisible()) + { + return; + } + } + + assertInitialized(); + + if (hasRenderType(drawablep->mRenderType)) + { + if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) + { + drawablep->setVisible(camera, NULL, FALSE); + } + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) + { + //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here + { + if (!drawablep->isActive()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); + } + else if (drawablep->isAvatar()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + } + } + } + + if (!drawablep->getVOVolume()) + { + for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); + iter != drawablep->mFaces.end(); iter++) + { + LLFace* facep = *iter; + + if (facep->hasGeometry()) + { + if (facep->getPool()) + { + facep->getPool()->enqueue(facep); + } + else + { + break; + } + } + } + } + + mNumVisibleFaces += drawablep->getNumFaces(); +} + + +void forAllDrawables(LLCullResult::sg_iterator begin, + LLCullResult::sg_iterator end, + void (*func)(LLDrawable*)) +{ + for (LLCullResult::sg_iterator i = begin; i != end; ++i) + { + LLSpatialGroup* group = *i; + if (group->isDead()) { continue; } - for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j) - { - if((*j)->hasDrawable()) - { - func((LLDrawable*)(*j)->getDrawable()); - } - } - } + for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j) + { + if((*j)->hasDrawable()) + { + func((LLDrawable*)(*j)->getDrawable()); + } + } + } } void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) { - forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); - forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); + forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); + forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); } //function for creating scripted beacons void renderScriptedBeacons(LLDrawable* drawablep) { - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj - && !vobj->isAvatar() - && !vobj->getParent() - && vobj->flagScripted()) - { - if (gPipeline.sRenderBeacons) - { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } - } + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj + && !vobj->isAvatar() + && !vobj->getParent() + && vobj->flagScripted()) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } + } } void renderScriptedTouchBeacons(LLDrawable *drawablep) @@ -3611,169 +3611,169 @@ void LLPipeline::postSort(LLCamera &camera) void render_hud_elements() { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); - gPipeline.disableLights(); - - LLGLSUIDefault gls_ui; - - //LLGLEnable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); - //glStencilMask(0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - gUIProgram.bind(); + gPipeline.disableLights(); + + LLGLSUIDefault gls_ui; + + //LLGLEnable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); + //glStencilMask(0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + gUIProgram.bind(); gGL.color4f(1, 1, 1, 1); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - - if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() - - // Draw the tracking overlays - LLTracker::render3D(); - + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() + + // Draw the tracking overlays + LLTracker::render3D(); + if (LLWorld::instanceExists()) { // Show the property lines LLWorld::getInstance()->renderPropertyLines(); } - LLViewerParcelMgr::getInstance()->render(); - LLViewerParcelMgr::getInstance()->renderParcelCollision(); - } - else if (gForceRenderLandFence) - { - // This is only set when not rendering the UI, for parcel snapshots - LLViewerParcelMgr::getInstance()->render(); - } - else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - LLHUDText::renderAllHUD(); - } + LLViewerParcelMgr::getInstance()->render(); + LLViewerParcelMgr::getInstance()->renderParcelCollision(); + } + else if (gForceRenderLandFence) + { + // This is only set when not rendering the UI, for parcel snapshots + LLViewerParcelMgr::getInstance()->render(); + } + else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + LLHUDText::renderAllHUD(); + } - gUIProgram.unbind(); + gUIProgram.unbind(); } void LLPipeline::renderHighlights() { - assertInitialized(); - - // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) - // Render highlighted faces. - LLGLSPipelineAlpha gls_pipeline_alpha; - LLColor4 color(1.f, 1.f, 1.f, 0.5f); - disableLights(); - - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) - { - mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) - { - // Make sure the selection image gets downloaded and decoded - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) - { - // Paint 'em red! - color.setVec(1.f, 0.f, 0.f, 0.5f); - - int count = mHighlightFaces.size(); - for (S32 i = 0; i < count; i++) - { - LLFace* facep = mHighlightFaces[i]; - facep->renderSelected(LLViewerTexture::sNullImagep, color); - } - } - - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); - - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) - { - gHighlightProgram.unbind(); - } - - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) - { - color.setVec(1.0f, 0.5f, 0.5f, 0.5f); - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightNormalProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightNormalProgram.unbind(); - } - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) - { - color.setVec(0.0f, 0.3f, 1.0f, 0.8f); - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.unbind(); - } - } + assertInitialized(); + + // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) + // Render highlighted faces. + LLGLSPipelineAlpha gls_pipeline_alpha; + LLColor4 color(1.f, 1.f, 1.f, 0.5f); + disableLights(); + + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) + { + mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) + { + // Make sure the selection image gets downloaded and decoded + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + { + // Paint 'em red! + color.setVec(1.f, 0.f, 0.f, 0.5f); + + int count = mHighlightFaces.size(); + for (S32 i = 0; i < count; i++) + { + LLFace* facep = mHighlightFaces[i]; + facep->renderSelected(LLViewerTexture::sNullImagep, color); + } + } + + // Contains a list of the faces of objects that are physical or + // have touch-handlers. + mHighlightFaces.clear(); + + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) + { + gHighlightProgram.unbind(); + } + + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) + { + color.setVec(1.0f, 0.5f, 0.5f, 0.5f); + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.unbind(); + } + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) + { + color.setVec(0.0f, 0.3f, 1.0f, 0.8f); + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.unbind(); + } + } } //debug use @@ -3781,8 +3781,8 @@ U32 LLPipeline::sCurRenderPoolType = 0 ; void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); LL_PROFILE_GPU_ZONE("renderGeomDeferred"); llassert(!sRenderingHUDs); @@ -3793,7 +3793,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) } if (&camera == LLViewerCamera::getInstance()) - { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and + { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and // current modelview matrix glh::matrix4f last_modelview(gGLLastModelView); glh::matrix4f cur_modelview(gGLModelView); @@ -3815,23 +3815,23 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) setupHWLights(); - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); - LLGLEnable cull(GL_CULL_FACE); + LLGLEnable cull(GL_CULL_FACE); - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } + } - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); + LLGLState::checkStates(); if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1) { @@ -3840,17 +3840,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) mHeroProbeManager.updateUniforms(); } - U32 cur_type = 0; + U32 cur_type = 0; + + gGL.setColorMask(true, true); + + pool_set_t::iterator iter1 = mPools.begin(); - gGL.setColorMask(true, true); - - pool_set_t::iterator iter1 = mPools.begin(); + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); + cur_type = poolp->getType(); if (occlude && cur_type >= LLDrawPool::POOL_GRASS) { @@ -3861,57 +3861,57 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) doOcclusion(camera); } - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render"); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } - } - poolp->endDeferredPass(i); - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } - - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); - - gGL.setColorMask(true, false); - - } // Tracy ZoneScoped + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render"); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } + } + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); + + gGL.setColorMask(true, false); + + } // Tracy ZoneScoped if (gUseWireframe) { @@ -3921,7 +3921,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_GPU_ZONE("renderGeomPostDeferred"); if (gUseWireframe) @@ -3929,9 +3929,9 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } - U32 cur_type = 0; + U32 cur_type = 0; - LLGLEnable cull(GL_CULL_FACE); + LLGLEnable cull(GL_CULL_FACE); bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds bool done_water_haze = done_atmospherics; @@ -3947,24 +3947,24 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) // do water haze just before pre water alpha U32 water_haze_pass = LLDrawPool::POOL_ALPHA_PRE_WATER; - calcNearbyLights(camera); - setupHWLights(); + calcNearbyLights(camera); + setupHWLights(); gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); - pool_set_t::iterator iter1 = mPools.begin(); + pool_set_t::iterator iter1 = mPools.begin(); if (gDebugGL || gDebugPipeline) { LLGLState::checkStates(GL_FALSE); } - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); if (cur_type >= atmospherics_pass && !done_atmospherics) { // do atmospherics against depth buffer before rendering alpha @@ -3978,56 +3978,56 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) done_water_haze = true; } - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender"); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginPostDeferredPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - p->renderPostDeferred(i); - } - poolp->endPostDeferredPass(i); - LLVertexBuffer::unbind(); - - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(GL_FALSE); - } - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } - - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender"); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginPostDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderPostDeferred(i); + } + poolp->endPostDeferredPass(i); + LLVertexBuffer::unbind(); + + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(GL_FALSE); + } + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); if (!gCubeSnapshot) { @@ -4049,63 +4049,63 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LL_PROFILE_GPU_ZONE("renderGeomShadow"); U32 cur_type = 0; - - LLGLEnable cull(GL_CULL_FACE); - - LLVertexBuffer::unbind(); - - pool_set_t::iterator iter1 = mPools.begin(); - - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); - - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) - { - poolp->prerender() ; - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginShadowPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - p->renderShadow(i); - } - poolp->endShadowPass(i); - LLVertexBuffer::unbind(); - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + + LLGLEnable cull(GL_CULL_FACE); + + LLVertexBuffer::unbind(); + + pool_set_t::iterator iter1 = mPools.begin(); + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) + { + poolp->prerender() ; + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginShadowPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderShadow(i); + } + poolp->endShadowPass(i); + LLVertexBuffer::unbind(); + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); } @@ -4126,10 +4126,10 @@ void LLPipeline::recordTrianglesDrawn() void LLPipeline::renderPhysicsDisplay() { - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) - { - return; - } + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + return; + } gGL.flush(); gDebugProgram.bind(); @@ -4179,7 +4179,7 @@ void LLPipeline::renderPhysicsDisplay() } } glLineWidth(1.f); - gDebugProgram.unbind(); + gDebugProgram.unbind(); } @@ -4189,379 +4189,379 @@ void LLPipeline::renderDebug() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - - bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); - - if (!hud_only ) - { - //Render any navmesh geometry - LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance(); - if ( llPathingLibInstance != NULL ) - { - //character floater renderables - - LLHandle pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle(); - if ( !pathfindingCharacterHandle.isDead() ) - { - LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get(); - - if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) - { - gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - - //Requried character physics capsule render parameters - LLUUID id; - LLVector3 pos; - LLQuaternion rot; - - if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) - { - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gGL.setColorMask(true, false); - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gPathfindingProgram.bind(); - } - } - } - - - //pathing console renderables - LLHandle pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); - if (!pathfindingConsoleHandle.isDead()) - { - LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get(); - - if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() ) - { - F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); - - gPathfindingProgram.bind(); - - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - - if ( !pathfindingConsole->isRenderWorld() ) - { - const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear"); - gGL.setColorMask(true, true); - glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT); - gGL.setColorMask(true, false); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - - //NavMesh - if ( pathfindingConsole->isRenderNavMesh() ) - { - gGL.flush(); - glLineWidth(2.0f); - LLGLEnable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - - if ( pathfindingConsole->isRenderWorld() ) - { - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.66f); - llPathingLibInstance->renderNavMesh(); - } - else - { - llPathingLibInstance->renderNavMesh(); - } - - //render edges - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - - gGL.flush(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glLineWidth(1.0f); - gGL.flush(); - } - //User designated path - if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) - { - //The path - gUIProgram.bind(); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - llPathingLibInstance->renderPath(); - gPathfindingProgram.bind(); + assertInitialized(); - //The bookends - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - - gGL.setColorMask(true, false); - //render the bookends - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - gPathfindingProgram.bind(); - } - - if ( pathfindingConsole->isRenderWaterPlane() ) - { - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); - } - //physics/exclusion shapes - if ( pathfindingConsole->isRenderAnyShapes() ) - { - U32 render_order[] = { - 1 << LLPathingLib::LLST_ObstacleObjects, - 1 << LLPathingLib::LLST_WalkableObjects, - 1 << LLPathingLib::LLST_ExclusionPhantoms, - 1 << LLPathingLib::LLST_MaterialPhantoms, - }; - - U32 flags = pathfindingConsole->getRenderShapeFlags(); - - for (U32 i = 0; i < 4; i++) - { - if (!(flags & render_order[i])) - { - continue; - } - - //turn off backface culling for volumes so they are visible when camera is inside volume - LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); - - gGL.flush(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - - //get rid of some z-fighting - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f, 1.0f); - - //render to depth first to avoid blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.setColorMask(true, false); - - //get rid of some z-fighting - glPolygonOffset(0.f, 0.f); - - LLGLEnable blend(GL_BLEND); - - { - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - - { //draw solid overlay - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.flush(); - } - - LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - - F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); - - if (pathfindingConsole->isRenderXRay()) - { - gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - - glPolygonOffset(offset, -offset); - - if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) - { //draw hidden wireframe as darker and less opaque - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - } - else - { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } - } - - { //draw visible wireframe as brighter, thicker and more opaque - glPolygonOffset(offset, offset); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - - glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); - LLGLDisable blendOut(GL_BLEND); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.flush(); - glLineWidth(1.f); - } - - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - } - } - - glPolygonOffset(0.f, 0.f); - - if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() ) - { //render navmesh xray - F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); - - LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - - F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); - glPolygonOffset(offset, -offset); - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - gGL.flush(); - glLineWidth(2.0f); - LLGLEnable cull(GL_CULL_FACE); - - gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - - if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) - { //draw hidden wireframe as darker and less opaque - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - llPathingLibInstance->renderNavMesh(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - else - { - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - llPathingLibInstance->renderNavMesh(); - } - - //render edges - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - - gGL.flush(); - glLineWidth(1.0f); - } - - glPolygonOffset(0.f, 0.f); - - gGL.flush(); - gPathfindingProgram.unbind(); - } - } - } - } - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); - - - if (!hud_only && !mDebugBlips.empty()) - { //render debug blips - gUIProgram.bind(); + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + + if (!hud_only ) + { + //Render any navmesh geometry + LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance(); + if ( llPathingLibInstance != NULL ) + { + //character floater renderables + + LLHandle pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle(); + if ( !pathfindingCharacterHandle.isDead() ) + { + LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get(); + + if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) + { + gPathfindingProgram.bind(); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + + //Requried character physics capsule render parameters + LLUUID id; + LLVector3 pos; + LLQuaternion rot; + + if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) + { + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gGL.setColorMask(true, false); + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gPathfindingProgram.bind(); + } + } + } + + + //pathing console renderables + LLHandle pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); + if (!pathfindingConsoleHandle.isDead()) + { + LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get(); + + if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() ) + { + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + gPathfindingProgram.bind(); + + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + + if ( !pathfindingConsole->isRenderWorld() ) + { + const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear"); + gGL.setColorMask(true, true); + glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT); + gGL.setColorMask(true, false); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + + //NavMesh + if ( pathfindingConsole->isRenderNavMesh() ) + { + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + if ( pathfindingConsole->isRenderWorld() ) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.66f); + llPathingLibInstance->renderNavMesh(); + } + else + { + llPathingLibInstance->renderNavMesh(); + } + + //render edges + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glLineWidth(1.0f); + gGL.flush(); + } + //User designated path + if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) + { + //The path + gUIProgram.bind(); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + llPathingLibInstance->renderPath(); + gPathfindingProgram.bind(); + + //The bookends + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + + gGL.setColorMask(true, false); + //render the bookends + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + gPathfindingProgram.bind(); + } + + if ( pathfindingConsole->isRenderWaterPlane() ) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); + } + //physics/exclusion shapes + if ( pathfindingConsole->isRenderAnyShapes() ) + { + U32 render_order[] = { + 1 << LLPathingLib::LLST_ObstacleObjects, + 1 << LLPathingLib::LLST_WalkableObjects, + 1 << LLPathingLib::LLST_ExclusionPhantoms, + 1 << LLPathingLib::LLST_MaterialPhantoms, + }; + + U32 flags = pathfindingConsole->getRenderShapeFlags(); + + for (U32 i = 0; i < 4; i++) + { + if (!(flags & render_order[i])) + { + continue; + } + + //turn off backface culling for volumes so they are visible when camera is inside volume + LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + + //get rid of some z-fighting + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0f, 1.0f); + + //render to depth first to avoid blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.setColorMask(true, false); + + //get rid of some z-fighting + glPolygonOffset(0.f, 0.f); + + LLGLEnable blend(GL_BLEND); + + { + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + + { //draw solid overlay + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + } + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + + if (pathfindingConsole->isRenderXRay()) + { + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + glPolygonOffset(offset, -offset); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + } + else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + } + + { //draw visible wireframe as brighter, thicker and more opaque + glPolygonOffset(offset, offset); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + + glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); + LLGLDisable blendOut(GL_BLEND); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + glLineWidth(1.f); + } + + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } + } + + glPolygonOffset(0.f, 0.f); + + if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() ) + { //render navmesh xray + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + glPolygonOffset(offset, -offset); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + llPathingLibInstance->renderNavMesh(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else + { + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + llPathingLibInstance->renderNavMesh(); + } + + //render edges + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + + gGL.flush(); + glLineWidth(1.0f); + } + + glPolygonOffset(0.f, 0.f); + + gGL.flush(); + gPathfindingProgram.unbind(); + } + } + } + } + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + gGL.setColorMask(true, false); + + + if (!hud_only && !mDebugBlips.empty()) + { //render debug blips + gUIProgram.bind(); gGL.color4f(1, 1, 1, 1); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); - - glPointSize(8.f); - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - - gGL.begin(LLRender::POINTS); - for (std::list::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) - { - DebugBlip& blip = *iter; - - blip.mAge += gFrameIntervalSeconds.value(); - if (blip.mAge > 2.f) - { - mDebugBlips.erase(iter++); - } - else - { - iter++; - } - - blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; - - gGL.color4fv(blip.mColor.mV); - gGL.vertex3fv(blip.mPosition.mV); - } - gGL.end(); - gGL.flush(); - glPointSize(1.f); - } - - // Debug stuff. - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || - (!hud_only && hasRenderType(part->mDrawableType)) ) - { - part->renderDebug(); - } - } - } - } - - for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - bridge->renderDebug(); - gGL.popMatrix(); - } - } + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); + + glPointSize(8.f); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + gGL.begin(LLRender::POINTS); + for (std::list::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) + { + DebugBlip& blip = *iter; + + blip.mAge += gFrameIntervalSeconds.value(); + if (blip.mAge > 2.f) + { + mDebugBlips.erase(iter++); + } + else + { + iter++; + } + + blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; + + gGL.color4fv(blip.mColor.mV); + gGL.vertex3fv(blip.mPosition.mV); + } + gGL.end(); + gGL.flush(); + glPointSize(1.f); + } + + // Debug stuff. + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || + (!hud_only && hasRenderType(part->mDrawableType)) ) + { + part->renderDebug(); + } + } + } + } + + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderDebug(); + gGL.popMatrix(); + } + } LL::GLTFSceneManager::instance().renderDebug(); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) - { //render visible selected group occlusion geometry - gDebugProgram.bind(); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.diffuseColor3f(1,0,1); - for (std::set::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter) - { - LLSpatialGroup* group = *iter; + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { //render visible selected group occlusion geometry + gDebugProgram.bind(); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.diffuseColor3f(1,0,1); + for (std::set::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter) + { + LLSpatialGroup* group = *iter; - LLVector4a fudge; - fudge.splat(0.25f); //SG_OCCLUSION_FUDGE + LLVector4a fudge; + fudge.splat(0.25f); //SG_OCCLUSION_FUDGE - LLVector4a size; - const LLVector4a* bounds = group->getBounds(); - size.setAdd(fudge, bounds[1]); - - drawBox(bounds[0], size); - } - } + LLVector4a size; + const LLVector4a* bounds = group->getBounds(); + size.setAdd(fudge, bounds[1]); + + drawBox(bounds[0], size); + } + } - visible_selected_groups.clear(); + visible_selected_groups.clear(); //draw reflection probes and links between them if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only) @@ -4584,559 +4584,559 @@ void LLPipeline::renderDebug() unbindDeferredShader(gReflectionProbeDisplayProgram); } - gUIProgram.bind(); - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) - { //draw crosshairs on particle intersection - if (gDebugRaycastParticle) - { - gDebugProgram.bind(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); - LLVector3 size(0.1f, 0.1f, 0.1f); - - LLVector3 p[6]; - - p[0] = center + size.scaledVec(LLVector3(1,0,0)); - p[1] = center + size.scaledVec(LLVector3(-1,0,0)); - p[2] = center + size.scaledVec(LLVector3(0,1,0)); - p[3] = center + size.scaledVec(LLVector3(0,-1,0)); - p[4] = center + size.scaledVec(LLVector3(0,0,1)); - p[5] = center + size.scaledVec(LLVector3(0,0,-1)); - - gGL.begin(LLRender::LINES); - gGL.diffuseColor3f(1.f, 1.f, 0.f); - for (U32 i = 0; i < 6; i++) - { - gGL.vertex3fv(p[i].mV); - } - gGL.end(); - gGL.flush(); - - gDebugProgram.unbind(); - } - } - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only) - { - LLVertexBuffer::unbind(); - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(TRUE, FALSE); - LLGLDisable cull(GL_CULL_FACE); - - gGL.color4f(1,1,1,1); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - F32 a = 0.1f; - - F32 col[] = - { - 1,0,0,a, - 0,1,0,a, - 0,0,1,a, - 1,0,1,a, - - 1,1,0,a, - 0,1,1,a, - 1,1,1,a, - 1,0,1,a, - }; - - for (U32 i = 0; i < 8; i++) - { - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - - if (i > 3) - { //render shadow frusta as volumes - if (mShadowFrustPoints[i-4].empty()) - { - continue; - } - - gGL.color4fv(col+(i-4)*4); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.end(); - - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[0].mV); - gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[2].mV); - gGL.end(); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[6].mV); - gGL.end(); - } - - - if (i < 4) - { - - //if (i == 0 || !mShadowFrustPoints[i].empty()) - { - //render visible point cloud - gGL.flush(); - glPointSize(8.f); - gGL.begin(LLRender::POINTS); - - F32* c = col+i*4; - gGL.color3fv(c); - - for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) - { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - - } - gGL.end(); - - gGL.flush(); - glPointSize(1.f); - - LLVector3* ext = mShadowExtents[i]; - LLVector3 pos = (ext[0]+ext[1])*0.5f; - LLVector3 size = (ext[1]-ext[0])*0.5f; - drawBoxOutline(pos, size); - - //render camera frustum splits as outlines - gGL.begin(LLRender::LINES); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); - gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); - gGL.end(); - } - } - - /*gGL.flush(); - glLineWidth(16-i*2); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - part->renderIntersectingBBoxes(&mShadowCamera[i]); - } - } - } - } - gGL.flush(); - glLineWidth(1.f);*/ - } - } - - if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) - { - gAgent.getRegion()->mWind.renderVectors(); - } - - if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) - { - // Debug composition layers - F32 x, y; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - if (gAgent.getRegion()) - { - gGL.begin(LLRender::POINTS); - // Draw the composition layer for the region that I'm in. - for (x = 0; x <= 260; x++) - { - for (y = 0; y <= 260; y++) - { - if ((x > 255) || (y > 255)) - { - gGL.color4f(1.f, 0.f, 0.f, 1.f); - } - else - { - gGL.color4f(0.f, 0.f, 1.f, 1.f); - } - F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); - z *= 5.f; - z += 50.f; - gGL.vertex3f(x, y, z); - } - } - gGL.end(); - } - } - - gGL.flush(); - gUIProgram.unbind(); + gUIProgram.bind(); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) + { //draw crosshairs on particle intersection + if (gDebugRaycastParticle) + { + gDebugProgram.bind(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); + LLVector3 size(0.1f, 0.1f, 0.1f); + + LLVector3 p[6]; + + p[0] = center + size.scaledVec(LLVector3(1,0,0)); + p[1] = center + size.scaledVec(LLVector3(-1,0,0)); + p[2] = center + size.scaledVec(LLVector3(0,1,0)); + p[3] = center + size.scaledVec(LLVector3(0,-1,0)); + p[4] = center + size.scaledVec(LLVector3(0,0,1)); + p[5] = center + size.scaledVec(LLVector3(0,0,-1)); + + gGL.begin(LLRender::LINES); + gGL.diffuseColor3f(1.f, 1.f, 0.f); + for (U32 i = 0; i < 6; i++) + { + gGL.vertex3fv(p[i].mV); + } + gGL.end(); + gGL.flush(); + + gDebugProgram.unbind(); + } + } + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only) + { + LLVertexBuffer::unbind(); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(TRUE, FALSE); + LLGLDisable cull(GL_CULL_FACE); + + gGL.color4f(1,1,1,1); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + F32 a = 0.1f; + + F32 col[] = + { + 1,0,0,a, + 0,1,0,a, + 0,0,1,a, + 1,0,1,a, + + 1,1,0,a, + 0,1,1,a, + 1,1,1,a, + 1,0,1,a, + }; + + for (U32 i = 0; i < 8; i++) + { + LLVector3* frust = mShadowCamera[i].mAgentFrustum; + + if (i > 3) + { //render shadow frusta as volumes + if (mShadowFrustPoints[i-4].empty()) + { + continue; + } + + gGL.color4fv(col+(i-4)*4); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.end(); + + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[2].mV); + gGL.end(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[6].mV); + gGL.end(); + } + + + if (i < 4) + { + + //if (i == 0 || !mShadowFrustPoints[i].empty()) + { + //render visible point cloud + gGL.flush(); + glPointSize(8.f); + gGL.begin(LLRender::POINTS); + + F32* c = col+i*4; + gGL.color3fv(c); + + for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) + { + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + + } + gGL.end(); + + gGL.flush(); + glPointSize(1.f); + + LLVector3* ext = mShadowExtents[i]; + LLVector3 pos = (ext[0]+ext[1])*0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + drawBoxOutline(pos, size); + + //render camera frustum splits as outlines + gGL.begin(LLRender::LINES); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.end(); + } + } + + /*gGL.flush(); + glLineWidth(16-i*2); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) + { + LLSpatialPartition* part = region->getSpatialPartition(j); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderIntersectingBBoxes(&mShadowCamera[i]); + } + } + } + } + gGL.flush(); + glLineWidth(1.f);*/ + } + } + + if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) + { + gAgent.getRegion()->mWind.renderVectors(); + } + + if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) + { + // Debug composition layers + F32 x, y; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + if (gAgent.getRegion()) + { + gGL.begin(LLRender::POINTS); + // Draw the composition layer for the region that I'm in. + for (x = 0; x <= 260; x++) + { + for (y = 0; y <= 260; y++) + { + if ((x > 255) || (y > 255)) + { + gGL.color4f(1.f, 0.f, 0.f, 1.f); + } + else + { + gGL.color4f(0.f, 0.f, 1.f, 1.f); + } + F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); + z *= 5.f; + z += 50.f; + gGL.vertex3f(x, y, z); + } + } + gGL.end(); + } + } + + gGL.flush(); + gUIProgram.unbind(); } void LLPipeline::rebuildPools() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - - S32 max_count = mPools.size(); - pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); - while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) - { - if (iter1 == mPools.end()) - { - iter1 = mPools.begin(); - } - LLDrawPool* poolp = *iter1; - - if (poolp->isDead()) - { - mPools.erase(iter1++); - removeFromQuickLookup( poolp ); - if (poolp == mLastRebuildPool) - { - mLastRebuildPool = NULL; - } - delete poolp; - } - else - { - mLastRebuildPool = poolp; - iter1++; - } - max_count--; - } + assertInitialized(); + + S32 max_count = mPools.size(); + pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); + while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) + { + if (iter1 == mPools.end()) + { + iter1 = mPools.begin(); + } + LLDrawPool* poolp = *iter1; + + if (poolp->isDead()) + { + mPools.erase(iter1++); + removeFromQuickLookup( poolp ); + if (poolp == mLastRebuildPool) + { + mLastRebuildPool = NULL; + } + delete poolp; + } + else + { + mLastRebuildPool = poolp; + iter1++; + } + max_count--; + } } void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) { - assertInitialized(); - - switch( new_poolp->getType() ) - { - case LLDrawPool::POOL_SIMPLE: - if (mSimplePool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; - } - else - { - mSimplePool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_ALPHA_MASK: - if (mAlphaMaskPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; - break; - } - else - { - mAlphaMaskPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - if (mFullbrightAlphaMaskPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; - break; - } - else - { - mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_GRASS: - if (mGrassPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL; - } - else - { - mGrassPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_FULLBRIGHT: - if (mFullbrightPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; - } - else - { - mFullbrightPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_GLOW: - if (mGlowPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL; - } - else - { - mGlowPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_TREE: - mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; - break; - - case LLDrawPool::POOL_TERRAIN: - mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; - break; - - case LLDrawPool::POOL_BUMP: - if (mBumpPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL; - } - else - { - mBumpPool = new_poolp; - } - break; - case LLDrawPool::POOL_MATERIALS: - if (mMaterialsPool) - { - llassert(0); - LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL; - } - else - { - mMaterialsPool = new_poolp; - } - break; - case LLDrawPool::POOL_ALPHA_PRE_WATER: - if( mAlphaPoolPreWater ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL; - } - else - { - mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp; - } - break; - case LLDrawPool::POOL_ALPHA_POST_WATER: - if (mAlphaPoolPostWater) + assertInitialized(); + + switch( new_poolp->getType() ) + { + case LLDrawPool::POOL_SIMPLE: + if (mSimplePool) { llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha post-water pool" << LL_ENDL; + LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; } else { - mAlphaPoolPostWater = (LLDrawPoolAlpha*)new_poolp; + mSimplePool = (LLRenderPass*) new_poolp; } break; - case LLDrawPool::POOL_AVATAR: - case LLDrawPool::POOL_CONTROL_AV: - break; // Do nothing - - case LLDrawPool::POOL_SKY: - if( mSkyPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL; - } - else - { - mSkyPool = new_poolp; - } - break; - - case LLDrawPool::POOL_WATER: - if( mWaterPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL; - } - else - { - mWaterPool = new_poolp; - } - break; - - case LLDrawPool::POOL_WL_SKY: - if( mWLSkyPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL; - } - else - { - mWLSkyPool = new_poolp; - } - break; + case LLDrawPool::POOL_ALPHA_MASK: + if (mAlphaMaskPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; + break; + } + else + { + mAlphaMaskPool = (LLRenderPass*) new_poolp; + } + break; - case LLDrawPool::POOL_GLTF_PBR: - if( mPBROpaquePool ) + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + if (mFullbrightAlphaMaskPool) { llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL; + LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; + break; } else { - mPBROpaquePool = new_poolp; + mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; } break; - case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: - if (mPBRAlphaMaskPool) + case LLDrawPool::POOL_GRASS: + if (mGrassPool) { llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Alpha Mask Pool" << LL_ENDL; + LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL; } else { - mPBRAlphaMaskPool = new_poolp; + mGrassPool = (LLRenderPass*) new_poolp; } break; + case LLDrawPool::POOL_FULLBRIGHT: + if (mFullbrightPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; + } + else + { + mFullbrightPool = (LLRenderPass*) new_poolp; + } + break; - default: - llassert(0); - LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL; - break; - } -} + case LLDrawPool::POOL_GLOW: + if (mGlowPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL; + } + else + { + mGlowPool = (LLRenderPass*) new_poolp; + } + break; -void LLPipeline::removePool( LLDrawPool* poolp ) + case LLDrawPool::POOL_TREE: + mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; + break; + + case LLDrawPool::POOL_TERRAIN: + mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; + break; + + case LLDrawPool::POOL_BUMP: + if (mBumpPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL; + } + else + { + mBumpPool = new_poolp; + } + break; + case LLDrawPool::POOL_MATERIALS: + if (mMaterialsPool) + { + llassert(0); + LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL; + } + else + { + mMaterialsPool = new_poolp; + } + break; + case LLDrawPool::POOL_ALPHA_PRE_WATER: + if( mAlphaPoolPreWater ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL; + } + else + { + mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp; + } + break; + case LLDrawPool::POOL_ALPHA_POST_WATER: + if (mAlphaPoolPostWater) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha post-water pool" << LL_ENDL; + } + else + { + mAlphaPoolPostWater = (LLDrawPoolAlpha*)new_poolp; + } + break; + + case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: + break; // Do nothing + + case LLDrawPool::POOL_SKY: + if( mSkyPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL; + } + else + { + mSkyPool = new_poolp; + } + break; + + case LLDrawPool::POOL_WATER: + if( mWaterPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL; + } + else + { + mWaterPool = new_poolp; + } + break; + + case LLDrawPool::POOL_WL_SKY: + if( mWLSkyPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL; + } + else + { + mWLSkyPool = new_poolp; + } + break; + + case LLDrawPool::POOL_GLTF_PBR: + if( mPBROpaquePool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL; + } + else + { + mPBROpaquePool = new_poolp; + } + break; + + case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: + if (mPBRAlphaMaskPool) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Alpha Mask Pool" << LL_ENDL; + } + else + { + mPBRAlphaMaskPool = new_poolp; + } + break; + + + default: + llassert(0); + LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL; + break; + } +} + +void LLPipeline::removePool( LLDrawPool* poolp ) { - assertInitialized(); - removeFromQuickLookup(poolp); - mPools.erase(poolp); - delete poolp; + assertInitialized(); + removeFromQuickLookup(poolp); + mPools.erase(poolp); + delete poolp; } void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) { - assertInitialized(); - switch( poolp->getType() ) - { - case LLDrawPool::POOL_SIMPLE: - llassert(mSimplePool == poolp); - mSimplePool = NULL; - break; - - case LLDrawPool::POOL_ALPHA_MASK: - llassert(mAlphaMaskPool == poolp); - mAlphaMaskPool = NULL; - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - llassert(mFullbrightAlphaMaskPool == poolp); - mFullbrightAlphaMaskPool = NULL; - break; - - case LLDrawPool::POOL_GRASS: - llassert(mGrassPool == poolp); - mGrassPool = NULL; - break; - - case LLDrawPool::POOL_FULLBRIGHT: - llassert(mFullbrightPool == poolp); - mFullbrightPool = NULL; - break; - - case LLDrawPool::POOL_WL_SKY: - llassert(mWLSkyPool == poolp); - mWLSkyPool = NULL; - break; - - case LLDrawPool::POOL_GLOW: - llassert(mGlowPool == poolp); - mGlowPool = NULL; - break; - - case LLDrawPool::POOL_TREE: - #ifdef _DEBUG - { - bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); - llassert( found ); - } - #else - mTreePools.erase( (uintptr_t)poolp->getTexture() ); - #endif - break; - - case LLDrawPool::POOL_TERRAIN: - #ifdef _DEBUG - { - bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); - llassert( found ); - } - #else - mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); - #endif - break; - - case LLDrawPool::POOL_BUMP: - llassert( poolp == mBumpPool ); - mBumpPool = NULL; - break; - - case LLDrawPool::POOL_MATERIALS: - llassert(poolp == mMaterialsPool); - mMaterialsPool = NULL; - break; - - case LLDrawPool::POOL_ALPHA_PRE_WATER: - llassert( poolp == mAlphaPoolPreWater ); - mAlphaPoolPreWater = nullptr; - break; - + assertInitialized(); + switch( poolp->getType() ) + { + case LLDrawPool::POOL_SIMPLE: + llassert(mSimplePool == poolp); + mSimplePool = NULL; + break; + + case LLDrawPool::POOL_ALPHA_MASK: + llassert(mAlphaMaskPool == poolp); + mAlphaMaskPool = NULL; + break; + + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + llassert(mFullbrightAlphaMaskPool == poolp); + mFullbrightAlphaMaskPool = NULL; + break; + + case LLDrawPool::POOL_GRASS: + llassert(mGrassPool == poolp); + mGrassPool = NULL; + break; + + case LLDrawPool::POOL_FULLBRIGHT: + llassert(mFullbrightPool == poolp); + mFullbrightPool = NULL; + break; + + case LLDrawPool::POOL_WL_SKY: + llassert(mWLSkyPool == poolp); + mWLSkyPool = NULL; + break; + + case LLDrawPool::POOL_GLOW: + llassert(mGlowPool == poolp); + mGlowPool = NULL; + break; + + case LLDrawPool::POOL_TREE: + #ifdef _DEBUG + { + bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); + llassert( found ); + } + #else + mTreePools.erase( (uintptr_t)poolp->getTexture() ); + #endif + break; + + case LLDrawPool::POOL_TERRAIN: + #ifdef _DEBUG + { + bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); + llassert( found ); + } + #else + mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); + #endif + break; + + case LLDrawPool::POOL_BUMP: + llassert( poolp == mBumpPool ); + mBumpPool = NULL; + break; + + case LLDrawPool::POOL_MATERIALS: + llassert(poolp == mMaterialsPool); + mMaterialsPool = NULL; + break; + + case LLDrawPool::POOL_ALPHA_PRE_WATER: + llassert( poolp == mAlphaPoolPreWater ); + mAlphaPoolPreWater = nullptr; + break; + case LLDrawPool::POOL_ALPHA_POST_WATER: llassert(poolp == mAlphaPoolPostWater); mAlphaPoolPostWater = nullptr; break; - case LLDrawPool::POOL_AVATAR: - case LLDrawPool::POOL_CONTROL_AV: - break; // Do nothing + case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: + break; // Do nothing - case LLDrawPool::POOL_SKY: - llassert( poolp == mSkyPool ); - mSkyPool = NULL; - break; + case LLDrawPool::POOL_SKY: + llassert( poolp == mSkyPool ); + mSkyPool = NULL; + break; - case LLDrawPool::POOL_WATER: - llassert( poolp == mWaterPool ); - mWaterPool = NULL; - break; + case LLDrawPool::POOL_WATER: + llassert( poolp == mWaterPool ); + mWaterPool = NULL; + break; case LLDrawPool::POOL_GLTF_PBR: llassert( poolp == mPBROpaquePool ); @@ -5148,23 +5148,23 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mPBRAlphaMaskPool = NULL; break; - default: - llassert(0); - LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; - break; - } + default: + llassert(0); + LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; + break; + } } void LLPipeline::resetDrawOrders() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - assertInitialized(); - // Iterate through all of the draw pools and rebuild them. - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - poolp->resetDrawOrders(); - } + assertInitialized(); + // Iterate through all of the draw pools and rebuild them. + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + poolp->resetDrawOrders(); + } } //============================================================================ @@ -5173,7 +5173,7 @@ void LLPipeline::resetDrawOrders() void LLPipeline::setupAvatarLights(bool for_edit) { - assertInitialized(); + assertInitialized(); LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t psky = environment.getCurrentSky(); @@ -5181,130 +5181,130 @@ void LLPipeline::setupAvatarLights(bool for_edit) bool sun_up = environment.getIsSunUp(); - if (for_edit) - { - LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); - LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light - LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); - camera_rot.invert(); - LLVector4 light_pos = light_pos_cam * camera_rot; - - light_pos.normalize(); - - LLLightState* light = gGL.getLight(1); - - mHWLightColors[1] = diffuse; - - light->setDiffuse(diffuse); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setPosition(light_pos); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } - else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) - { + if (for_edit) + { + LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); + LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light + LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); + LLMatrix4 camera_rot(camera_mat.getMat3()); + camera_rot.invert(); + LLVector4 light_pos = light_pos_cam * camera_rot; + + light_pos.normalize(); + + LLLightState* light = gGL.getLight(1); + + mHWLightColors[1] = diffuse; + + light->setDiffuse(diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setPosition(light_pos); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } + else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) + { LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir); - LLVector3 opposite_pos = -light_dir; - LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis; - LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); - backlight_pos.normalize(); - - LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse; - - LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); - F32 max_component = 0.001f; - for (S32 i = 0; i < 3; i++) - { - if (backlight_diffuse.mV[i] > max_component) - { - max_component = backlight_diffuse.mV[i]; - } - } - F32 backlight_mag; - if (LLEnvironment::instance().getIsSunUp()) - { - backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; - } - else - { - backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT; - } - backlight_diffuse *= backlight_mag / max_component; - - mHWLightColors[1] = backlight_diffuse; - - LLLightState* light = gGL.getLight(1); - - light->setPosition(backlight_pos); - light->setDiffuse(backlight_diffuse); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } - else - { - LLLightState* light = gGL.getLight(1); - - mHWLightColors[1] = LLColor4::black; - - light->setDiffuse(LLColor4::black); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - } + LLVector3 opposite_pos = -light_dir; + LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis; + LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); + backlight_pos.normalize(); + + LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse; + + LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); + F32 max_component = 0.001f; + for (S32 i = 0; i < 3; i++) + { + if (backlight_diffuse.mV[i] > max_component) + { + max_component = backlight_diffuse.mV[i]; + } + } + F32 backlight_mag; + if (LLEnvironment::instance().getIsSunUp()) + { + backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; + } + else + { + backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT; + } + backlight_diffuse *= backlight_mag / max_component; + + mHWLightColors[1] = backlight_diffuse; + + LLLightState* light = gGL.getLight(1); + + light->setPosition(backlight_pos); + light->setDiffuse(backlight_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } + else + { + LLLightState* light = gGL.getLight(1); + + mHWLightColors[1] = LLColor4::black; + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } } static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - F32 inten = light->getLightIntensity(); - if (inten < .001f) - { - return max_dist; - } - bool selected = light->isSelected(); - if (selected) - { + F32 inten = light->getLightIntensity(); + if (inten < .001f) + { + return max_dist; + } + bool selected = light->isSelected(); + if (selected) + { return 0.f; // selected lights get highest priority - } + } F32 radius = light->getLightRadius(); F32 dist = dist_vec(light->getRenderPosition(), cam_pos); dist = llmax(dist - radius, 0.f); - if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE)) - { - // moving lights get a little higher priority (too much causes artifacts) + if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE)) + { + // moving lights get a little higher priority (too much causes artifacts) dist = llmax(dist - light->getLightRadius()*0.25f, 0.f); - } - return dist; + } + return dist; } void LLPipeline::calcNearbyLights(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - assertInitialized(); + assertInitialized(); - if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs) - { - return; - } + if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs) + { + return; + } static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); - if (local_light_count >= 1) - { - // mNearbyLight (and all light_set_t's) are sorted such that - // begin() == the closest light and rbegin() == the farthest light - const S32 MAX_LOCAL_LIGHTS = 6; + if (local_light_count >= 1) + { + // mNearbyLight (and all light_set_t's) are sorted such that + // begin() == the closest light and rbegin() == the farthest light + const S32 MAX_LOCAL_LIGHTS = 6; LLVector3 cam_pos = camera.getOrigin(); - + F32 max_dist; if (LLPipeline::sRenderDeferred) { @@ -5315,15 +5315,15 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f); } - // UPDATE THE EXISTING NEARBY LIGHTS - light_set_t cur_nearby_lights; - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - const Light* light = &(*iter); - LLDrawable* drawable = light->drawable; + // UPDATE THE EXISTING NEARBY LIGHTS + light_set_t cur_nearby_lights; + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + const Light* light = &(*iter); + LLDrawable* drawable = light->drawable; const LLViewerObject *vobj = light->drawable->getVObj(); - if(vobj && vobj->getAvatar() + if(vobj && vobj->getAvatar() && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow()) ) { @@ -5331,22 +5331,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) continue; } - LLVOVolume* volight = drawable->getVOVolume(); - if (!volight || !drawable->isState(LLDrawable::LIGHT)) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (light->fade <= -LIGHT_FADE_TIME) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (!sRenderAttachedLights && volight && volight->isAttachment()) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } + LLVOVolume* volight = drawable->getVOVolume(); + if (!volight || !drawable->isState(LLDrawable::LIGHT)) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (light->fade <= -LIGHT_FADE_TIME) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (!sRenderAttachedLights && volight && volight->isAttachment()) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } F32 dist = calc_light_dist(volight, cam_pos, max_dist); F32 fade = light->fade; @@ -5380,28 +5380,28 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) } } cur_nearby_lights.insert(Light(drawable, dist, fade)); - } - mNearbyLights = cur_nearby_lights; - - // FIND NEW LIGHTS THAT ARE IN RANGE - light_set_t new_nearby_lights; - for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin(); - iter != mLights.end(); ++iter) - { - LLDrawable* drawable = *iter; - LLVOVolume* light = drawable->getVOVolume(); - if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT)) - { - continue; - } - if (light->isHUDAttachment()) - { - continue; // no lighting from HUD objects - } + } + mNearbyLights = cur_nearby_lights; + + // FIND NEW LIGHTS THAT ARE IN RANGE + light_set_t new_nearby_lights; + for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin(); + iter != mLights.end(); ++iter) + { + LLDrawable* drawable = *iter; + LLVOVolume* light = drawable->getVOVolume(); + if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT)) + { + continue; + } + if (light->isHUDAttachment()) + { + continue; // no lighting from HUD objects + } if (!sRenderAttachedLights && light && light->isAttachment()) - { - continue; - } + { + continue; + } LLVOAvatar * av = light->getAvatar(); if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow())) { @@ -5410,36 +5410,36 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) } F32 dist = calc_light_dist(light, cam_pos, max_dist); if (dist >= max_dist) - { - continue; - } - new_nearby_lights.insert(Light(drawable, dist, 0.f)); + { + continue; + } + new_nearby_lights.insert(Light(drawable, dist, 0.f)); if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) - { - new_nearby_lights.erase(--new_nearby_lights.end()); - const Light& last = *new_nearby_lights.rbegin(); - max_dist = last.dist; - } - } - - // INSERT ANY NEW LIGHTS - for (light_set_t::iterator iter = new_nearby_lights.begin(); - iter != new_nearby_lights.end(); iter++) - { - const Light* light = &(*iter); + { + new_nearby_lights.erase(--new_nearby_lights.end()); + const Light& last = *new_nearby_lights.rbegin(); + max_dist = last.dist; + } + } + + // INSERT ANY NEW LIGHTS + for (light_set_t::iterator iter = new_nearby_lights.begin(); + iter != new_nearby_lights.end(); iter++) + { + const Light* light = &(*iter); if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS) - { - mNearbyLights.insert(*light); - ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT); - } - else - { - // crazy cast so that we can overwrite the fade value - // even though gcc enforces sets as const - // (fade value doesn't affect sort so this is safe) - Light* farthest_light = (const_cast(&(*(mNearbyLights.rbegin())))); - if (light->dist < farthest_light->dist) - { + { + mNearbyLights.insert(*light); + ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT); + } + else + { + // crazy cast so that we can overwrite the fade value + // even though gcc enforces sets as const + // (fade value doesn't affect sort so this is safe) + Light* farthest_light = (const_cast(&(*(mNearbyLights.rbegin())))); + if (light->dist < farthest_light->dist) + { // mark light to fade out // visibility goes down from -0 to -LIGHT_FADE_TIME. // @@ -5456,29 +5456,29 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) { farthest_light->fade -= LIGHT_FADE_TIME; } - } - else - { - break; // none of the other lights are closer - } - } - } - - //mark nearby lights not-removable. - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - const Light* light = &(*iter); - ((LLViewerOctreeEntryData*) light->drawable)->setVisible(); - } - } + } + else + { + break; // none of the other lights are closer + } + } + } + + //mark nearby lights not-removable. + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + const Light* light = &(*iter); + ((LLViewerOctreeEntryData*) light->drawable)->setVisible(); + } + } } void LLPipeline::setupHWLights() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - assertInitialized(); - + assertInitialized(); + if (LLPipeline::sRenderingHUDs) { return; @@ -5498,13 +5498,13 @@ void LLPipeline::setupHWLights() // Ambient LLColor4 ambient = psky->getTotalAmbient(); - gGL.setAmbientLightColor(ambient); + gGL.setAmbientLightColor(ambient); bool sun_up = environment.getIsSunUp(); bool moon_up = environment.getIsMoonUp(); - // Light 0 = Sun or Moon (All objects) - { + // Light 0 = Sun or Moon (All objects) + { LLVector4 sun_dir(environment.getSunDirection(), 0.0f); LLVector4 moon_dir(environment.getMoonDirection(), 0.0f); @@ -5514,12 +5514,12 @@ void LLPipeline::setupHWLights() mSunDiffuse.setVec(psky->getSunlightColor()); mMoonDiffuse.setVec(psky->getMoonlightColor()); - F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); - if (max_color > 1.f) - { - mSunDiffuse *= 1.f/max_color; - } - mSunDiffuse.clamp(); + F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); + if (max_color > 1.f) + { + mSunDiffuse *= 1.f/max_color; + } + mSunDiffuse.clamp(); max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]); if (max_color > 1.f) @@ -5530,54 +5530,54 @@ void LLPipeline::setupHWLights() // prevent underlighting from having neither lightsource facing us if (!sun_up && !moon_up) - { + { mSunDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0)); mMoonDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0)); mSunDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0)); mMoonDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0)); - } + } LLVector4 light_dir = sun_up ? mSunDir : mMoonDir; mHWLightColors[0] = sun_up ? mSunDiffuse : mMoonDiffuse; - LLLightState* light = gGL.getLight(0); + LLLightState* light = gGL.getLight(0); light->setPosition(light_dir); light->setSunPrimary(sun_up); light->setDiffuse(mHWLightColors[0]); light->setDiffuseB(mMoonDiffuse); light->setAmbient(psky->getTotalAmbient()); - light->setSpecular(LLColor4::black); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } - - // Light 1 = Backlight (for avatars) - // (set by enableLightsAvatar) - - S32 cur_light = 2; - - // Nearby lights = LIGHT 2-7 - - mLightMovingMask = 0; - + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } + + // Light 1 = Backlight (for avatars) + // (set by enableLightsAvatar) + + S32 cur_light = 2; + + // Nearby lights = LIGHT 2-7 + + mLightMovingMask = 0; + static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); - if (local_light_count >= 1) - { - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); ++iter) - { - LLDrawable* drawable = iter->drawable; - LLVOVolume* light = drawable->getVOVolume(); - if (!light) - { - continue; - } + if (local_light_count >= 1) + { + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); ++iter) + { + LLDrawable* drawable = iter->drawable; + LLVOVolume* light = drawable->getVOVolume(); + if (!light) + { + continue; + } if (light->isAttachment()) { @@ -5587,32 +5587,32 @@ void LLPipeline::setupHWLights() } } - if (drawable->isState(LLDrawable::ACTIVE)) - { - mLightMovingMask |= (1<isState(LLDrawable::ACTIVE)) + { + mLightMovingMask |= (1<getLightLinearColor() * light_scale; - light_color.mV[3] = 0.0f; - - F32 fade = iter->fade; - if (fade < LIGHT_FADE_TIME) - { - // fade in/out light - if (fade >= 0.f) - { - fade = fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); - } - else - { - fade = 1.f + fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); - } - fade = llclamp(fade,0.f,1.f); - light_color *= fade; - } + light_color.mV[3] = 0.0f; + + F32 fade = iter->fade; + if (fade < LIGHT_FADE_TIME) + { + // fade in/out light + if (fade >= 0.f) + { + fade = fade / LIGHT_FADE_TIME; + ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); + } + else + { + fade = 1.f + fade / LIGHT_FADE_TIME; + ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); + } + fade = llclamp(fade,0.f,1.f); + light_color *= fade; + } if (light_color.magVecSquared() < 0.001f) { @@ -5632,213 +5632,213 @@ void LLPipeline::setupHWLights() F32 linatten = x / adjusted_radius; // % of brightness at radius mHWLightColors[cur_light] = light_color; - LLLightState* light_state = gGL.getLight(cur_light); - - light_state->setPosition(light_pos_gl); - light_state->setDiffuse(light_color); - light_state->setAmbient(LLColor4::black); - light_state->setConstantAttenuation(0.f); + LLLightState* light_state = gGL.getLight(cur_light); + + light_state->setPosition(light_pos_gl); + light_state->setDiffuse(light_color); + light_state->setAmbient(LLColor4::black); + light_state->setConstantAttenuation(0.f); light_state->setSize(light->getLightRadius() * 1.5f); light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); - if (sRenderDeferred) - { - light_state->setLinearAttenuation(linatten); - light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights - } - else - { - light_state->setLinearAttenuation(linatten); - light_state->setQuadraticAttenuation(0.f); - } - - - if (light->isLightSpotlight() // directional (spot-)light - && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on - { - LLQuaternion quat = light->getRenderRotation(); - LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction - at_axis *= quat; - - light_state->setSpotDirection(at_axis); - light_state->setSpotCutoff(90.f); - light_state->setSpotExponent(2.f); - - LLVector3 spotParams = light->getSpotLightParams(); - - const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]); - light_state->setSpecular(specular); - } - else // omnidirectional (point) light - { - light_state->setSpotExponent(0.f); - light_state->setSpotCutoff(180.f); - - // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const LLColor4 specular(0.f, 0.f, 1.f, 0.f); - light_state->setSpecular(specular); - } - cur_light++; - if (cur_light >= 8) - { - break; // safety - } - } - } - for ( ; cur_light < 8 ; cur_light++) - { - mHWLightColors[cur_light] = LLColor4::black; - LLLightState* light = gGL.getLight(cur_light); - light->setSunPrimary(true); - light->setDiffuse(LLColor4::black); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - } + if (sRenderDeferred) + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } - // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), - // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20 - // Init GL state - for (S32 i = 0; i < 8; ++i) - { - gGL.getLight(i)->disable(); - } - mLightMask = 0; -} + if (light->isLightSpotlight() // directional (spot-)light + && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on + { + LLQuaternion quat = light->getRenderRotation(); + LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction + at_axis *= quat; -void LLPipeline::enableLights(U32 mask) -{ - assertInitialized(); - - if (mLightMask != mask) - { - stop_glerror(); - if (mask) - { - stop_glerror(); - for (S32 i=0; i<8; i++) - { - LLLightState* light = gGL.getLight(i); - if (mask & (1<enable(); - light->setDiffuse(mHWLightColors[i]); - } - else - { - light->disable(); - light->setDiffuse(LLColor4::black); - } - } - stop_glerror(); - } - mLightMask = mask; - stop_glerror(); - } + light_state->setSpotDirection(at_axis); + light_state->setSpotCutoff(90.f); + light_state->setSpotExponent(2.f); + + LLVector3 spotParams = light->getSpotLightParams(); + + const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]); + light_state->setSpecular(specular); + } + else // omnidirectional (point) light + { + light_state->setSpotExponent(0.f); + light_state->setSpotCutoff(180.f); + + // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight + const LLColor4 specular(0.f, 0.f, 1.f, 0.f); + light_state->setSpecular(specular); + } + cur_light++; + if (cur_light >= 8) + { + break; // safety + } + } + } + for ( ; cur_light < 8 ; cur_light++) + { + mHWLightColors[cur_light] = LLColor4::black; + LLLightState* light = gGL.getLight(cur_light); + light->setSunPrimary(true); + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } + + // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), + // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20 + + // Init GL state + for (S32 i = 0; i < 8; ++i) + { + gGL.getLight(i)->disable(); + } + mLightMask = 0; +} + +void LLPipeline::enableLights(U32 mask) +{ + assertInitialized(); + + if (mLightMask != mask) + { + stop_glerror(); + if (mask) + { + stop_glerror(); + for (S32 i=0; i<8; i++) + { + LLLightState* light = gGL.getLight(i); + if (mask & (1<enable(); + light->setDiffuse(mHWLightColors[i]); + } + else + { + light->disable(); + light->setDiffuse(LLColor4::black); + } + } + stop_glerror(); + } + mLightMask = mask; + stop_glerror(); + } } void LLPipeline::enableLightsDynamic() { - assertInitialized(); - U32 mask = 0xff & (~2); // Local lights - enableLights(mask); - - if (isAgentAvatarValid()) - { - if (gAgentAvatarp->mSpecialRenderMode == 0) // normal - { - gPipeline.enableLightsAvatar(); - } - else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview - { - gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); - } - } + assertInitialized(); + U32 mask = 0xff & (~2); // Local lights + enableLights(mask); + + if (isAgentAvatarValid()) + { + if (gAgentAvatarp->mSpecialRenderMode == 0) // normal + { + gPipeline.enableLightsAvatar(); + } + else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview + { + gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); + } + } } void LLPipeline::enableLightsAvatar() { - U32 mask = 0xff; // All lights - setupAvatarLights(FALSE); - enableLights(mask); + U32 mask = 0xff; // All lights + setupAvatarLights(FALSE); + enableLights(mask); } void LLPipeline::enableLightsPreview() { - disableLights(); - - LLColor4 ambient = PreviewAmbientColor; - gGL.setAmbientLightColor(ambient); - - LLColor4 diffuse0 = PreviewDiffuse0; - LLColor4 specular0 = PreviewSpecular0; - LLColor4 diffuse1 = PreviewDiffuse1; - LLColor4 specular1 = PreviewSpecular1; - LLColor4 diffuse2 = PreviewDiffuse2; - LLColor4 specular2 = PreviewSpecular2; - - LLVector3 dir0 = PreviewDirection0; - LLVector3 dir1 = PreviewDirection1; - LLVector3 dir2 = PreviewDirection2; - - dir0.normVec(); - dir1.normVec(); - dir2.normVec(); - - LLVector4 light_pos(dir0, 0.0f); - - LLLightState* light = gGL.getLight(1); - - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse0); - light->setAmbient(ambient); - light->setSpecular(specular0); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - - light_pos = LLVector4(dir1, 0.f); - - light = gGL.getLight(2); - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse1); - light->setAmbient(ambient); - light->setSpecular(specular1); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - - light_pos = LLVector4(dir2, 0.f); - light = gGL.getLight(3); - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse2); - light->setAmbient(ambient); - light->setSpecular(specular2); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); + disableLights(); + + LLColor4 ambient = PreviewAmbientColor; + gGL.setAmbientLightColor(ambient); + + LLColor4 diffuse0 = PreviewDiffuse0; + LLColor4 specular0 = PreviewSpecular0; + LLColor4 diffuse1 = PreviewDiffuse1; + LLColor4 specular1 = PreviewSpecular1; + LLColor4 diffuse2 = PreviewDiffuse2; + LLColor4 specular2 = PreviewSpecular2; + + LLVector3 dir0 = PreviewDirection0; + LLVector3 dir1 = PreviewDirection1; + LLVector3 dir2 = PreviewDirection2; + + dir0.normVec(); + dir1.normVec(); + dir2.normVec(); + + LLVector4 light_pos(dir0, 0.0f); + + LLLightState* light = gGL.getLight(1); + + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse0); + light->setAmbient(ambient); + light->setSpecular(specular0); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir1, 0.f); + + light = gGL.getLight(2); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse1); + light->setAmbient(ambient); + light->setSpecular(specular1); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir2, 0.f); + light = gGL.getLight(3); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse2); + light->setAmbient(ambient); + light->setSpecular(specular2); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) { - U32 mask = 0x2002; // Avatar backlight only, set ambient - setupAvatarLights(TRUE); - enableLights(mask); + U32 mask = 0x2002; // Avatar backlight only, set ambient + setupAvatarLights(TRUE); + enableLights(mask); - gGL.setAmbientLightColor(color); + gGL.setAmbientLightColor(color); } void LLPipeline::enableLightsFullbright() { - assertInitialized(); - U32 mask = 0x1000; // Non-0 mask, set ambient - enableLights(mask); + assertInitialized(); + U32 mask = 0x1000; // Non-0 mask, set ambient + enableLights(mask); } void LLPipeline::disableLights() { - enableLights(0); // no lighting (full bright) + enableLights(0); // no lighting (full bright) } //============================================================================ @@ -5851,58 +5851,58 @@ class LLVOLeaf; void LLPipeline::findReferences(LLDrawable *drawablep) { - assertInitialized(); - if (mLights.find(drawablep) != mLights.end()) - { - LL_INFOS() << "In mLights" << LL_ENDL; - } - if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end()) - { - LL_INFOS() << "In mMovedList" << LL_ENDL; - } - if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end()) - { - LL_INFOS() << "In mShiftList" << LL_ENDL; - } - if (mRetexturedList.find(drawablep) != mRetexturedList.end()) - { - LL_INFOS() << "In mRetexturedList" << LL_ENDL; - } - - if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) - { - LL_INFOS() << "In mBuildQ1" << LL_ENDL; - } - - S32 count; - - count = gObjectList.findReferences(drawablep); - if (count) - { - LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL; - } + assertInitialized(); + if (mLights.find(drawablep) != mLights.end()) + { + LL_INFOS() << "In mLights" << LL_ENDL; + } + if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end()) + { + LL_INFOS() << "In mMovedList" << LL_ENDL; + } + if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end()) + { + LL_INFOS() << "In mShiftList" << LL_ENDL; + } + if (mRetexturedList.find(drawablep) != mRetexturedList.end()) + { + LL_INFOS() << "In mRetexturedList" << LL_ENDL; + } + + if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) + { + LL_INFOS() << "In mBuildQ1" << LL_ENDL; + } + + S32 count; + + count = gObjectList.findReferences(drawablep); + if (count) + { + LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL; + } } bool LLPipeline::verify() { - bool ok = assertInitialized(); - if (ok) - { - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (!poolp->verify()) - { - ok = false; - } - } - } - - if (!ok) - { - LL_WARNS() << "Pipeline verify failed!" << LL_ENDL; - } - return ok; + bool ok = assertInitialized(); + if (ok) + { + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (!poolp->verify()) + { + ok = false; + } + } + } + + if (!ok) + { + LL_WARNS() << "Pipeline verify failed!" << LL_ENDL; + } + return ok; } ////////////////////////////// @@ -5913,89 +5913,89 @@ bool LLPipeline::verify() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * A method to compute a ray-AABB intersection. - * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 - * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) - * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only) + * A method to compute a ray-AABB intersection. + * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 + * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) + * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only) * - * Hence this version is faster as well as more robust than the original one. + * Hence this version is faster as well as more robust than the original one. * - * Should work provided: - * 1) the integer representation of 0.0f is 0x00000000 - * 2) the sign bit of the float is the most significant one + * Should work provided: + * 1) the integer representation of 0.0f is 0x00000000 + * 2) the sign bit of the float is the most significant one * - * Report bugs: p.terdiman@codercorner.com + * Report bugs: p.terdiman@codercorner.com * - * \param aabb [in] the axis-aligned bounding box - * \param origin [in] ray origin - * \param dir [in] ray direction - * \param coord [out] impact coordinates - * \return true if ray intersects AABB + * \param aabb [in] the axis-aligned bounding box + * \param origin [in] ray origin + * \param dir [in] ray direction + * \param coord [out] impact coordinates + * \return true if ray intersects AABB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //#define RAYAABB_EPSILON 0.00001f -#define IR(x) ((U32&)x) +#define IR(x) ((U32&)x) bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon) { - bool Inside = true; - LLVector3 MinB = center - size; - LLVector3 MaxB = center + size; - LLVector3 MaxT; - MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f; - - // Find candidate planes. - for(U32 i=0;i<3;i++) - { - if(origin.mV[i] < MinB.mV[i]) - { - coord.mV[i] = MinB.mV[i]; - Inside = false; - - // Calculate T distances to candidate planes - if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i]; - } - else if(origin.mV[i] > MaxB.mV[i]) - { - coord.mV[i] = MaxB.mV[i]; - Inside = false; - - // Calculate T distances to candidate planes - if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i]; - } - } - - // Ray origin inside bounding box - if(Inside) - { - coord = origin; - return true; - } - - // Get largest of the maxT's for final choice of intersection - U32 WhichPlane = 0; - if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1; - if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2; - - // Check final candidate actually inside box - if(IR(MaxT.mV[WhichPlane])&0x80000000) return false; - - for(U32 i=0;i<3;i++) - { - if(i!=WhichPlane) - { - coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i]; - if (epsilon > 0) - { - if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false; - } - else - { - if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false; - } - } - } - return true; // ray hits box + bool Inside = true; + LLVector3 MinB = center - size; + LLVector3 MaxB = center + size; + LLVector3 MaxT; + MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f; + + // Find candidate planes. + for(U32 i=0;i<3;i++) + { + if(origin.mV[i] < MinB.mV[i]) + { + coord.mV[i] = MinB.mV[i]; + Inside = false; + + // Calculate T distances to candidate planes + if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i]; + } + else if(origin.mV[i] > MaxB.mV[i]) + { + coord.mV[i] = MaxB.mV[i]; + Inside = false; + + // Calculate T distances to candidate planes + if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i]; + } + } + + // Ray origin inside bounding box + if(Inside) + { + coord = origin; + return true; + } + + // Get largest of the maxT's for final choice of intersection + U32 WhichPlane = 0; + if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1; + if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2; + + // Check final candidate actually inside box + if(IR(MaxT.mV[WhichPlane])&0x80000000) return false; + + for(U32 i=0;i<3;i++) + { + if(i!=WhichPlane) + { + coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i]; + if (epsilon > 0) + { + if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false; + } + else + { + if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false; + } + } + } + return true; // ray hits box } ////////////////////////////// @@ -6006,454 +6006,454 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& void LLPipeline::setLight(LLDrawable *drawablep, bool is_light) { - if (drawablep && assertInitialized()) - { - if (is_light) - { - mLights.insert(drawablep); - drawablep->setState(LLDrawable::LIGHT); - } - else - { - drawablep->clearState(LLDrawable::LIGHT); - mLights.erase(drawablep); - } - } + if (drawablep && assertInitialized()) + { + if (is_light) + { + mLights.insert(drawablep); + drawablep->setState(LLDrawable::LIGHT); + } + else + { + drawablep->clearState(LLDrawable::LIGHT); + mLights.erase(drawablep); + } + } } //static void LLPipeline::toggleRenderType(U32 type) { - gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; - if (type == LLPipeline::RENDER_TYPE_WATER) - { - gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER]; - } + gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; + if (type == LLPipeline::RENDER_TYPE_WATER) + { + gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER]; + } } //static void LLPipeline::toggleRenderTypeControl(U32 type) { - gPipeline.toggleRenderType(type); + gPipeline.toggleRenderType(type); } //static bool LLPipeline::hasRenderTypeControl(U32 type) { - return gPipeline.hasRenderType(type); + return gPipeline.hasRenderType(type); } // Allows UI items labeled "Hide foo" instead of "Show foo" //static bool LLPipeline::toggleRenderTypeControlNegated(S32 type) { - return !gPipeline.hasRenderType(type); + return !gPipeline.hasRenderType(type); } //static void LLPipeline::toggleRenderDebug(U64 bit) { - if (gPipeline.hasRenderDebugMask(bit)) - { - LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; - } - else - { - LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL; - } - gPipeline.mRenderDebugMask ^= bit; + if (gPipeline.hasRenderDebugMask(bit)) + { + LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; + } + else + { + LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL; + } + gPipeline.mRenderDebugMask ^= bit; } //static bool LLPipeline::toggleRenderDebugControl(U64 bit) { - return gPipeline.hasRenderDebugMask(bit); + return gPipeline.hasRenderDebugMask(bit); } //static void LLPipeline::toggleRenderDebugFeature(U32 bit) { - gPipeline.mRenderDebugFeatureMask ^= bit; + gPipeline.mRenderDebugFeatureMask ^= bit; } //static bool LLPipeline::toggleRenderDebugFeatureControl(U32 bit) { - return gPipeline.hasRenderDebugFeatureMask(bit); + return gPipeline.hasRenderDebugFeatureMask(bit); } void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) { - if (value) - { - gPipeline.mRenderDebugFeatureMask |= bit; - } - else - { - gPipeline.mRenderDebugFeatureMask &= !bit; - } + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } } void LLPipeline::pushRenderDebugFeatureMask() { - mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); + mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); } void LLPipeline::popRenderDebugFeatureMask() { - if (mRenderDebugFeatureStack.empty()) - { - LL_ERRS() << "Depleted render feature stack." << LL_ENDL; - } + if (mRenderDebugFeatureStack.empty()) + { + LL_ERRS() << "Depleted render feature stack." << LL_ENDL; + } - mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); - mRenderDebugFeatureStack.pop(); + mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); + mRenderDebugFeatureStack.pop(); } // static void LLPipeline::setRenderScriptedBeacons(bool val) { - sRenderScriptedBeacons = val; + sRenderScriptedBeacons = val; } // static void LLPipeline::toggleRenderScriptedBeacons() { - sRenderScriptedBeacons = !sRenderScriptedBeacons; + sRenderScriptedBeacons = !sRenderScriptedBeacons; } // static bool LLPipeline::getRenderScriptedBeacons() { - return sRenderScriptedBeacons; + return sRenderScriptedBeacons; } // static void LLPipeline::setRenderScriptedTouchBeacons(bool val) { - sRenderScriptedTouchBeacons = val; + sRenderScriptedTouchBeacons = val; } // static void LLPipeline::toggleRenderScriptedTouchBeacons() { - sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons; + sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons; } // static bool LLPipeline::getRenderScriptedTouchBeacons() { - return sRenderScriptedTouchBeacons; + return sRenderScriptedTouchBeacons; } // static void LLPipeline::setRenderMOAPBeacons(bool val) { - sRenderMOAPBeacons = val; + sRenderMOAPBeacons = val; } // static void LLPipeline::toggleRenderMOAPBeacons() { - sRenderMOAPBeacons = !sRenderMOAPBeacons; + sRenderMOAPBeacons = !sRenderMOAPBeacons; } // static bool LLPipeline::getRenderMOAPBeacons() { - return sRenderMOAPBeacons; + return sRenderMOAPBeacons; } // static void LLPipeline::setRenderPhysicalBeacons(bool val) { - sRenderPhysicalBeacons = val; + sRenderPhysicalBeacons = val; } // static void LLPipeline::toggleRenderPhysicalBeacons() { - sRenderPhysicalBeacons = !sRenderPhysicalBeacons; + sRenderPhysicalBeacons = !sRenderPhysicalBeacons; } // static bool LLPipeline::getRenderPhysicalBeacons() { - return sRenderPhysicalBeacons; + return sRenderPhysicalBeacons; } // static void LLPipeline::setRenderParticleBeacons(bool val) { - sRenderParticleBeacons = val; + sRenderParticleBeacons = val; } // static void LLPipeline::toggleRenderParticleBeacons() { - sRenderParticleBeacons = !sRenderParticleBeacons; + sRenderParticleBeacons = !sRenderParticleBeacons; } // static bool LLPipeline::getRenderParticleBeacons() { - return sRenderParticleBeacons; + return sRenderParticleBeacons; } // static void LLPipeline::setRenderSoundBeacons(bool val) { - sRenderSoundBeacons = val; + sRenderSoundBeacons = val; } // static void LLPipeline::toggleRenderSoundBeacons() { - sRenderSoundBeacons = !sRenderSoundBeacons; + sRenderSoundBeacons = !sRenderSoundBeacons; } // static bool LLPipeline::getRenderSoundBeacons() { - return sRenderSoundBeacons; + return sRenderSoundBeacons; } // static void LLPipeline::setRenderBeacons(bool val) { - sRenderBeacons = val; + sRenderBeacons = val; } // static void LLPipeline::toggleRenderBeacons() { - sRenderBeacons = !sRenderBeacons; + sRenderBeacons = !sRenderBeacons; } // static bool LLPipeline::getRenderBeacons() { - return sRenderBeacons; + return sRenderBeacons; } // static void LLPipeline::setRenderHighlights(bool val) { - sRenderHighlight = val; + sRenderHighlight = val; } // static void LLPipeline::toggleRenderHighlights() { - sRenderHighlight = !sRenderHighlight; + sRenderHighlight = !sRenderHighlight; } // static bool LLPipeline::getRenderHighlights() { - return sRenderHighlight; + return sRenderHighlight; } // static void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) { - sRenderHighlightTextureChannel = channel; + sRenderHighlightTextureChannel = channel; } LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection, - S32* face_hit) -{ - LLVector4a local_end = end; - - LLVector4a position; - - LLDrawable* drawable = NULL; - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL); - if (hit) - { - drawable = hit; - local_end = position; - } - } - } - - LLVOPartGroup* ret = NULL; - if (drawable) - { - //make sure we're returning an LLVOPartGroup - llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP); - ret = (LLVOPartGroup*) drawable->getVObj().get(); - } - - if (intersection) - { - *intersection = position; - } - - return ret; + S32* face_hit) +{ + LLVector4a local_end = end; + + LLVector4a position; + + LLDrawable* drawable = NULL; + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL); + if (hit) + { + drawable = hit; + local_end = position; + } + } + } + + LLVOPartGroup* ret = NULL; + if (drawable) + { + //make sure we're returning an LLVOPartGroup + llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP); + ret = (LLVOPartGroup*) drawable->getVObj().get(); + } + + if (intersection) + { + *intersection = position; + } + + return ret; } LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - bool pick_rigged, + bool pick_transparent, + bool pick_rigged, bool pick_unselectable, bool pick_reflection_probe, - S32* face_hit, + S32* face_hit, S32* gltf_node_hit, S32* gltf_primitive_hit, - LLVector4a* intersection, // return the intersection point - LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point - ) + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point + ) { - LLDrawable* drawable = NULL; + LLDrawable* drawable = NULL; - LLVector4a local_end = end; + LLVector4a local_end = end; - LLVector4a position; + LLVector4a position; - sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; + sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - if ((j == LLViewerRegion::PARTITION_VOLUME) || - (j == LLViewerRegion::PARTITION_BRIDGE) || + for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) + { + if ((j == LLViewerRegion::PARTITION_VOLUME) || + (j == LLViewerRegion::PARTITION_BRIDGE) || (j == LLViewerRegion::PARTITION_AVATAR) || // for attachments - (j == LLViewerRegion::PARTITION_CONTROL_AV) || - (j == LLViewerRegion::PARTITION_TERRAIN) || - (j == LLViewerRegion::PARTITION_TREE) || - (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent); - if (hit) - { - drawable = hit; - local_end = position; - } - } - } - } - } - - if (!sPickAvatar) - { - //save hit info in case we need to restore - //due to attachment override - LLVector4a local_normal; - LLVector4a local_tangent; - LLVector2 local_texcoord; - S32 local_face_hit = -1; - - if (face_hit) - { - local_face_hit = *face_hit; - } - if (tex_coord) - { - local_texcoord = *tex_coord; - } - if (tangent) - { - local_tangent = *tangent; - } - else - { - local_tangent.clear(); - } - if (normal) - { - local_normal = *normal; - } - else - { - local_normal.clear(); - } - - const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; - - //check against avatars - sPickAvatar = true; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent); - if (hit) - { - LLVector4a delta; - delta.setSub(position, local_end); - - if (!drawable || - !drawable->getVObj()->isAttachment() || - delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST) - { //avatar overrides if previously hit drawable is not an attachment or - //attachment is far enough away from detected intersection - drawable = hit; - local_end = position; - } - else - { //prioritize attachments over avatars - position = local_end; - - if (face_hit) - { - *face_hit = local_face_hit; - } - if (tex_coord) - { - *tex_coord = local_texcoord; - } - if (tangent) - { - *tangent = local_tangent; - } - if (normal) - { - *normal = local_normal; - } - } - } - } - } - } - - //check all avatar nametags (silly, isn't it?) - for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); - ++iter) - { - LLVOAvatar* av = (LLVOAvatar*) *iter; - if (av->mNameText.notNull() - && av->mNameText->lineSegmentIntersect(start, local_end, position)) - { - drawable = av->mDrawable; - local_end = position; - } - } + (j == LLViewerRegion::PARTITION_CONTROL_AV) || + (j == LLViewerRegion::PARTITION_TERRAIN) || + (j == LLViewerRegion::PARTITION_TREE) || + (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now + { + LLSpatialPartition* part = region->getSpatialPartition(j); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent); + if (hit) + { + drawable = hit; + local_end = position; + } + } + } + } + } + + if (!sPickAvatar) + { + //save hit info in case we need to restore + //due to attachment override + LLVector4a local_normal; + LLVector4a local_tangent; + LLVector2 local_texcoord; + S32 local_face_hit = -1; + + if (face_hit) + { + local_face_hit = *face_hit; + } + if (tex_coord) + { + local_texcoord = *tex_coord; + } + if (tangent) + { + local_tangent = *tangent; + } + else + { + local_tangent.clear(); + } + if (normal) + { + local_normal = *normal; + } + else + { + local_normal.clear(); + } + + const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; + + //check against avatars + sPickAvatar = true; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent); + if (hit) + { + LLVector4a delta; + delta.setSub(position, local_end); + + if (!drawable || + !drawable->getVObj()->isAttachment() || + delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST) + { //avatar overrides if previously hit drawable is not an attachment or + //attachment is far enough away from detected intersection + drawable = hit; + local_end = position; + } + else + { //prioritize attachments over avatars + position = local_end; + + if (face_hit) + { + *face_hit = local_face_hit; + } + if (tex_coord) + { + *tex_coord = local_texcoord; + } + if (tangent) + { + *tangent = local_tangent; + } + if (normal) + { + *normal = local_normal; + } + } + } + } + } + } + + //check all avatar nametags (silly, isn't it?) + for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); + ++iter) + { + LLVOAvatar* av = (LLVOAvatar*) *iter; + if (av->mNameText.notNull() + && av->mNameText->lineSegmentIntersect(start, local_end, position)) + { + drawable = av->mDrawable; + local_end = position; + } + } S32 node_hit = -1; S32 primitive_hit = -1; @@ -6468,96 +6468,96 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, { *gltf_node_hit = node_hit; } - + if (gltf_primitive_hit) { *gltf_primitive_hit = primitive_hit; } - if (intersection) - { - *intersection = position; - } + if (intersection) + { + *intersection = position; + } - return drawable ? drawable->getVObj().get() : NULL; + return drawable ? drawable->getVObj().get() : NULL; } LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - S32* face_hit, - LLVector4a* intersection, // return the intersection point - LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point - ) -{ - LLDrawable* drawable = NULL; - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - bool toggle = false; - if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - toggle = true; - } - - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); - if (part) - { - LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, FALSE, face_hit, intersection, tex_coord, normal, tangent); - if (hit) - { - drawable = hit; - } - } - - if (toggle) - { - toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } - } - return drawable ? drawable->getVObj().get() : NULL; + bool pick_transparent, + S32* face_hit, + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point + ) +{ + LLDrawable* drawable = NULL; + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + bool toggle = false; + if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + toggle = true; + } + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); + if (part) + { + LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, FALSE, face_hit, intersection, tex_coord, normal, tangent); + if (hit) + { + drawable = hit; + } + } + + if (toggle) + { + toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + } + return drawable ? drawable->getVObj().get() : NULL; } LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) { - if (vobj) - { - LLViewerRegion* region = vobj->getRegion(); - if (region) - { - return region->getSpatialPartition(vobj->getPartitionType()); - } - } - return NULL; + if (vobj) + { + LLViewerRegion* region = vobj->getRegion(); + if (region) + { + return region->getSpatialPartition(vobj->getPartitionType()); + } + } + return NULL; } void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { - if (!drawable) - { - return; - } + if (!drawable) + { + return; + } - for (S32 i = 0; i < drawable->getNumFaces(); i++) - { - LLFace* facep = drawable->getFace(i); - if (facep) - { - facep->clearVertexBuffer(); - } - } + for (S32 i = 0; i < drawable->getNumFaces(); i++) + { + LLFace* facep = drawable->getFace(i); + if (facep) + { + facep->clearVertexBuffer(); + } + } } void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool rigged) { - assertInitialized(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; if (rigged) { @@ -6569,7 +6569,7 @@ void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool } gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + gGLLastMatrix = NULL; } void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged) @@ -6681,9 +6681,9 @@ void LLPipeline::renderAlphaObjects(bool rigged) // Currently only used for shadows -Cosmic,2023-04-19 void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged) { - assertInitialized(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; if (rigged) { mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); @@ -6692,16 +6692,16 @@ void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, { mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); } - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; } // Currently only used for shadows -Cosmic,2023-04-19 void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged) { - assertInitialized(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; if (rigged) { mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); @@ -6710,116 +6710,116 @@ void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batc { mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); } - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; } void apply_cube_face_rotation(U32 face) { - switch (face) - { - case 0: - gGL.rotatef(90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); - break; - case 2: - gGL.rotatef(-90.f, 1, 0, 0); - break; - case 4: - gGL.rotatef(180.f, 0, 1, 0); - gGL.rotatef(180.f, 0, 0, 1); - break; - case 1: - gGL.rotatef(-90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); - break; - case 3: - gGL.rotatef(90, 1, 0, 0); - break; - case 5: - gGL.rotatef(180, 0, 0, 1); - break; - } -} - -void validate_framebuffer_object() -{ - GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE: - //framebuffer OK, no error. - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - // frame buffer not OK: probably means unsupported depth buffer format - LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL; - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - // frame buffer not OK: probably means unsupported depth buffer format - LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL; - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - /* choose different formats */ - LL_ERRS() << "Framebuffer unsupported." << LL_ENDL; - break; - default: - LL_ERRS() << "Unknown framebuffer status." << LL_ENDL; - break; - } -} - -void LLPipeline::bindScreenToTexture() -{ - + switch (face) + { + case 0: + gGL.rotatef(90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); + break; + case 2: + gGL.rotatef(-90.f, 1, 0, 0); + break; + case 4: + gGL.rotatef(180.f, 0, 1, 0); + gGL.rotatef(180.f, 0, 0, 1); + break; + case 1: + gGL.rotatef(-90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); + break; + case 3: + gGL.rotatef(90, 1, 0, 0); + break; + case 5: + gGL.rotatef(180, 0, 0, 1); + break; + } +} + +void validate_framebuffer_object() +{ + GLenum status; + status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE: + //framebuffer OK, no error. + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + // frame buffer not OK: probably means unsupported depth buffer format + LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL; + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + // frame buffer not OK: probably means unsupported depth buffer format + LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + /* choose different formats */ + LL_ERRS() << "Framebuffer unsupported." << LL_ENDL; + break; + default: + LL_ERRS() << "Unknown framebuffer status." << LL_ENDL; + break; + } +} + +void LLPipeline::bindScreenToTexture() +{ + } static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) { - dst->bindTarget(); - gDeferredBufferVisualProgram.bind(); - gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex); + dst->bindTarget(); + gDeferredBufferVisualProgram.bind(); + gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex); - static LLStaticHashedString mipLevel("mipLevel"); - if (RenderBufferVisualization != 4) - gDeferredBufferVisualProgram.uniform1f(mipLevel, 0); - else - gDeferredBufferVisualProgram.uniform1f(mipLevel, 8); + static LLStaticHashedString mipLevel("mipLevel"); + if (RenderBufferVisualization != 4) + gDeferredBufferVisualProgram.uniform1f(mipLevel, 0); + else + gDeferredBufferVisualProgram.uniform1f(mipLevel, 8); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gDeferredBufferVisualProgram.unbind(); - dst->flush(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredBufferVisualProgram.unbind(); + dst->flush(); } void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) { - // luminance sample and mipmap generation - { - LL_PROFILE_GPU_ZONE("luminance sample"); + // luminance sample and mipmap generation + { + LL_PROFILE_GPU_ZONE("luminance sample"); - dst->bindTarget(); + dst->bindTarget(); - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); - gLuminanceProgram.bind(); + gLuminanceProgram.bind(); static LLCachedControl diffuse_luminance_scale(gSavedSettings, "RenderDiffuseLuminanceScale", 1.0f); - S32 channel = 0; - channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_POINT); - } + S32 channel = 0; + channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_POINT); + } - channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); - if (channel > -1) - { - mGlow[1].bindTexture(0, channel); - } + channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); + if (channel > -1) + { + mGlow[1].bindTexture(0, channel); + } channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_NORMAL); if (channel > -1) @@ -6831,129 +6831,129 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) static LLStaticHashedString diffuse_luminance_scale_s("diffuse_luminance_scale"); gLuminanceProgram.uniform1f(diffuse_luminance_scale_s, diffuse_luminance_scale); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst->flush(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + dst->flush(); - // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance" - // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader - gLuminanceProgram.unbind(); - } + // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance" + // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader + gLuminanceProgram.unbind(); + } } void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history) { - // exposure sample - { - LL_PROFILE_GPU_ZONE("exposure sample"); - - if (use_history) - { - // copy last frame's exposure into mLastExposure - mLastExposure.bindTarget(); - gCopyProgram.bind(); - gGL.getTexUnit(0)->bind(dst); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - mLastExposure.flush(); - } - - dst->bindTarget(); - - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - - LLGLSLShader* shader; - if (use_history) - { - shader = &gExposureProgram; - } - else - { - shader = &gExposureProgramNoFade; - } - - shader->bind(); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); - } - - if (use_history) - { - channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP); - if (channel > -1) - { - mLastExposure.bindTexture(0, channel); - } - } - - static LLStaticHashedString dt("dt"); - static LLStaticHashedString noiseVec("noiseVec"); - static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); - static LLCachedControl dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); - static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - - LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); - - F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); - F32 exp_min = 1.f; - F32 exp_max = 1.f; - - if (probe_ambiance > 0.f) - { - F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f; - - if (hdr_scale > 1.f) - { - exp_min = 1.f / hdr_scale; - exp_max = hdr_scale; - } - } - shader->uniform1f(dt, gFrameIntervalSeconds); - shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); - shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - if (use_history) - { - gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage()); - } - shader->unbind(); - dst->flush(); - } + // exposure sample + { + LL_PROFILE_GPU_ZONE("exposure sample"); + + if (use_history) + { + // copy last frame's exposure into mLastExposure + mLastExposure.bindTarget(); + gCopyProgram.bind(); + gGL.getTexUnit(0)->bind(dst); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + mLastExposure.flush(); + } + + dst->bindTarget(); + + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + + LLGLSLShader* shader; + if (use_history) + { + shader = &gExposureProgram; + } + else + { + shader = &gExposureProgramNoFade; + } + + shader->bind(); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); + } + + if (use_history) + { + channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP); + if (channel > -1) + { + mLastExposure.bindTexture(0, channel); + } + } + + static LLStaticHashedString dt("dt"); + static LLStaticHashedString noiseVec("noiseVec"); + static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); + static LLCachedControl dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + + LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); + + F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); + F32 exp_min = 1.f; + F32 exp_max = 1.f; + + if (probe_ambiance > 0.f) + { + F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f; + + if (hdr_scale > 1.f) + { + exp_min = 1.f / hdr_scale; + exp_max = hdr_scale; + } + } + shader->uniform1f(dt, gFrameIntervalSeconds); + shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); + shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + if (use_history) + { + gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage()); + } + shader->unbind(); + dst->flush(); + } } extern LLPointer gEXRImage; void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { - dst->bindTarget(); - // gamma correct lighting - { - LL_PROFILE_GPU_ZONE("gamma correct"); + dst->bindTarget(); + // gamma correct lighting + { + LL_PROFILE_GPU_ZONE("gamma correct"); static LLCachedControl buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); - // Apply gamma correction to the frame here. + // Apply gamma correction to the frame here. static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable()); LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping) psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram : gDeferredPostGammaCorrectProgram; - + shader.bind(); - S32 channel = 0; + S32 channel = 0; shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); @@ -6961,73 +6961,73 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight()); - static LLCachedControl exposure(gSavedSettings, "RenderExposure", 1.f); + static LLCachedControl exposure(gSavedSettings, "RenderExposure", 1.f); - F32 e = llclamp(exposure(), 0.5f, 4.f); + F32 e = llclamp(exposure(), 0.5f, 4.f); - static LLStaticHashedString s_exposure("exposure"); + static LLStaticHashedString s_exposure("exposure"); static LLStaticHashedString aces_mix("aces_mix"); shader.uniform1f(s_exposure, e); shader.uniform1f(aces_mix, gEXRImage.notNull() ? 0.f : 0.3f); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gGL.getTexUnit(channel)->unbind(src->getUsage()); + gGL.getTexUnit(channel)->unbind(src->getUsage()); shader.unbind(); - } - dst->flush(); + } + dst->flush(); } -void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) { - if (RenderScreenSpaceReflections && !gCubeSnapshot) - { - LL_PROFILE_GPU_ZONE("ssr copy"); - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + if (RenderScreenSpaceReflections && !gCubeSnapshot) + { + LL_PROFILE_GPU_ZONE("ssr copy"); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - LLRenderTarget& depth_src = mRT->deferredScreen; + LLRenderTarget& depth_src = mRT->deferredScreen; - dst->bindTarget(); - dst->clear(); - gCopyDepthProgram.bind(); + dst->bindTarget(); + dst->clear(); + gCopyDepthProgram.bind(); - S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); - S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); + S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); + S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); - gGL.getTexUnit(diff_map)->bind(src); - gGL.getTexUnit(depth_map)->bind(&depth_src, true); + gGL.getTexUnit(diff_map)->bind(src); + gGL.getTexUnit(depth_map)->bind(&depth_src, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst->flush(); - } + dst->flush(); + } } -void LLPipeline::generateGlow(LLRenderTarget* src) +void LLPipeline::generateGlow(LLRenderTarget* src) { - if (sRenderGlow) - { - LL_PROFILE_GPU_ZONE("glow"); - mGlow[2].bindTarget(); - mGlow[2].clear(); - - gGlowExtractProgram.bind(); - F32 maxAlpha = RenderGlowMaxExtractAlpha; - F32 warmthAmount = RenderGlowWarmthAmount; - LLVector3 lumWeights = RenderGlowLumWeights; - LLVector3 warmthWeights = RenderGlowWarmthWeights; - - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], - lumWeights.mV[2]); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], - warmthWeights.mV[2]); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + if (sRenderGlow) + { + LL_PROFILE_GPU_ZONE("glow"); + mGlow[2].bindTarget(); + mGlow[2].clear(); + + gGlowExtractProgram.bind(); + F32 maxAlpha = RenderGlowMaxExtractAlpha; + F32 warmthAmount = RenderGlowWarmthAmount; + LLVector3 lumWeights = RenderGlowLumWeights; + LLVector3 warmthWeights = RenderGlowWarmthWeights; + + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], + lumWeights.mV[2]); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], + warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); if (RenderGlowNoise) { @@ -7042,406 +7042,406 @@ void LLPipeline::generateGlow(LLRenderTarget* src) mGlow[2].getHeight()); } - { - LLGLEnable blend_on(GL_BLEND); + { + LLGLEnable blend_on(GL_BLEND); + + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src); + + gGL.color4f(1, 1, 1, 1); + gPipeline.enableLightsFullbright(); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + mGlow[2].flush(); + } + + gGlowExtractProgram.unbind(); + + // power of two between 1 and 1024 + U32 glowResPow = RenderGlowResolutionPow; + const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); + + S32 kernel = RenderGlowIterations * 2; + F32 delta = RenderGlowWidth / glow_res; + // Use half the glow width if we have the res set to less than 9 so that it looks + // almost the same in either case. + if (glowResPow < 9) + { + delta *= 0.5f; + } + F32 strength = RenderGlowStrength; + + gGlowProgram.bind(); + gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); + + for (S32 i = 0; i < kernel; i++) + { + mGlow[i % 2].bindTarget(); + mGlow[i % 2].clear(); + + if (i == 0) + { + gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]); + } + else + { + gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]); + } + + if (i % 2 == 0) + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); + } + else + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); + } + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + mGlow[i % 2].flush(); + } + + gGlowProgram.unbind(); + + } + else // !sRenderGlow, skip the glow ping-pong and just clear the result target + { + mGlow[1].bindTarget(); + mGlow[1].clear(); + mGlow[1].flush(); + } +} + +void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) +{ + { + llassert(!gCubeSnapshot); + bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete(); + LLGLSLShader* shader = &gGlowCombineProgram; + + S32 width = dst->getWidth(); + S32 height = dst->getHeight(); + + // Present everything. + if (multisample) + { + LL_PROFILE_GPU_ZONE("aa"); + // bake out texture2D with RGBL for FXAA shader + mRT->fxaaBuffer.bindTarget(); + + shader = &gGlowCombineFXAAProgram; + shader->bind(); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } + + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + shader->unbind(); - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + mRT->fxaaBuffer.flush(); - gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src); + dst->bindTarget(); + shader = &gFXAAProgram; + shader->bind(); - gGL.color4f(1, 1, 1, 1); - gPipeline.enableLightsFullbright(); + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); + if (channel > -1) + { + mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - mGlow[2].flush(); - } + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - gGlowExtractProgram.unbind(); + F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth(); + F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, + 0.5f / width * scale_x, 0.5f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, + 2.f / width * scale_x, 2.f / height * scale_y); - // power of two between 1 and 1024 - U32 glowResPow = RenderGlowResolutionPow; - const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); + gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); - S32 kernel = RenderGlowIterations * 2; - F32 delta = RenderGlowWidth / glow_res; - // Use half the glow width if we have the res set to less than 9 so that it looks - // almost the same in either case. - if (glowResPow < 9) - { - delta *= 0.5f; - } - F32 strength = RenderGlowStrength; + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - gGlowProgram.bind(); - gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); - - for (S32 i = 0; i < kernel; i++) - { - mGlow[i % 2].bindTarget(); - mGlow[i % 2].clear(); - - if (i == 0) - { - gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]); - } - else - { - gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]); - } - - if (i % 2 == 0) - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); - } - else - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); - } - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - mGlow[i % 2].flush(); - } - - gGlowProgram.unbind(); - - } - else // !sRenderGlow, skip the glow ping-pong and just clear the result target - { - mGlow[1].bindTarget(); - mGlow[1].clear(); - mGlow[1].flush(); - } -} - -void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) -{ - { - llassert(!gCubeSnapshot); - bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete(); - LLGLSLShader* shader = &gGlowCombineProgram; - - S32 width = dst->getWidth(); - S32 height = dst->getHeight(); - - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - // bake out texture2D with RGBL for FXAA shader - mRT->fxaaBuffer.bindTarget(); - - shader = &gGlowCombineFXAAProgram; - shader->bind(); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - shader->unbind(); - - mRT->fxaaBuffer.flush(); - - dst->bindTarget(); - shader = &gFXAAProgram; - shader->bind(); - - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); - if (channel > -1) - { - mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } - - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth(); - F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, - 0.5f / width * scale_x, 0.5f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, - 2.f / width * scale_x, 2.f / height * scale_y); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); - gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - shader->unbind(); - dst->flush(); - } - else { - copyRenderTarget(src, dst); - } - } + shader->unbind(); + dst->flush(); + } + else { + copyRenderTarget(src, dst); + } + } } void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) { - LL_PROFILE_GPU_ZONE("copyRenderTarget"); - dst->bindTarget(); + LL_PROFILE_GPU_ZONE("copyRenderTarget"); + dst->bindTarget(); - gDeferredPostNoDoFProgram.bind(); + gDeferredPostNoDoFProgram.bind(); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - { - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + { + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - gDeferredPostNoDoFProgram.unbind(); + gDeferredPostNoDoFProgram.unbind(); - dst->flush(); + dst->flush(); } void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) { - // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer. + // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer. - dst->bindTarget(); + dst->bindTarget(); - { + { - gGlowCombineProgram.bind(); + gGlowCombineProgram.bind(); - gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); - gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); + gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); + gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - dst->flush(); + dst->flush(); } void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) { - { - bool dof_enabled = - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField && - !gCubeSnapshot; - - gViewerWindow->setup3DViewport(); - - if (dof_enabled) - { - LL_PROFILE_GPU_ZONE("dof"); - LLGLDisable blend(GL_BLEND); - - // depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; - - LLVector3 focus_point; - - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } - - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, nullptr, nullptr, nullptr, &result); - - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } - - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) - { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); - } - - if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) - { // large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { // currently in a transition, continue interpolating - transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); - - F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; - current_distance = start_distance + (target_distance - start_distance) * t; - } - else - { // small or no change, just snap to target distance - current_distance = target_distance; - } - - // convert to mm - F32 subject_distance = current_distance * 1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; - - F32 fov = LLViewerCamera::getInstance()->getView(); - - const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - - // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); - - F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - - F32 focal_length = dv / (2 * tanf(fov / 2.f)); - - // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // - - F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); - blur_constant /= 1000.f; // convert to meters for shader - F32 magnification = focal_length / (subject_distance - focal_length); - - { // build diffuse+bloom+CoF - mRT->deferredLight.bindTarget(); - - gDeferredCoFProgram.bind(); - - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - - gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); - gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gDeferredCoFProgram.unbind(); - mRT->deferredLight.flush(); - } - - U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); - U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); - - { // perform DoF sampling at half-res (preserve alpha channel) - src->bindTarget(); - glViewport(0, 0, dof_width, dof_height); - - gGL.setColorMask(true, false); - - gDeferredPostProgram.bind(); - gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT); - - gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - gDeferredPostProgram.unbind(); - - src->flush(); - gGL.setColorMask(true, true); - } - - { // combine result based on alpha - - dst->bindTarget(); - if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete()) + { + bool dof_enabled = + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField && + !gCubeSnapshot; + + gViewerWindow->setup3DViewport(); + + if (dof_enabled) + { + LL_PROFILE_GPU_ZONE("dof"); + LLGLDisable blend(GL_BLEND); + + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, nullptr, nullptr, nullptr, &result); + + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } + } + } + + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + } + + if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) + { // large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { // currently in a transition, continue interpolating + transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; + current_distance = start_distance + (target_distance - start_distance) * t; + } + else + { // small or no change, just snap to target distance + current_distance = target_distance; + } + + // convert to mm + F32 subject_distance = current_distance * 1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = CameraFieldOfView * F_PI / 180.f; + + // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); + + F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); + + F32 focal_length = dv / (2 * tanf(fov / 2.f)); + + // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); + blur_constant /= 1000.f; // convert to meters for shader + F32 magnification = focal_length / (subject_distance - focal_length); + + { // build diffuse+bloom+CoF + mRT->deferredLight.bindTarget(); + + gDeferredCoFProgram.bind(); + + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + + gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); + gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredCoFProgram.unbind(); + mRT->deferredLight.flush(); + } + + U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); + + { // perform DoF sampling at half-res (preserve alpha channel) + src->bindTarget(); + glViewport(0, 0, dof_width, dof_height); + + gGL.setColorMask(true, false); + + gDeferredPostProgram.bind(); + gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT); + + gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + gDeferredPostProgram.unbind(); + + src->flush(); + gGL.setColorMask(true, true); + } + + { // combine result based on alpha + + dst->bindTarget(); + if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete()) { - glViewport(0, 0, dst->getWidth(), dst->getHeight()); - } - else + glViewport(0, 0, dst->getWidth(), dst->getHeight()); + } + else { - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - } - - gDeferredDoFCombineProgram.bind(); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT); - - gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - gDeferredDoFCombineProgram.unbind(); - - dst->flush(); - } - } - else - { - copyRenderTarget(src, dst); - } - } + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + } + + gDeferredDoFCombineProgram.bind(); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT); + + gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); + + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + gDeferredDoFCombineProgram.unbind(); + + dst->flush(); + } + } + else + { + copyRenderTarget(src, dst); + } + } } void LLPipeline::renderFinalize() @@ -7465,7 +7465,7 @@ void LLPipeline::renderFinalize() gGL.setColorMask(true, true); glClearColor(0, 0, 0, 0); - + copyScreenSpaceReflections(&mRT->screen, &mSceneMap); generateLuminance(&mRT->screen, &mLuminanceMap); @@ -7480,60 +7480,60 @@ void LLPipeline::renderFinalize() combineGlow(&mPostMap, &mRT->screen); - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - renderDoF(&mRT->screen, &mPostMap); - - applyFXAA(&mPostMap, &mRT->screen); - LLRenderTarget* finalBuffer = &mRT->screen; - if (RenderBufferVisualization > -1) - { - finalBuffer = &mPostMap; - switch (RenderBufferVisualization) - { - case 0: - case 1: - case 2: - case 3: - visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization); - break; - case 4: - visualizeBuffers(&mLuminanceMap, finalBuffer, 0); - default: - break; - } - } - - // Present the screen target. - - gDeferredPostNoDoFProgram.bind(); - - // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems. - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredPostNoDoFProgram.unbind(); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + renderDoF(&mRT->screen, &mPostMap); - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + applyFXAA(&mPostMap, &mRT->screen); + LLRenderTarget* finalBuffer = &mRT->screen; + if (RenderBufferVisualization > -1) { - renderPhysicsDisplay(); + finalBuffer = &mPostMap; + switch (RenderBufferVisualization) + { + case 0: + case 1: + case 2: + case 3: + visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization); + break; + case 4: + visualizeBuffers(&mLuminanceMap, finalBuffer, 0); + default: + break; + } } - /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot) - { // copy depth buffer from mRT->screen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0, + // Present the screen target. + + gDeferredPostNoDoFProgram.bind(); + + // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems. + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + gDeferredPostNoDoFProgram.unbind(); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + renderPhysicsDisplay(); + } + + /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot) + { // copy depth buffer from mRT->screen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); }*/ @@ -7612,28 +7612,28 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ LLRenderTarget* deferred_target = &mRT->deferredScreen; LLRenderTarget* deferred_light_target = &mRT->deferredLight; - shader.bind(); - S32 channel = 0; + shader.bind(); + S32 channel = 0; channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); - if (channel > -1) - { + if (channel > -1) + { deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0] gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } + } channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); - if (channel > -1) - { + if (channel > -1) + { deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1] gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } + } channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); - if (channel > -1) - { + if (channel > -1) + { deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2] gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } + } channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); if (channel > -1) @@ -7664,32 +7664,32 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1) { - shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], - (F32) gGLViewport[1], - (F32) gGLViewport[2], - (F32) gGLViewport[3]); - } + shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], + (F32) gGLViewport[1], + (F32) gGLViewport[2], + (F32) gGLViewport[3]); + } if (sReflectionRender && !shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX)) { - shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m); + shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m); } - channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE); - if (channel > -1) - { + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE); + if (channel > -1) + { gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } bindLightFunc(shader); - stop_glerror(); + stop_glerror(); light_target = light_target ? light_target : deferred_light_target; channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage()); - if (channel > -1) - { + if (channel > -1) + { if (light_target->isComplete()) { light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); @@ -7698,28 +7698,28 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ { gGL.getTexUnit(channel)->bindFast(LLViewerFetchedTexture::sWhiteImagep); } - } + } - stop_glerror(); + stop_glerror(); bindShadowMaps(shader); - stop_glerror(); + stop_glerror(); - F32 mat[16*6]; - for (U32 i = 0; i < 16; i++) - { - mat[i] = mSunShadowMatrix[0].m[i]; - mat[i+16] = mSunShadowMatrix[1].m[i]; - mat[i+32] = mSunShadowMatrix[2].m[i]; - mat[i+48] = mSunShadowMatrix[3].m[i]; - mat[i+64] = mSunShadowMatrix[4].m[i]; - mat[i+80] = mSunShadowMatrix[5].m[i]; - } + F32 mat[16*6]; + for (U32 i = 0; i < 16; i++) + { + mat[i] = mSunShadowMatrix[0].m[i]; + mat[i+16] = mSunShadowMatrix[1].m[i]; + mat[i+32] = mSunShadowMatrix[2].m[i]; + mat[i+48] = mSunShadowMatrix[3].m[i]; + mat[i+64] = mSunShadowMatrix[4].m[i]; + mat[i+80] = mSunShadowMatrix[5].m[i]; + } - shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); - stop_glerror(); + stop_glerror(); if (!LLPipeline::sReflectionProbesEnabled) { @@ -7781,55 +7781,55 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ { shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); } - shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash); - shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); - shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize); - - shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale); - shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale); - - F32 ssao_factor = RenderSSAOFactor; - shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor); - shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor); - - LLVector3 ssao_effect = RenderSSAOEffect; - F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0; - F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0; - // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by - // value factor, and scales remainder by saturation factor - F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag, - matrix_nondiag, matrix_diag, matrix_nondiag, - matrix_nondiag, matrix_nondiag, matrix_diag}; - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); - - //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f; + shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash); + shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); + shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize); + + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale); + + F32 ssao_factor = RenderSSAOFactor; + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor); + + LLVector3 ssao_effect = RenderSSAOEffect; + F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0; + F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0; + // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by + // value factor, and scales remainder by saturation factor + F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag, + matrix_nondiag, matrix_diag, matrix_nondiag, + matrix_nondiag, matrix_nondiag, matrix_diag}; + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); + + //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f; F32 shadow_bias = RenderShadowBias + shadow_bias_error; shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->getHeight()); - shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error); + shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f); + shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error); shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, shadow_bias); - shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); - shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); + shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); + shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); - shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); + shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV); - shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight()); - shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight()); - shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); - shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); - + shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight()); + shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight()); + shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); + shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); + shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLDeltaModelView); shader.uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLInverseDeltaModelView); shader.uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0); - if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) - { + if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) + { glh::matrix4f norm_mat = get_current_modelview().inverse().transpose(); - shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); - } + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); + } // auto adjust legacy sun color if needed static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); @@ -7850,18 +7850,18 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ LLColor3 pow3f(LLColor3 v, F32 f) { - v.mV[0] = powf(v.mV[0], f); - v.mV[1] = powf(v.mV[1], f); - v.mV[2] = powf(v.mV[2], f); - return v; + v.mV[0] = powf(v.mV[0], f); + v.mV[1] = powf(v.mV[1], f); + v.mV[2] = powf(v.mV[2], f); + return v; } LLVector4 pow4fsrgb(LLVector4 v, F32 f) { - v.mV[0] = powf(v.mV[0], f); - v.mV[1] = powf(v.mV[1], f); - v.mV[2] = powf(v.mV[2], f); - return v; + v.mV[0] = powf(v.mV[0], f); + v.mV[1] = powf(v.mV[1], f); + v.mV[2] = powf(v.mV[2], f); + return v; } void LLPipeline::renderDeferredLighting() @@ -7888,7 +7888,7 @@ void LLPipeline::renderDeferredLighting() { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); LLViewerCamera *camera = LLViewerCamera::getInstance(); - + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); @@ -8040,14 +8040,14 @@ void LLPipeline::renderDeferredLighting() static LLCachedControl ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f); static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale"); static LLStaticHashedString ssao_max_str("ssao_irradiance_max"); - + soften_shader.uniform1f(ssao_scale_str, ssao_scale); soften_shader.uniform1f(ssao_max_str, ssao_max); LLEnvironment &environment = LLEnvironment::instance(); soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); - + soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); { @@ -8341,7 +8341,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, END_RENDER_TYPES); @@ -8422,7 +8422,7 @@ void LLPipeline::doAtmospherics() // full screen blit mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - + unbindDeferredShader(haze_shader); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -8461,1489 +8461,1489 @@ void LLPipeline::doWaterHaze() gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst.flush(); - mRT->screen.bindTarget(); - } + dst.flush(); + mRT->screen.bindTarget(); + } + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA); + + gGL.setColorMask(true, true); + + // apply haze + LLGLSLShader& haze_shader = gHazeWaterProgram; + + LL_PROFILE_GPU_ZONE("haze"); + bindDeferredShader(haze_shader, nullptr, &mWaterDis); + + haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); + + static LLStaticHashedString above_water_str("above_water"); + haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); + + if (LLPipeline::sUnderWaterRender) + { + LLGLDepthTest depth(GL_FALSE); + + // full screen blit + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + else + { + //render water patches like LLDrawPoolWater does + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + if (mWaterPool) + { + mWaterPool->pushFaceGeometry(); + } + } + + unbindDeferredShader(haze_shader); + + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } +} + +void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) +{ + //construct frustum + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 params = volume->getSpotLightParams(); + + F32 fov = params.mV[0]; + F32 focus = params.mV[1]; + + LLVector3 pos = drawablep->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + LLVector3 scale = volume->getScale(); + + //get near clip plane + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = pos+at_axis; + at_axis.normVec(); + + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + + LLVector3 origin = np - at_axis*dist; + + //matrix from volume space to agent space + LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + + glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); + glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; + + glh::matrix4f screen_to_light = light_to_screen.inverse(); + + F32 s = volume->getLightRadius()*1.5f; + F32 near_clip = dist; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = s+dist-scale.mV[VZ]; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + glh::vec3f p1(0, 0, -(near_clip+0.01f)); + glh::vec3f p2(0, 0, -(near_clip+1.f)); + + glh::vec3f screen_origin(0, 0, 0); + + light_to_screen.mult_matrix_vec(p1); + light_to_screen.mult_matrix_vec(p2); + light_to_screen.mult_matrix_vec(screen_origin); + + glh::vec3f n = p2-p1; + n.normalize(); + + F32 proj_range = far_clip - near_clip; + glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); + screen_to_light = trans * light_proj * screen_to_light; + shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); + shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); + shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); + shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); + S32 s_idx = -1; + + for (U32 i = 0; i < 2; i++) + { + if (mShadowSpotLight[i] == drawablep) + { + s_idx = i; + } + } + + shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx); + + if (s_idx >= 0) + { + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]); + } + else + { + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); + } + + // make sure we're not already targeting the same spot light with both shadow maps + llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull()); + + if (!gCubeSnapshot) + { + LLDrawable* potential = drawablep; + //determine if this light is higher priority than one of the existing spot shadows + F32 m_pri = volume->getSpotLightPriority(); + + for (U32 i = 0; i < 2; i++) + { + F32 pri = 0.f; + + if (mTargetShadowSpotLight[i].notNull()) + { + pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); + } + + if (m_pri > pri) + { + LLDrawable* temp = mTargetShadowSpotLight[i]; + mTargetShadowSpotLight[i] = potential; + potential = temp; + m_pri = pri; + } + } + } + + // make sure we didn't end up targeting the same spot light with both shadow maps + llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull()); + + LLViewerTexture* img = volume->getLightTexture(); + + if (img == NULL) + { + img = LLViewerFetchedTexture::sWhiteImagep; + } + + S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + + if (channel > -1) + { + if (img) + { + gGL.getTexUnit(channel)->bind(img); + + F32 lod_range = logf(img->getWidth())/logf(2.f); + + shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus); + shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } + } + +} + +void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) +{ + LLRenderTarget* deferred_target = &mRT->deferredScreen; + LLRenderTarget* deferred_light_target = &mRT->deferredLight; + + stop_glerror(); + shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT); + //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage()); + shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM); + + for (U32 i = 0; i < 4; i++) + { + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); + } + } + + for (U32 i = 4; i < 6; i++) + { + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); + } + } + + shader.disableTexture(LLShaderMgr::DEFERRED_NOISE); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC); + + if (!LLPipeline::sReflectionProbesEnabled) + { + S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + if (channel > -1) + { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map) + { + cube_map->disable(); + } + } + } + + unbindReflectionProbes(shader); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->activate(); + shader.unbind(); +} + +void LLPipeline::setEnvMat(LLGLSLShader& shader) +{ + F32* m = gGLModelView; + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); +} + +void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) +{ + if (!sReflectionProbesEnabled) + { + return; + } + + S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + bool bound = false; + if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + { + mReflectionMapManager.mTexture->bind(channel); + bound = true; + } + + channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull()) + { + mReflectionMapManager.mIrradianceMaps->bind(channel); + bound = true; + } + + if (RenderMirrors) + { + channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); + if (channel > -1 && mHeroProbeManager.mTexture.notNull()) + { + mHeroProbeManager.mTexture->bind(channel); + bound = true; + } + } + + + if (bound) + { + mReflectionMapManager.setUniforms(); + + setEnvMat(shader); + } + + // reflection probe shaders generally sample the scene map as well for SSR + channel = shader.enableTexture(LLShaderMgr::SCENE_MAP); + if (channel > -1) + { + gGL.getTexUnit(channel)->bind(&mSceneMap); + } + + + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ITR_COUNT, RenderScreenSpaceReflectionIterations); + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_DIST_BIAS, RenderScreenSpaceReflectionDistanceBias); + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_RAY_STEP, RenderScreenSpaceReflectionRayStep); + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_GLOSSY_SAMPLES, RenderScreenSpaceReflectionGlossySamples); + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_REJECT_BIAS, RenderScreenSpaceReflectionDepthRejectBias); + mPoissonOffset++; + + if (mPoissonOffset > 128 - RenderScreenSpaceReflectionGlossySamples) + mPoissonOffset = 0; + + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_NOISE_SINE, mPoissonOffset); + shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ADAPTIVE_STEP_MULT, RenderScreenSpaceReflectionAdaptiveStepMultiplier); + + channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH); + if (channel > -1) + { + gGL.getTexUnit(channel)->bind(&mSceneMap, true); + } + + +} + +void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader) +{ + S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP); + if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + { + mReflectionMapManager.mTexture->unbind(); + if (channel == 0) + { + gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE); + } + } +} + + +inline float sgn(float a) +{ + if (a > 0.0F) return (1.0F); + if (a < 0.0F) return (-1.0F); + return (0.0F); +} + +glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) +{ + glh::matrix4f ret; + + LLVector3 dirN; + LLVector3 upN; + LLVector3 lftN; + + lftN = dir % up; + lftN.normVec(); + + upN = lftN % dir; + upN.normVec(); + + dirN = dir; + dirN.normVec(); + + ret.m[ 0] = lftN[0]; + ret.m[ 1] = upN[0]; + ret.m[ 2] = -dirN[0]; + ret.m[ 3] = 0.f; + + ret.m[ 4] = lftN[1]; + ret.m[ 5] = upN[1]; + ret.m[ 6] = -dirN[1]; + ret.m[ 7] = 0.f; + + ret.m[ 8] = lftN[2]; + ret.m[ 9] = upN[2]; + ret.m[10] = -dirN[2]; + ret.m[11] = 0.f; + + ret.m[12] = -(lftN*pos); + ret.m[13] = -(upN*pos); + ret.m[14] = dirN*pos; + ret.m[15] = 1.f; + + return ret; +} + +glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) +{ + glh::matrix4f ret; + ret.m[ 0] = 2/(max[0]-min[0]); + ret.m[ 4] = 0; + ret.m[ 8] = 0; + ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); + + ret.m[ 1] = 0; + ret.m[ 5] = 2/(max[1]-min[1]); + ret.m[ 9] = 0; + ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); + + ret.m[ 2] = 0; + ret.m[ 6] = 0; + ret.m[10] = 2/(max[2]-min[2]); + ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); + + ret.m[ 3] = 0; + ret.m[ 7] = 0; + ret.m[11] = 0; + ret.m[15] = 1; + + return ret; +} + +static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_GEOM("Shadow Geom"); + +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); + +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool depth_clamp) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); + LL_PROFILE_GPU_ZONE("renderShadow"); + + LLPipeline::sShadowRender = true; + + // disable occlusion culling during shadow render + U32 saved_occlusion = sUseOcclusion; + sUseOcclusion = 0; + + // List of render pass types that use the prim volume as the shadow, + // ignoring textures. + static const U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY, + LLRenderPass::PASS_BUMP, + LLRenderPass::PASS_FULLBRIGHT_SHINY, + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_NORMSPEC_EMISSIVE + }; + + LLGLEnable cull(GL_CULL_FACE); + + //enable depth clamping if available + LLGLEnable clamp_depth(depth_clamp ? GL_DEPTH_CLAMP : 0); + + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS); + + updateCull(shadow_cam, result); + + stateSort(shadow_cam, result); + + //generate shadow map + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadMatrix(proj.m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadMatrix(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + stop_glerror(); + + struct CompareVertexBuffer + { + bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs) + { + return lhs->mVertexBuffer > rhs->mVertexBuffer; + } + }; + + + LLVertexBuffer::unbind(); + for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged + { + bool rigged = j == 1; + gDeferredShadowProgram.bind(rigged); + + gGL.diffuseColor4f(1, 1, 1, 1); + + S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + + // if not using VSM, disable color writes + if (shadow_detail <= 2) + { + gGL.setColorMask(false, false); + } + + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); + LL_PROFILE_GPU_ZONE("shadow simple"); + gGL.getTexUnit(0)->disable(); + + for (U32 type : types) + { + renderObjects(type, false, false, rigged); + } + + renderGLTFObjects(LLRenderPass::PASS_GLTF_PBR, false, rigged); + + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + if (LLPipeline::sUseOcclusion > 1) + { // do occlusion culling against non-masked only to take advantage of hierarchical Z + doOcclusion(shadow_cam); + } + + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); + renderGeomShadow(shadow_cam); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); + LL_PROFILE_GPU_ZONE("shadow alpha"); + const S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0; + U32 target_width = LLRenderTarget::sCurResX; + + for (int i = 0; i < 2; ++i) + { + bool rigged = i == 1; + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); + LL_PROFILE_GPU_ZONE("shadow alpha masked"); + gDeferredShadowAlphaMaskProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, true, true, rigged); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); + LL_PROFILE_GPU_ZONE("shadow alpha blend"); + renderAlphaObjects(rigged); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); + LL_PROFILE_GPU_ZONE("shadow alpha masked"); + gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true, rigged); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); + LL_PROFILE_GPU_ZONE("shadow alpha grass"); + gDeferredTreeShadowProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF); + + if (i == 0) + { + renderObjects(LLRenderPass::PASS_GRASS, true); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha material"); + LL_PROFILE_GPU_ZONE("shadow alpha material"); + renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, true, false, rigged); + } + } + } + + for (int i = 0; i < 2; ++i) + { + bool rigged = i == 1; + gDeferredShadowGLTFAlphaMaskProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + + U32 type = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK; + + if (rigged) + { + mAlphaMaskPool->pushRiggedGLTFBatches(type + 1); + } + else + { + mAlphaMaskPool->pushGLTFBatches(type); + } + + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + } + } + + gDeferredShadowCubeProgram.bind(); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + gGL.setColorMask(true, true); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + gGLLastMatrix = NULL; + + // reset occlusion culling flag + sUseOcclusion = saved_occlusion; + LLPipeline::sShadowRender = false; +} - LLGLEnable blend(GL_BLEND); - gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA); +bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector& fp, LLVector3 light_dir) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + //get point cloud of intersection of frust and min, max - gGL.setColorMask(true, true); + if (getVisibleExtents(camera, min, max)) + { + return false; + } - // apply haze - LLGLSLShader& haze_shader = gHazeWaterProgram; + //get set of planes on bounding box + LLPlane bp[] = { + LLPlane(min, LLVector3(-1,0,0)), + LLPlane(min, LLVector3(0,-1,0)), + LLPlane(min, LLVector3(0,0,-1)), + LLPlane(max, LLVector3(1,0,0)), + LLPlane(max, LLVector3(0,1,0)), + LLPlane(max, LLVector3(0,0,1))}; + + //potential points + std::vector pp; + + //add corners of AABB + pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); + + //add corners of camera frustum + for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++) + { + pp.push_back(camera.mAgentFrustum[i]); + } - LL_PROFILE_GPU_ZONE("haze"); - bindDeferredShader(haze_shader, nullptr, &mWaterDis); - haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); + //bounding box line segments + U32 bs[] = + { + 0,1, + 1,3, + 3,2, + 2,0, + + 4,5, + 5,7, + 7,6, + 6,4, + + 0,4, + 1,5, + 3,7, + 2,6 + }; - static LLStaticHashedString above_water_str("above_water"); - haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); + for (U32 i = 0; i < 12; i++) + { //for each line segment in bounding box + for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++) + { //for each plane in camera frustum + const LLPlane& cp = camera.getAgentPlane(j); + const LLVector3& v1 = pp[bs[i*2+0]]; + const LLVector3& v2 = pp[bs[i*2+1]]; + LLVector3 n; + cp.getVector3(n); - if (LLPipeline::sUnderWaterRender) - { - LLGLDepthTest depth(GL_FALSE); + LLVector3 line = v1-v2; - // full screen blit - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - else - { - //render water patches like LLDrawPoolWater does - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + F32 t = d2/d1; - if (mWaterPool) + if (t > 0.f && t < 1.f) { - mWaterPool->pushFaceGeometry(); + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); } } + } - unbindDeferredShader(haze_shader); + //camera frustum line segments + const U32 fs[] = + { + 0,1, + 1,2, + 2,3, + 3,0, + + 4,5, + 5,6, + 6,7, + 7,4, + + 0,4, + 1,5, + 2,6, + 3,7 + }; + for (U32 i = 0; i < 12; i++) + { + for (U32 j = 0; j < 6; ++j) + { + const LLVector3& v1 = pp[fs[i*2+0]+8]; + const LLVector3& v2 = pp[fs[i*2+1]+8]; + const LLPlane& cp = bp[j]; + LLVector3 n; + cp.getVector3(n); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } -} + LLVector3 line = v1-v2; -void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) -{ - //construct frustum - LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 params = volume->getSpotLightParams(); - - F32 fov = params.mV[0]; - F32 focus = params.mV[1]; - - LLVector3 pos = drawablep->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); - LLVector3 scale = volume->getScale(); - - //get near clip plane - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; - - LLVector3 np = pos+at_axis; - at_axis.normVec(); - - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - - LLVector3 origin = np - at_axis*dist; - - //matrix from volume space to agent space - LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); - - glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; - - glh::matrix4f screen_to_light = light_to_screen.inverse(); - - F32 s = volume->getLightRadius()*1.5f; - F32 near_clip = dist; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = s+dist-scale.mV[VZ]; - - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - glh::vec3f p1(0, 0, -(near_clip+0.01f)); - glh::vec3f p2(0, 0, -(near_clip+1.f)); - - glh::vec3f screen_origin(0, 0, 0); - - light_to_screen.mult_matrix_vec(p1); - light_to_screen.mult_matrix_vec(p2); - light_to_screen.mult_matrix_vec(screen_origin); - - glh::vec3f n = p2-p1; - n.normalize(); - - F32 proj_range = far_clip - near_clip; - glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); - screen_to_light = trans * light_proj * screen_to_light; - shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); - shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); - shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); - shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); - shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); - S32 s_idx = -1; - - for (U32 i = 0; i < 2; i++) - { - if (mShadowSpotLight[i] == drawablep) - { - s_idx = i; - } - } - - shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx); - - if (s_idx >= 0) - { - shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]); - } - else - { - shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); - } + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); - // make sure we're not already targeting the same spot light with both shadow maps - llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull()); + F32 t = d2/d1; - if (!gCubeSnapshot) - { - LLDrawable* potential = drawablep; - //determine if this light is higher priority than one of the existing spot shadows - F32 m_pri = volume->getSpotLightPriority(); - - for (U32 i = 0; i < 2; i++) - { - F32 pri = 0.f; - - if (mTargetShadowSpotLight[i].notNull()) - { - pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); - } - - if (m_pri > pri) - { - LLDrawable* temp = mTargetShadowSpotLight[i]; - mTargetShadowSpotLight[i] = potential; - potential = temp; - m_pri = pri; - } - } - } + if (t > 0.f && t < 1.f) + { + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); + } + } + } - // make sure we didn't end up targeting the same spot light with both shadow maps - llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull()); + LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), + max+LLVector3(0.05f,0.05f,0.05f) }; - LLViewerTexture* img = volume->getLightTexture(); + for (U32 i = 0; i < pp.size(); ++i) + { + bool found = true; + + const F32* p = pp[i].mV; - if (img == NULL) - { - img = LLViewerFetchedTexture::sWhiteImagep; - } + for (U32 j = 0; j < 3; ++j) + { + if (p[j] < ext[0].mV[j] || + p[j] > ext[1].mV[j]) + { + found = false; + break; + } + } - S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) + { + const LLPlane& cp = camera.getAgentPlane(j); + F32 dist = cp.dist(pp[i]); + if (dist > 0.05f) //point is above some plane, not contained + { + found = false; + break; + } + } - if (channel > -1) - { - if (img) - { - gGL.getTexUnit(channel)->bind(img); + if (found) + { + fp.push_back(pp[i]); + } + } - F32 lod_range = logf(img->getWidth())/logf(2.f); + if (fp.empty()) + { + return false; + } - shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus); - shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range); - shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); - } - } - + return true; } -void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) +void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) { - LLRenderTarget* deferred_target = &mRT->deferredScreen; - LLRenderTarget* deferred_light_target = &mRT->deferredLight; - - stop_glerror(); - shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT); - //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage()); - shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage()); - shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); - shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM); - - for (U32 i = 0; i < 4; i++) - { - if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); - } - } - - for (U32 i = 4; i < 6; i++) - { - if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); - } - } - - shader.disableTexture(LLShaderMgr::DEFERRED_NOISE); - shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC); - - if (!LLPipeline::sReflectionProbesEnabled) + if (obj && obj->getVolume()) { - S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - if (channel > -1) + for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if (cube_map) + renderHighlight(*iter, fade); + } + + LLDrawable* drawable = obj->mDrawable; + if (drawable) + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) { - cube_map->disable(); + LLFace* face = drawable->getFace(i); + if (face) + { + face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade)); + } } } } +} - unbindReflectionProbes(shader); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->activate(); - shader.unbind(); +LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i) +{ + llassert(i < 4); + return &mRT->shadow[i]; } -void LLPipeline::setEnvMat(LLGLSLShader& shader) +LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i) { - F32* m = gGLModelView; - - F32 mat[] = { m[0], m[1], m[2], - m[4], m[5], m[6], - m[8], m[9], m[10] }; - - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); + llassert(i < 2); + return &mSpotShadow[i]; } -void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render"); + +// helper class for disabling occlusion culling for the current stack frame +class LLDisableOcclusionCulling { - if (!sReflectionProbesEnabled) +public: + S32 mUseOcclusion; + + LLDisableOcclusionCulling() { - return; + mUseOcclusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; } - S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - bool bound = false; - if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + ~LLDisableOcclusionCulling() { - mReflectionMapManager.mTexture->bind(channel); - bound = true; + LLPipeline::sUseOcclusion = mUseOcclusion; } +}; - channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull()) +void LLPipeline::generateSunShadow(LLCamera& camera) +{ + if (!sRenderDeferred || RenderShadowDetail <= 0) { - mReflectionMapManager.mIrradianceMaps->bind(channel); - bound = true; + return; } - - if (RenderMirrors) + + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); + LL_PROFILE_GPU_ZONE("generateSunShadow"); + + LLDisableOcclusionCulling no_occlusion; + + bool skip_avatar_update = false; + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { - channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); - if (channel > -1 && mHeroProbeManager.mTexture.notNull()) - { - mHeroProbeManager.mTexture->bind(channel); - bound = true; - } + skip_avatar_update = true; } - - if (bound) + if (!skip_avatar_update) { - mReflectionMapManager.setUniforms(); + gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); + } - setEnvMat(shader); + F64 last_modelview[16]; + F64 last_projection[16]; + for (U32 i = 0; i < 16; i++) + { //store last_modelview of world camera + last_modelview[i] = gGLLastModelView[i]; + last_projection[i] = gGLLastProjection[i]; } - // reflection probe shaders generally sample the scene map as well for SSR - channel = shader.enableTexture(LLShaderMgr::SCENE_MAP); - if (channel > -1) + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER, + LLPipeline::RENDER_TYPE_ALPHA_POST_WATER, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_GLTF_PBR, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_MATERIAL, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_SPECMAP, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_NORMMAP, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_BUMP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SHINY_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_GLTF_PBR, + LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED, + LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED, + END_RENDER_TYPES); + + gGL.setColorMask(false, false); + + LLEnvironment& environment = LLEnvironment::instance(); + + //get sun view matrix + + //store current projection/modelview matrix + glh::matrix4f saved_proj = get_current_projection(); + glh::matrix4f saved_view = get_current_modelview(); + glh::matrix4f inv_view = saved_view.inverse(); + + glh::matrix4f view[6]; + glh::matrix4f proj[6]; + + LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); + + //put together a universal "near clip" plane for shadow frusta + LLPlane shadow_near_clip; { - gGL.getTexUnit(channel)->bind(&mSceneMap); + LLVector3 p = camera.getOrigin(); // gAgent.getPositionAgent(); + p += caster_dir * RenderFarClip*2.f; + shadow_near_clip.setVec(p, caster_dir); } - - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ITR_COUNT, RenderScreenSpaceReflectionIterations); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_DIST_BIAS, RenderScreenSpaceReflectionDistanceBias); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_RAY_STEP, RenderScreenSpaceReflectionRayStep); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_GLOSSY_SAMPLES, RenderScreenSpaceReflectionGlossySamples); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_REJECT_BIAS, RenderScreenSpaceReflectionDepthRejectBias); - mPoissonOffset++; + LLVector3 lightDir = -caster_dir; + lightDir.normVec(); - if (mPoissonOffset > 128 - RenderScreenSpaceReflectionGlossySamples) - mPoissonOffset = 0; + glh::vec3f light_dir(lightDir.mV); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_NOISE_SINE, mPoissonOffset); - shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ADAPTIVE_STEP_MULT, RenderScreenSpaceReflectionAdaptiveStepMultiplier); + //create light space camera matrix - channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH); - if (channel > -1) + LLVector3 at = lightDir; + + LLVector3 up = camera.getAtAxis(); + + if (fabsf(up*lightDir) > 0.75f) { - gGL.getTexUnit(channel)->bind(&mSceneMap, true); + up = camera.getUpAxis(); } + up.normVec(); + at.normVec(); -} -void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader) -{ - S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP); - if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + LLCamera main_camera = camera; + + F32 near_clip = 0.f; { - mReflectionMapManager.mTexture->unbind(); - if (channel == 0) + //get visible point cloud + std::vector fp; + + main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); + + LLVector3 min,max; + getVisiblePointCloud(main_camera,min,max,fp); + + if (fp.empty()) { - gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE); + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowCamera[0] = main_camera; + mShadowExtents[0][0] = min; + mShadowExtents[0][1] = max; + + mShadowFrustPoints[0].clear(); + mShadowFrustPoints[1].clear(); + mShadowFrustPoints[2].clear(); + mShadowFrustPoints[3].clear(); + } + popRenderTypeMask(); + + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } + + return; + } + + //get good split distances for frustum + for (U32 i = 0; i < fp.size(); ++i) + { + glh::vec3f v(fp[i].mV); + saved_view.mult_matrix_vec(v); + fp[i].setVec(v.v); } - } -} + min = fp[0]; + max = fp[0]; -inline float sgn(float a) -{ - if (a > 0.0F) return (1.0F); - if (a < 0.0F) return (-1.0F); - return (0.0F); -} + //get camera space bounding box + for (U32 i = 1; i < fp.size(); ++i) + { + update_min_max(min, max, fp[i]); + } -glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) -{ - glh::matrix4f ret; + near_clip = llclamp(-max.mV[2], 0.01f, 4.0f); + F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f); - LLVector3 dirN; - LLVector3 upN; - LLVector3 lftN; + //far_clip = llmin(far_clip, 128.f); + far_clip = llmin(far_clip, camera.getFar()); - lftN = dir % up; - lftN.normVec(); - - upN = lftN % dir; - upN.normVec(); - - dirN = dir; - dirN.normVec(); + F32 range = far_clip-near_clip; - ret.m[ 0] = lftN[0]; - ret.m[ 1] = upN[0]; - ret.m[ 2] = -dirN[0]; - ret.m[ 3] = 0.f; + LLVector3 split_exp = RenderShadowSplitExponent; - ret.m[ 4] = lftN[1]; - ret.m[ 5] = upN[1]; - ret.m[ 6] = -dirN[1]; - ret.m[ 7] = 0.f; + F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - ret.m[ 8] = lftN[2]; - ret.m[ 9] = upN[2]; - ret.m[10] = -dirN[2]; - ret.m[11] = 0.f; + da = powf(da, split_exp.mV[2]); - ret.m[12] = -(lftN*pos); - ret.m[13] = -(upN*pos); - ret.m[14] = dirN*pos; - ret.m[15] = 1.f; + F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - return ret; -} + for (U32 i = 0; i < 4; ++i) + { + F32 x = (F32)(i+1)/4.f; + x = powf(x, sxp); + mSunClipPlanes.mV[i] = near_clip+range*x; + } -glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) -{ - glh::matrix4f ret; - ret.m[ 0] = 2/(max[0]-min[0]); - ret.m[ 4] = 0; - ret.m[ 8] = 0; - ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); + mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding + } - ret.m[ 1] = 0; - ret.m[ 5] = 2/(max[1]-min[1]); - ret.m[ 9] = 0; - ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); + if (gCubeSnapshot) + { // stretch clip planes for reflection probe renders to reduce number of shadow passes + mSunClipPlanes.mV[1] = mSunClipPlanes.mV[2]; + mSunClipPlanes.mV[2] = mSunClipPlanes.mV[3]; + mSunClipPlanes.mV[3] *= 1.5f; + } - ret.m[ 2] = 0; - ret.m[ 6] = 0; - ret.m[10] = 2/(max[2]-min[2]); - ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); - ret.m[ 3] = 0; - ret.m[ 7] = 0; - ret.m[11] = 0; - ret.m[15] = 1; + // convenience array of 4 near clip plane distances + F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - return ret; -} + if (mSunDiffuse == LLColor4::black) + { //sun diffuse is totally black shadows don't matter + skipRenderingShadows(); + } + else + { + for (S32 j = 0; j < (gCubeSnapshot ? 2 : 4); j++) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowFrustPoints[j].clear(); + } -static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_GEOM("Shadow Geom"); + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); + //restore render matrices + set_current_modelview(saved_view); + set_current_projection(saved_proj); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool depth_clamp) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); - LL_PROFILE_GPU_ZONE("renderShadow"); - - LLPipeline::sShadowRender = true; + LLVector3 eye = camera.getOrigin(); + llassert(eye.isFinite()); - // disable occlusion culling during shadow render - U32 saved_occlusion = sUseOcclusion; - sUseOcclusion = 0; + //camera used for shadow cull/render + LLCamera shadow_cam; - // List of render pass types that use the prim volume as the shadow, - // ignoring textures. - static const U32 types[] = { - LLRenderPass::PASS_SIMPLE, - LLRenderPass::PASS_FULLBRIGHT, - LLRenderPass::PASS_SHINY, - LLRenderPass::PASS_BUMP, - LLRenderPass::PASS_FULLBRIGHT_SHINY, - LLRenderPass::PASS_MATERIAL, - LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, - LLRenderPass::PASS_SPECMAP, - LLRenderPass::PASS_SPECMAP_EMISSIVE, - LLRenderPass::PASS_NORMMAP, - LLRenderPass::PASS_NORMMAP_EMISSIVE, - LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_NORMSPEC_EMISSIVE - }; + //create world space camera frustum for this split + shadow_cam = camera; + shadow_cam.setFar(16.f); - LLGLEnable cull(GL_CULL_FACE); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - //enable depth clamping if available - LLGLEnable clamp_depth(depth_clamp ? GL_DEPTH_CLAMP : 0); + LLVector3* frust = shadow_cam.mAgentFrustum; - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS); + LLVector3 pn = shadow_cam.getAtAxis(); - updateCull(shadow_cam, result); + LLVector3 min, max; - stateSort(shadow_cam, result); + //construct 8 corners of split frustum section + for (U32 i = 0; i < 4; i++) + { + LLVector3 delta = frust[i+4]-eye; + delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; + delta.normVec(); + F32 dp = delta*pn; + frust[i] = eye + (delta*dist[j]*0.75f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; + } - //generate shadow map - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadMatrix(proj.m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadMatrix(view.m); + shadow_cam.calcAgentFrustumPlanes(frust); + shadow_cam.mFrustumCornerDist = 0.f; - stop_glerror(); - gGLLastMatrix = NULL; + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowCamera[j] = shadow_cam; + } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + std::vector fp; - stop_glerror(); + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir) + || j > RenderShadowSplits) + { + //no possible shadow receivers + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowExtents[j][0] = LLVector3(); + mShadowExtents[j][1] = LLVector3(); + mShadowCamera[j+4] = shadow_cam; + } - struct CompareVertexBuffer - { - bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs) - { - return lhs->mVertexBuffer > rhs->mVertexBuffer; - } - }; + mRT->shadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mRT->shadow[j].clear(); + } + mRT->shadow[j].flush(); + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; - LLVertexBuffer::unbind(); - for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged - { - bool rigged = j == 1; - gDeferredShadowProgram.bind(rigged); + continue; + } - gGL.diffuseColor4f(1, 1, 1, 1); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowExtents[j][0] = min; + mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; + } - S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); - // if not using VSM, disable color writes - if (shadow_detail <= 2) - { - gGL.setColorMask(false, false); - } + //find a good origin for shadow projection + LLVector3 origin; - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); - LL_PROFILE_GPU_ZONE("shadow simple"); - gGL.getTexUnit(0)->disable(); + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); - for (U32 type : types) - { - renderObjects(type, false, false, rigged); - } + std::vector wpf; - renderGLTFObjects(LLRenderPass::PASS_GLTF_PBR, false, rigged); + for (U32 i = 0; i < fp.size(); i++) + { + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); + } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - } + min = wpf[0]; + max = wpf[0]; - if (LLPipeline::sUseOcclusion > 1) - { // do occlusion culling against non-masked only to take advantage of hierarchical Z - doOcclusion(shadow_cam); - } + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); + } + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin - { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); - renderGeomShadow(shadow_cam); - } + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; - { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); - LL_PROFILE_GPU_ZONE("shadow alpha"); - const S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0; - U32 target_width = LLRenderTarget::sCurResX; - for (int i = 0; i < 2; ++i) - { - bool rigged = i == 1; + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; + for (U32 i = 0; i < wpf.size(); ++i) { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); - LL_PROFILE_GPU_ZONE("shadow alpha masked"); - gDeferredShadowAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, true, true, rigged); + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); } + if (!wpf.empty()) { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); - LL_PROFILE_GPU_ZONE("shadow alpha blend"); - renderAlphaObjects(rigged); - } + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; - { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); - LL_PROFILE_GPU_ZONE("shadow alpha masked"); - gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true, rigged); + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; + } + + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); } { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); - LL_PROFILE_GPU_ZONE("shadow alpha grass"); - gDeferredTreeShadowProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF); + // best fit line is y=bfm*x+bfb - if (i == 0) + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; + + for (U32 i = 0; i < wpf.size(); ++i) { - renderObjects(LLRenderPass::PASS_GRASS, true); + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) + { + off_x = lx; + lp = wpf[i]; + } } + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; + + //calculate error + mShadowError.mV[j] = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha material"); - LL_PROFILE_GPU_ZONE("shadow alpha material"); - renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, true, false, rigged); + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); } - } - } - for (int i = 0; i < 2; ++i) - { - bool rigged = i == 1; - gDeferredShadowGLTFAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; - U32 type = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK; + if (mShadowError.mV[j] > RenderShadowErrorCutoff) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); - if (rigged) - { - mAlphaMaskPool->pushRiggedGLTFBatches(type + 1); - } - else - { - mAlphaMaskPool->pushGLTFBatches(type); - } + F32 fovz = 1.f; + F32 fovx = 1.f; - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; - } - } + LLVector3 zp; + LLVector3 xp; - gDeferredShadowCubeProgram.bind(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } - gGL.setColorMask(true, true); + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } + } - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - gGLLastMatrix = NULL; + fovx = acos(fovx); + fovz = acos(fovz); - // reset occlusion culling flag - sUseOcclusion = saved_occlusion; - LLPipeline::sShadowRender = false; -} + F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); -bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector& fp, LLVector3 light_dir) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - //get point cloud of intersection of frust and min, max - - if (getVisibleExtents(camera, min, max)) - { - return false; - } - - //get set of planes on bounding box - LLPlane bp[] = { - LLPlane(min, LLVector3(-1,0,0)), - LLPlane(min, LLVector3(0,-1,0)), - LLPlane(min, LLVector3(0,0,-1)), - LLPlane(max, LLVector3(1,0,0)), - LLPlane(max, LLVector3(0,1,0)), - LLPlane(max, LLVector3(0,0,1))}; - - //potential points - std::vector pp; - - //add corners of AABB - pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); - pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); - pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); - pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); - pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); - pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); - pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); - pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); - - //add corners of camera frustum - for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++) - { - pp.push_back(camera.mAgentFrustum[i]); - } - - - //bounding box line segments - U32 bs[] = - { - 0,1, - 1,3, - 3,2, - 2,0, - - 4,5, - 5,7, - 7,6, - 6,4, - - 0,4, - 1,5, - 3,7, - 2,6 - }; - - for (U32 i = 0; i < 12; i++) - { //for each line segment in bounding box - for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++) - { //for each plane in camera frustum - const LLPlane& cp = camera.getAgentPlane(j); - const LLVector3& v1 = pp[bs[i*2+0]]; - const LLVector3& v2 = pp[bs[i*2+1]]; - LLVector3 n; - cp.getVector3(n); - - LLVector3 line = v1-v2; - - F32 d1 = line*n; - F32 d2 = -cp.dist(v2); - - F32 t = d2/d1; - - if (t > 0.f && t < 1.f) - { - LLVector3 intersect = v2+line*t; - pp.push_back(intersect); - } - } - } - - //camera frustum line segments - const U32 fs[] = - { - 0,1, - 1,2, - 2,3, - 3,0, - - 4,5, - 5,6, - 6,7, - 7,4, - - 0,4, - 1,5, - 2,6, - 3,7 - }; - - for (U32 i = 0; i < 12; i++) - { - for (U32 j = 0; j < 6; ++j) - { - const LLVector3& v1 = pp[fs[i*2+0]+8]; - const LLVector3& v2 = pp[fs[i*2+1]+8]; - const LLPlane& cp = bp[j]; - LLVector3 n; - cp.getVector3(n); - - LLVector3 line = v1-v2; - - F32 d1 = line*n; - F32 d2 = -cp.dist(v2); - - F32 t = d2/d1; - - if (t > 0.f && t < 1.f) - { - LLVector3 intersect = v2+line*t; - pp.push_back(intersect); - } - } - } - - LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), - max+LLVector3(0.05f,0.05f,0.05f) }; - - for (U32 i = 0; i < pp.size(); ++i) - { - bool found = true; - - const F32* p = pp[i].mV; - - for (U32 j = 0; j < 3; ++j) - { - if (p[j] < ext[0].mV[j] || - p[j] > ext[1].mV[j]) - { - found = false; - break; - } - } - - for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) - { - const LLPlane& cp = camera.getAgentPlane(j); - F32 dist = cp.dist(pp[i]); - if (dist > 0.05f) //point is above some plane, not contained - { - found = false; - break; - } - } - - if (found) - { - fp.push_back(pp[i]); - } - } - - if (fp.empty()) - { - return false; - } - - return true; -} + mShadowFOV.mV[j] = fovx; -void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) -{ - if (obj && obj->getVolume()) - { - for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) - { - renderHighlight(*iter, fade); - } - - LLDrawable* drawable = obj->mDrawable; - if (drawable) - { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - if (face) - { - face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade)); - } - } - } - } -} + if (fovx < cutoff && fovz > cutoff) + { + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); + origin.mV[1] = ny; -LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i) -{ - llassert(i < 4); - return &mRT->shadow[i]; -} + fovz = 1.f; + fovx = 1.f; -LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i) -{ - llassert(i < 2); - return &mSpotShadow[i]; -} + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } + + fovx = acos(fovx); + fovz = acos(fovz); + + mShadowFOV.mV[j] = cutoff; + } + + + origin += center; + + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); + + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } + + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //get perspective projection + view[j] = view[j].inverse(); + //llassert(origin.isFinite()); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render"); + glh::vec3f origin_agent(origin.mV); -// helper class for disabling occlusion culling for the current stack frame -class LLDisableOcclusionCulling -{ -public: - S32 mUseOcclusion; + //translate view to origin + view[j].mult_matrix_vec(origin_agent); - LLDisableOcclusionCulling() - { - mUseOcclusion = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 0; - } + eye = LLVector3(origin_agent.v); + //llassert(eye.isFinite()); + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowFrustOrigin[j] = eye; + } - ~LLDisableOcclusionCulling() - { - LLPipeline::sUseOcclusion = mUseOcclusion; - } -}; + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); -void LLPipeline::generateSunShadow(LLCamera& camera) -{ - if (!sRenderDeferred || RenderShadowDetail <= 0) - { - return; - } + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); - LL_PROFILE_GPU_ZONE("generateSunShadow"); + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } + } + } - LLDisableOcclusionCulling no_occlusion; + //shadow_cam.setFar(128.f); + shadow_cam.setOriginAndLookAt(eye, up, center); - bool skip_avatar_update = false; - if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) - { - skip_avatar_update = true; - } - - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); - } - - F64 last_modelview[16]; - F64 last_projection[16]; - for (U32 i = 0; i < 16; i++) - { //store last_modelview of world camera - last_modelview[i] = gGLLastModelView[i]; - last_projection[i] = gGLLastProjection[i]; - } - - pushRenderTypeMask(); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, - LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER, - LLPipeline::RENDER_TYPE_ALPHA_POST_WATER, - LLPipeline::RENDER_TYPE_GRASS, - LLPipeline::RENDER_TYPE_GLTF_PBR, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_CONTROL_AV, - LLPipeline::RENDER_TYPE_TREE, - LLPipeline::RENDER_TYPE_TERRAIN, - LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_MATERIAL, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_SPECMAP, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_NORMMAP, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED, - LLPipeline::RENDER_TYPE_PASS_BUMP_RIGGED, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SHINY_RIGGED, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_RIGGED, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED, - LLPipeline::RENDER_TYPE_PASS_GLTF_PBR, - LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED, - LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED, - END_RENDER_TYPES); + shadow_cam.setOrigin(0,0,0); - gGL.setColorMask(false, false); + set_current_modelview(view[j]); + set_current_projection(proj[j]); - LLEnvironment& environment = LLEnvironment::instance(); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - //get sun view matrix - - //store current projection/modelview matrix - glh::matrix4f saved_proj = get_current_projection(); - glh::matrix4f saved_view = get_current_modelview(); - glh::matrix4f inv_view = saved_view.inverse(); + //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); - glh::matrix4f view[6]; - glh::matrix4f proj[6]; - - LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - //put together a universal "near clip" plane for shadow frusta - LLPlane shadow_near_clip; - { - LLVector3 p = camera.getOrigin(); // gAgent.getPositionAgent(); - p += caster_dir * RenderFarClip*2.f; - shadow_near_clip.setVec(p, caster_dir); - } - - LLVector3 lightDir = -caster_dir; - lightDir.normVec(); - - glh::vec3f light_dir(lightDir.mV); - - //create light space camera matrix - - LLVector3 at = lightDir; - - LLVector3 up = camera.getAtAxis(); - - if (fabsf(up*lightDir) > 0.75f) - { - up = camera.getUpAxis(); - } - - up.normVec(); - at.normVec(); - - - LLCamera main_camera = camera; - - F32 near_clip = 0.f; - { - //get visible point cloud - std::vector fp; - - main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); - - LLVector3 min,max; - getVisiblePointCloud(main_camera,min,max,fp); - - if (fp.empty()) - { - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowCamera[0] = main_camera; - mShadowExtents[0][0] = min; - mShadowExtents[0][1] = max; - - mShadowFrustPoints[0].clear(); - mShadowFrustPoints[1].clear(); - mShadowFrustPoints[2].clear(); - mShadowFrustPoints[3].clear(); - } - popRenderTypeMask(); - - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); - } - - return; - } - - //get good split distances for frustum - for (U32 i = 0; i < fp.size(); ++i) - { - glh::vec3f v(fp[i].mV); - saved_view.mult_matrix_vec(v); - fp[i].setVec(v.v); - } - - min = fp[0]; - max = fp[0]; - - //get camera space bounding box - for (U32 i = 1; i < fp.size(); ++i) - { - update_min_max(min, max, fp[i]); - } - - near_clip = llclamp(-max.mV[2], 0.01f, 4.0f); - F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f); - - //far_clip = llmin(far_clip, 128.f); - far_clip = llmin(far_clip, camera.getFar()); - - F32 range = far_clip-near_clip; - - LLVector3 split_exp = RenderShadowSplitExponent; - - F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - - da = powf(da, split_exp.mV[2]); - - F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - for (U32 i = 0; i < 4; ++i) - { - F32 x = (F32)(i+1)/4.f; - x = powf(x, sxp); - mSunClipPlanes.mV[i] = near_clip+range*x; - } - - mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding - } + set_current_modelview(view[j]); + set_current_projection(proj[j]); - if (gCubeSnapshot) - { // stretch clip planes for reflection probe renders to reduce number of shadow passes - mSunClipPlanes.mV[1] = mSunClipPlanes.mV[2]; - mSunClipPlanes.mV[2] = mSunClipPlanes.mV[3]; - mSunClipPlanes.mV[3] *= 1.5f; - } + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = mShadowModelview[j].m[i]; + gGLLastProjection[i] = mShadowProjection[j].m[i]; + } + mShadowModelview[j] = view[j]; + mShadowProjection[j] = proj[j]; + mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - // convenience array of 4 near clip plane distances - F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - - if (mSunDiffuse == LLColor4::black) - { //sun diffuse is totally black shadows don't matter - skipRenderingShadows(); - } - else - { - for (S32 j = 0; j < (gCubeSnapshot ? 2 : 4); j++) - { - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowFrustPoints[j].clear(); - } + stop_glerror(); - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j); + mRT->shadow[j].bindTarget(); + mRT->shadow[j].getViewport(gGLViewport); + mRT->shadow[j].clear(); - //restore render matrices - set_current_modelview(saved_view); - set_current_projection(saved_proj); + { + static LLCullResult result[4]; + renderShadow(view[j], proj[j], shadow_cam, result[j], true); + } - LLVector3 eye = camera.getOrigin(); - llassert(eye.isFinite()); + mRT->shadow[j].flush(); - //camera used for shadow cull/render - LLCamera shadow_cam; - - //create world space camera frustum for this split - shadow_cam = camera; - shadow_cam.setFar(16.f); - - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - - LLVector3* frust = shadow_cam.mAgentFrustum; - - LLVector3 pn = shadow_cam.getAtAxis(); - - LLVector3 min, max; - - //construct 8 corners of split frustum section - for (U32 i = 0; i < 4; i++) - { - LLVector3 delta = frust[i+4]-eye; - delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; - delta.normVec(); - F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j]*0.75f)/dp; - frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; - } - - shadow_cam.calcAgentFrustumPlanes(frust); - shadow_cam.mFrustumCornerDist = 0.f; - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowCamera[j] = shadow_cam; - } - - std::vector fp; - - if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir) - || j > RenderShadowSplits) - { - //no possible shadow receivers - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowExtents[j][0] = LLVector3(); - mShadowExtents[j][1] = LLVector3(); - mShadowCamera[j+4] = shadow_cam; - } - - mRT->shadow[j].bindTarget(); - { - LLGLDepthTest depth(GL_TRUE); - mRT->shadow[j].clear(); - } - mRT->shadow[j].flush(); - - mShadowError.mV[j] = 0.f; - mShadowFOV.mV[j] = 0.f; - - continue; - } - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowExtents[j][0] = min; - mShadowExtents[j][1] = max; - mShadowFrustPoints[j] = fp; - } - - - //find a good origin for shadow projection - LLVector3 origin; - - //get a temporary view projection - view[j] = look(camera.getOrigin(), lightDir, -up); - - std::vector wpf; - - for (U32 i = 0; i < fp.size(); i++) - { - glh::vec3f p = glh::vec3f(fp[i].mV); - view[j].mult_matrix_vec(p); - wpf.push_back(LLVector3(p.v)); - } - - min = wpf[0]; - max = wpf[0]; - - for (U32 i = 0; i < fp.size(); ++i) - { //get AABB in camera space - update_min_max(min, max, wpf[i]); - } - - // Construct a perspective transform with perspective along y-axis that contains - // points in wpf - //Known: - // - far clip plane - // - near clip plane - // - points in frustum - //Find: - // - origin - - //get some "interesting" points of reference - LLVector3 center = (min+max)*0.5f; - LLVector3 size = (max-min)*0.5f; - LLVector3 near_center = center; - near_center.mV[1] += size.mV[1]*2.f; - - - //put all points in wpf in quadrant 0, reletive to center of min/max - //get the best fit line using least squares - F32 bfm = 0.f; - F32 bfb = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - wpf[i] -= center; - wpf[i].mV[0] = fabsf(wpf[i].mV[0]); - wpf[i].mV[2] = fabsf(wpf[i].mV[2]); - } - - if (!wpf.empty()) - { - F32 sx = 0.f; - F32 sx2 = 0.f; - F32 sy = 0.f; - F32 sxy = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - sx += wpf[i].mV[0]; - sx2 += wpf[i].mV[0]*wpf[i].mV[0]; - sy += wpf[i].mV[1]; - sxy += wpf[i].mV[0]*wpf[i].mV[1]; - } - - bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); - bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); - } - - { - // best fit line is y=bfm*x+bfb - - //find point that is furthest to the right of line - F32 off_x = -1.f; - LLVector3 lp; - - for (U32 i = 0; i < wpf.size(); ++i) - { - //y = bfm*x+bfb - //x = (y-bfb)/bfm - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - - lx = wpf[i].mV[0]-lx; - - if (off_x < lx) - { - off_x = lx; - lp = wpf[i]; - } - } - - //get line with slope bfm through lp - // bfb = y-bfm*x - bfb = lp.mV[1]-bfm*lp.mV[0]; - - //calculate error - mShadowError.mV[j] = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); - } - - mShadowError.mV[j] /= wpf.size(); - mShadowError.mV[j] /= size.mV[0]; - - if (mShadowError.mV[j] > RenderShadowErrorCutoff) - { //just use ortho projection - mShadowFOV.mV[j] = -1.f; - origin.clearVec(); - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //origin is where line x = 0; - origin.setVec(0,bfb,0); - - F32 fovz = 1.f; - F32 fovx = 1.f; - - LLVector3 zp; - LLVector3 xp; - - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - if (fovz > -atz.mV[1]) - { - zp = wpf[i]; - fovz = -atz.mV[1]; - } - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - if (fovx > -atx.mV[1]) - { - fovx = -atx.mV[1]; - xp = wpf[i]; - } - } - - fovx = acos(fovx); - fovz = acos(fovz); - - F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); - - mShadowFOV.mV[j] = fovx; - - if (fovx < cutoff && fovz > cutoff) - { - //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff - F32 d = zp.mV[2]/tan(cutoff); - F32 ny = zp.mV[1] + fabsf(d); - - origin.mV[1] = ny; - - fovz = 1.f; - fovx = 1.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - fovz = llmin(fovz, -atz.mV[1]); - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - fovx = llmin(fovx, -atx.mV[1]); - } - - fovx = acos(fovx); - fovz = acos(fovz); - - mShadowFOV.mV[j] = cutoff; - } - - - origin += center; - - F32 ynear = -(max.mV[1]-origin.mV[1]); - F32 yfar = -(min.mV[1]-origin.mV[1]); - - if (ynear < 0.1f) //keep a sensible near clip plane - { - F32 diff = 0.1f-ynear; - origin.mV[1] += diff; - ynear += diff; - yfar += diff; - } - - if (fovx > cutoff) - { //just use ortho projection - origin.clearVec(); - mShadowError.mV[j] = -1.f; - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //get perspective projection - view[j] = view[j].inverse(); - //llassert(origin.isFinite()); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) + { + mShadowCamera[j+4] = shadow_cam; + } + } + } - glh::vec3f origin_agent(origin.mV); - - //translate view to origin - view[j].mult_matrix_vec(origin_agent); + //hack to disable projector shadows + bool gen_shadow = RenderShadowDetail > 1; - eye = LLVector3(origin_agent.v); - //llassert(eye.isFinite()); - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowFrustOrigin[j] = eye; - } - - view[j] = look(LLVector3(origin_agent.v), lightDir, -up); - - F32 fx = 1.f/tanf(fovx); - F32 fz = 1.f/tanf(fovz); - - proj[j] = glh::matrix4f(-fx, 0, 0, 0, - 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), - 0, 0, -fz, 0, - 0, -1.f, 0, 0); - } - } - } - - //shadow_cam.setFar(128.f); - shadow_cam.setOriginAndLookAt(eye, up, center); - - shadow_cam.setOrigin(0,0,0); - - set_current_modelview(view[j]); - set_current_projection(proj[j]); - - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - - //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); - shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); - - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - set_current_modelview(view[j]); - set_current_projection(proj[j]); - - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = mShadowModelview[j].m[i]; - gGLLastProjection[i] = mShadowProjection[j].m[i]; - } - - mShadowModelview[j] = view[j]; - mShadowProjection[j] = proj[j]; - mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - - stop_glerror(); - - mRT->shadow[j].bindTarget(); - mRT->shadow[j].getViewport(gGLViewport); - mRT->shadow[j].clear(); - - { - static LLCullResult result[4]; - renderShadow(view[j], proj[j], shadow_cam, result[j], true); - } - - mRT->shadow[j].flush(); - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) - { - mShadowCamera[j+4] = shadow_cam; - } - } - } - - //hack to disable projector shadows - bool gen_shadow = RenderShadowDetail > 1; - - if (gen_shadow) - { + if (gen_shadow) + { if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates { LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); @@ -10072,7 +10072,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); // - + mSpotShadow[i].bindTarget(); mSpotShadow[i].getViewport(gGLViewport); mSpotShadow[i].clear(); @@ -10090,56 +10090,56 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSpotShadow[i].flush(); } } - } - else - { //no spotlight shadows - mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; - } + } + else + { //no spotlight shadows + mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; + } - if (!CameraOffset) - { - set_current_modelview(saved_view); - set_current_projection(saved_proj); - } - else - { - set_current_modelview(view[1]); - set_current_projection(proj[1]); - gGL.loadMatrix(view[1].m); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj[1].m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - gGL.setColorMask(true, true); + if (!CameraOffset) + { + set_current_modelview(saved_view); + set_current_projection(saved_proj); + } + else + { + set_current_modelview(view[1]); + set_current_projection(proj[1]); + gGL.loadMatrix(view[1].m); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadMatrix(proj[1].m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + gGL.setColorMask(true, true); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = last_modelview[i]; - gGLLastProjection[i] = last_projection[i]; - } + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = last_modelview[i]; + gGLLastProjection[i] = last_projection[i]; + } - popRenderTypeMask(); + popRenderTypeMask(); - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); - } + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, bool texture) { - for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (!group->isDead() && - (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && - gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && - group->mDrawMap.find(type) != group->mDrawMap.end()) - { - pass->renderGroup(group,type,texture); - } - } + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!group->isDead() && + (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && + gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) + { + pass->renderGroup(group,type,texture); + } + } } void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture) @@ -10187,8 +10187,8 @@ void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments) avatar->readProfileQuery(5); // allow up to 5 frames of latency } - else - { + else + { // profile attachments one at a time LLVOAvatar::attachment_map_t::iterator iter; LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin(); @@ -10231,27 +10231,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LL_PROFILE_GPU_ZONE("generateImpostor"); - LLGLState::checkStates(); - - static LLCullResult result; - result.clear(); - grabReferences(result); - - if (!avatar || !avatar->mDrawable) - { + LLGLState::checkStates(); + + static LLCullResult result; + result.clear(); + grabReferences(result); + + if (!avatar || !avatar->mDrawable) + { LL_WARNS_ONCE("AvatarRenderPipeline") << "Avatar is " << (avatar ? "not drawable" : "null") << LL_ENDL; - return; - } + return; + } LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is drawable" << LL_ENDL; - assertInitialized(); + assertInitialized(); // previews can't be muted or impostered - bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted(); + bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted(); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( visually_muted ? "" : "not ") << "visually muted" << LL_ENDL; - bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex(); + bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex(); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( too_complex ? "" : "not ") << "too complex" << LL_ENDL; @@ -10261,12 +10261,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool if (visually_muted || too_complex) { // only show jelly doll geometry - andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_CONTROL_AV, - END_RENDER_TYPES); - } - else - { + andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + END_RENDER_TYPES); + } + else + { //hide world geometry clearRenderTypeMask( RENDER_TYPE_SKY, @@ -10285,25 +10285,25 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool RENDER_TYPE_HUD_PARTICLES, END_RENDER_TYPES ); - } - + } + if (specific_attachment && specific_attachment->isHUDAttachment()) { //enable HUD rendering setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES); } - S32 occlusion = sUseOcclusion; - sUseOcclusion = 0; + S32 occlusion = sUseOcclusion; + sUseOcclusion = 0; - sReflectionRender = ! sRenderDeferred; + sReflectionRender = ! sRenderDeferred; - sShadowRender = true; - sImpostorRender = true; + sShadowRender = true; + sImpostorRender = true; - LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); + LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); - { - markVisible(avatar->mDrawable, *viewer_camera); + { + markVisible(avatar->mDrawable, *viewer_camera); if (preview_avatar) { @@ -10376,70 +10376,70 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool } } } - } + } - stateSort(*LLViewerCamera::getInstance(), result); - - LLCamera camera = *viewer_camera; - LLVector2 tdim; - U32 resY = 0; - U32 resX = 0; + stateSort(*LLViewerCamera::getInstance(), result); + + LLCamera camera = *viewer_camera; + LLVector2 tdim; + U32 resY = 0; + U32 resX = 0; if (!preview_avatar) - { - const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); - LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); - - camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); - - LLVector4a half_height; - half_height.setSub(ext[1], ext[0]); - half_height.mul(0.5f); - - LLVector4a left; - left.load3(camera.getLeftAxis().mV); - left.mul(left); - llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO); - left.normalize3fast(); - - LLVector4a up; - up.load3(camera.getUpAxis().mV); - up.mul(up); - llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO); - up.normalize3fast(); - - tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); - tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - - F32 distance = (pos-camera.getOrigin()).length(); - F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; - F32 aspect = tdim.mV[0]/tdim.mV[1]; - glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); - set_current_projection(persp); - gGL.loadMatrix(persp.m); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - glh::matrix4f mat; - camera.getOpenGLTransform(mat.m); - - mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; - - gGL.loadMatrix(mat.m); - set_current_modelview(mat); - - glClearColor(0.0f,0.0f,0.0f,0.0f); - gGL.setColorMask(true, true); - - // get the number of pixels per angle - F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); - - //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) - resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); - resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); + { + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); + LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); + + camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); + + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); + + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO); + left.normalize3fast(); + + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO); + up.normalize3fast(); + + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + + F32 distance = (pos-camera.getOrigin()).length(); + F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; + F32 aspect = tdim.mV[0]/tdim.mV[1]; + glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); + set_current_projection(persp); + gGL.loadMatrix(persp.m); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + glh::matrix4f mat; + camera.getOpenGLTransform(mat.m); + + mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + + gGL.loadMatrix(mat.m); + set_current_modelview(mat); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + gGL.setColorMask(true, true); + + // get the number of pixels per angle + F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); + + //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) + resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); + resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); if (!for_profile) { @@ -10463,14 +10463,14 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool avatar->mImpostor.bindTarget(); } - } + } - F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; + F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; - if (visually_muted || too_complex) - { //disable alpha masking for muted avatars (get whole skin silhouette) - LLDrawPoolAvatar::sMinimumAlpha = 0.f; - } + if (visually_muted || too_complex) + { //disable alpha masking for muted avatars (get whole skin silhouette) + LLDrawPoolAvatar::sMinimumAlpha = 0.f; + } if (preview_avatar || for_profile) { @@ -10479,91 +10479,91 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool renderGeomPostDeferred(camera); } else - { - avatar->mImpostor.clear(); - renderGeomDeferred(camera); + { + avatar->mImpostor.clear(); + renderGeomDeferred(camera); - renderGeomPostDeferred(camera); + renderGeomPostDeferred(camera); - // Shameless hack time: render it all again, - // this time writing the depth - // values we need to generate the alpha mask below - // while preserving the alpha-sorted color rendering - // from the previous pass - // - sImpostorRenderAlphaDepthPass = true; - // depth-only here... - // - gGL.setColorMask(false,false); - renderGeomPostDeferred(camera); + // Shameless hack time: render it all again, + // this time writing the depth + // values we need to generate the alpha mask below + // while preserving the alpha-sorted color rendering + // from the previous pass + // + sImpostorRenderAlphaDepthPass = true; + // depth-only here... + // + gGL.setColorMask(false,false); + renderGeomPostDeferred(camera); - sImpostorRenderAlphaDepthPass = false; + sImpostorRenderAlphaDepthPass = false; - } + } - LLDrawPoolAvatar::sMinimumAlpha = old_alpha; + LLDrawPoolAvatar::sMinimumAlpha = old_alpha; if (!for_profile) - { //create alpha mask based on depth buffer (grey out if muted) - if (LLPipeline::sRenderDeferred) - { - GLuint buff = GL_COLOR_ATTACHMENT0; - glDrawBuffers(1, &buff); - } - - LLGLDisable blend(GL_BLEND); - - if (visually_muted || too_complex) - { - gGL.setColorMask(true, true); - } - else - { - gGL.setColorMask(false, true); - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - - gGL.flush(); - - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - static const F32 clip_plane = 0.99999f; - - gDebugProgram.bind(); - - if (visually_muted) - { // Visually muted avatar + { //create alpha mask based on depth buffer (grey out if muted) + if (LLPipeline::sRenderDeferred) + { + GLuint buff = GL_COLOR_ATTACHMENT0; + glDrawBuffers(1, &buff); + } + + LLGLDisable blend(GL_BLEND); + + if (visually_muted || too_complex) + { + gGL.setColorMask(true, true); + } + else + { + gGL.setColorMask(false, true); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + gGL.flush(); + + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + static const F32 clip_plane = 0.99999f; + + gDebugProgram.bind(); + + if (visually_muted) + { // Visually muted avatar LLColor4 muted_color(avatar->getMutedAVColor()); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set solid color " << muted_color << LL_ENDL; - gGL.diffuseColor4fv( muted_color.mV ); - } - else if (!preview_avatar) - { //grey muted avatar + gGL.diffuseColor4fv( muted_color.mV ); + } + else if (!preview_avatar) + { //grey muted avatar LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set grey" << LL_ENDL; - gGL.diffuseColor4fv(LLColor4::pink.mV ); - } + gGL.diffuseColor4fv(LLColor4::pink.mV ); + } - gGL.begin(LLRender::QUADS); - gGL.vertex3f(-1, -1, clip_plane); - gGL.vertex3f(1, -1, clip_plane); - gGL.vertex3f(1, 1, clip_plane); - gGL.vertex3f(-1, 1, clip_plane); - gGL.end(); - gGL.flush(); + gGL.begin(LLRender::QUADS); + gGL.vertex3f(-1, -1, clip_plane); + gGL.vertex3f(1, -1, clip_plane); + gGL.vertex3f(1, 1, clip_plane); + gGL.vertex3f(-1, 1, clip_plane); + gGL.end(); + gGL.flush(); - gDebugProgram.unbind(); + gDebugProgram.unbind(); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } if (!preview_avatar && !for_profile) { @@ -10571,16 +10571,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool avatar->setImpostorDim(tdim); } - sUseOcclusion = occlusion; - sReflectionRender = false; - sImpostorRender = false; - sShadowRender = false; - popRenderTypeMask(); + sUseOcclusion = occlusion; + sReflectionRender = false; + sImpostorRender = false; + sShadowRender = false; + popRenderTypeMask(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); if (!preview_avatar && !for_profile) { @@ -10589,33 +10589,33 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds; } - LLVertexBuffer::unbind(); - LLGLState::checkStates(); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); } bool LLPipeline::hasRenderBatches(const U32 type) const { - return sCull->getRenderMapSize(type) > 0; + return sCull->getRenderMapSize(type) > 0; } LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) { - return sCull->beginRenderMap(type); + return sCull->beginRenderMap(type); } LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) { - return sCull->endRenderMap(type); + return sCull->endRenderMap(type); } LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() { - return sCull->beginAlphaGroups(); + return sCull->beginAlphaGroups(); } LLCullResult::sg_iterator LLPipeline::endAlphaGroups() { - return sCull->endAlphaGroups(); + return sCull->endAlphaGroups(); } LLCullResult::sg_iterator LLPipeline::beginRiggedAlphaGroups() @@ -10633,278 +10633,278 @@ bool LLPipeline::hasRenderType(const U32 type) const // STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render" // We then need to test that value here and return false to prevent attachment to render (in mouselook for instance) // TODO: reintroduce RENDER_TYPE_NONE in LLRenderTypeMask and initialize its mRenderTypeEnabled[RENDER_TYPE_NONE] to false explicitely - return (type == 0 ? false : mRenderTypeEnabled[type]); + return (type == 0 ? false : mRenderTypeEnabled[type]); } void LLPipeline::setRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - mRenderTypeEnabled[type] = true; - type = va_arg(args, U32); - } - va_end(args); + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = true; + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } } bool LLPipeline::hasAnyRenderType(U32 type, ...) const { - va_list args; + va_list args; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - if (mRenderTypeEnabled[type]) - { - return true; - } - type = va_arg(args, U32); - } - va_end(args); + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + return true; + } + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } - return false; + return false; } void LLPipeline::pushRenderTypeMask() { - std::string cur_mask; - cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); - mRenderTypeEnableStack.push(cur_mask); + std::string cur_mask; + cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.push(cur_mask); } void LLPipeline::popRenderTypeMask() { - if (mRenderTypeEnableStack.empty()) - { - LL_ERRS() << "Depleted render type stack." << LL_ENDL; - } + if (mRenderTypeEnableStack.empty()) + { + LL_ERRS() << "Depleted render type stack." << LL_ENDL; + } - memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); - mRenderTypeEnableStack.pop(); + memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.pop(); } void LLPipeline::andRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; - bool tmp[NUM_RENDER_TYPES]; - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - tmp[i] = false; - } + bool tmp[NUM_RENDER_TYPES]; + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + tmp[i] = false; + } - va_start(args, type); - while (type < END_RENDER_TYPES) - { - if (mRenderTypeEnabled[type]) - { - tmp[type] = true; - } + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + tmp[type] = true; + } - type = va_arg(args, U32); - } - va_end(args); + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } - for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = tmp[i]; - } + for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = tmp[i]; + } } void LLPipeline::clearRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = false; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - mRenderTypeEnabled[type] = false; - - type = va_arg(args, U32); - } - va_end(args); + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } } void LLPipeline::setAllRenderTypes() { - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = true; - } + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = true; + } } void LLPipeline::clearAllRenderTypes() { - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = false; - } + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = false; + } } void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) { - DebugBlip blip(position, color); - mDebugBlips.push_back(blip); + DebugBlip blip(position, color); + mDebugBlips.push_back(blip); } void LLPipeline::hidePermanentObjects( std::vector& restoreList ) { - //This method is used to hide any vo's from the object list that may have - //the permanent flag set. - - U32 objCnt = gObjectList.getNumObjects(); - for (U32 i = 0; i < objCnt; ++i) - { - LLViewerObject* pObject = gObjectList.getObject(i); - if ( pObject && pObject->flagObjectPermanent() ) - { - LLDrawable *pDrawable = pObject->mDrawable; - - if ( pDrawable ) - { - restoreList.push_back( i ); - hideDrawable( pDrawable ); - } - } - } - - skipRenderingOfTerrain( true ); + //This method is used to hide any vo's from the object list that may have + //the permanent flag set. + + U32 objCnt = gObjectList.getNumObjects(); + for (U32 i = 0; i < objCnt; ++i) + { + LLViewerObject* pObject = gObjectList.getObject(i); + if ( pObject && pObject->flagObjectPermanent() ) + { + LLDrawable *pDrawable = pObject->mDrawable; + + if ( pDrawable ) + { + restoreList.push_back( i ); + hideDrawable( pDrawable ); + } + } + } + + skipRenderingOfTerrain( true ); } void LLPipeline::restorePermanentObjects( const std::vector& restoreList ) { - //This method is used to restore(unhide) any vo's from the object list that may have - //been hidden because their permanency flag was set. - - std::vector::const_iterator itCurrent = restoreList.begin(); - std::vector::const_iterator itEnd = restoreList.end(); - - U32 objCnt = gObjectList.getNumObjects(); - - while ( itCurrent != itEnd ) - { - U32 index = *itCurrent; - LLViewerObject* pObject = NULL; - if ( index < objCnt ) - { - pObject = gObjectList.getObject( index ); - } - if ( pObject ) - { - LLDrawable *pDrawable = pObject->mDrawable; - if ( pDrawable ) - { - pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); - unhideDrawable( pDrawable ); - } - } - ++itCurrent; - } - - skipRenderingOfTerrain( false ); + //This method is used to restore(unhide) any vo's from the object list that may have + //been hidden because their permanency flag was set. + + std::vector::const_iterator itCurrent = restoreList.begin(); + std::vector::const_iterator itEnd = restoreList.end(); + + U32 objCnt = gObjectList.getNumObjects(); + + while ( itCurrent != itEnd ) + { + U32 index = *itCurrent; + LLViewerObject* pObject = NULL; + if ( index < objCnt ) + { + pObject = gObjectList.getObject( index ); + } + if ( pObject ) + { + LLDrawable *pDrawable = pObject->mDrawable; + if ( pDrawable ) + { + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + unhideDrawable( pDrawable ); + } + } + ++itCurrent; + } + + skipRenderingOfTerrain( false ); } void LLPipeline::skipRenderingOfTerrain( bool flag ) { - pool_set_t::iterator iter = mPools.begin(); - while ( iter != mPools.end() ) - { - LLDrawPool* pPool = *iter; - U32 poolType = pPool->getType(); - if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN ) - { - pPool->setSkipRenderFlag( flag ); - } - ++iter; - } + pool_set_t::iterator iter = mPools.begin(); + while ( iter != mPools.end() ) + { + LLDrawPool* pPool = *iter; + U32 poolType = pPool->getType(); + if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN ) + { + pPool->setSkipRenderFlag( flag ); + } + ++iter; + } } void LLPipeline::hideObject( const LLUUID& id ) { - LLViewerObject *pVO = gObjectList.findObject( id ); - - if ( pVO ) - { - LLDrawable *pDrawable = pVO->mDrawable; - - if ( pDrawable ) - { - hideDrawable( pDrawable ); - } - } + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + + if ( pDrawable ) + { + hideDrawable( pDrawable ); + } + } } void LLPipeline::hideDrawable( LLDrawable *pDrawable ) { - pDrawable->setState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( pDrawable, LLDrawable::REBUILD_ALL); - //hide the children - LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); - for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++ ) - { - LLViewerObject* child = *iter; - LLDrawable* drawable = child->mDrawable; - if ( drawable ) - { - drawable->setState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( drawable, LLDrawable::REBUILD_ALL); - } - } + pDrawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL); + //hide the children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++ ) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL); + } + } } void LLPipeline::unhideDrawable( LLDrawable *pDrawable ) { - pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( pDrawable, LLDrawable::REBUILD_ALL); - //restore children - LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); - for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - LLDrawable* drawable = child->mDrawable; - if ( drawable ) - { - drawable->clearState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( drawable, LLDrawable::REBUILD_ALL); - } - } + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL); + //restore children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL); + } + } } void LLPipeline::restoreHiddenObject( const LLUUID& id ) { - LLViewerObject *pVO = gObjectList.findObject( id ); - - if ( pVO ) - { - LLDrawable *pDrawable = pVO->mDrawable; - if ( pDrawable ) - { - unhideDrawable( pDrawable ); - } - } + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + if ( pDrawable ) + { + unhideDrawable( pDrawable ); + } + } } void LLPipeline::skipRenderingShadows() diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bfa4009a0b..62eba72e81 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1,25 +1,25 @@ -/** +/** * @file pipeline.h * @brief Rendering pipeline definitions * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -56,8 +56,8 @@ class LLSettingsSky; typedef enum e_avatar_skinning_method { - SKIN_METHOD_SOFTWARE, - SKIN_METHOD_VERTEX_PROGRAM + SKIN_METHOD_SOFTWARE, + SKIN_METHOD_VERTEX_PROGRAM } EAvatarSkinningMethod; bool compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here! @@ -93,43 +93,43 @@ extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D; class LLPipeline { public: - LLPipeline(); - ~LLPipeline(); + LLPipeline(); + ~LLPipeline(); - void destroyGL(); - void restoreGL(); - void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks... + void destroyGL(); + void restoreGL(); + void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks... void requestResizeShadowTexture(); // set flag only, no work, safer for callbacks... - void resizeScreenTexture(); + void resizeScreenTexture(); void resizeShadowTexture(); - void releaseGLBuffers(); - void releaseLUTBuffers(); - void releaseScreenBuffers(); + void releaseGLBuffers(); + void releaseLUTBuffers(); + void releaseScreenBuffers(); void releaseShadowBuffers(); - void createGLBuffers(); - void createLUTBuffers(); + void createGLBuffers(); + void createLUTBuffers(); - //allocate the largest screen buffer possible up to resX, resY - //returns true if full size buffer allocated, false if some other size is allocated - bool allocateScreenBuffer(U32 resX, U32 resY); + //allocate the largest screen buffer possible up to resX, resY + //returns true if full size buffer allocated, false if some other size is allocated + bool allocateScreenBuffer(U32 resX, U32 resY); - typedef enum { - FBO_SUCCESS_FULLRES = 0, - FBO_SUCCESS_LOWRES, - FBO_FAILURE - } eFBOStatus; + typedef enum { + FBO_SUCCESS_FULLRES = 0, + FBO_SUCCESS_LOWRES, + FBO_FAILURE + } eFBOStatus; private: - //implementation of above, wrapped for easy error handling - eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); + //implementation of above, wrapped for easy error handling + eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); public: - //attempt to allocate screen buffers at resX, resY - //returns true if allocation successful, false otherwise - bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); + //attempt to allocate screen buffers at resX, resY + //returns true if allocation successful, false otherwise + bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); bool allocateShadowBuffer(U32 resX, U32 resY); // rebuild all LLVOVolume render batches @@ -138,7 +138,7 @@ public: void rebuildTerrain(); // Clear LLFace mVertexBuffer pointers - void resetVertexBuffers(LLDrawable* drawable); + void resetVertexBuffers(LLDrawable* drawable); // perform a profile of the given avatar // if profile_attachments is true, run a profile for each attachment @@ -148,173 +148,173 @@ public: // preview_avatar - if true, a preview window render is being performed // for_profile - if true, a profile is being performed, do not update actual impostor // specific_attachment - specific attachment to profile, or nullptr to profile entire avatar - void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr); - - void bindScreenToTexture(); - void renderFinalize(); - void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); - void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); - void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true); - void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); - void generateGlow(LLRenderTarget* src); - void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); - void renderDoF(LLRenderTarget* src, LLRenderTarget* dst); - void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst); - void combineGlow(LLRenderTarget* src, LLRenderTarget* dst); - void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex); - - void init(); - void cleanup(); - bool isInit() { return mInitialized; }; - - /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. - /// @return Draw pool, or NULL if not found. - LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); - - /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary. - /// @return Always returns a draw pool. - LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); - - /// @brief Figures out draw pool type from texture entry. Creates pool if necessary. - static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image); - static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep); - - void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools! - void removePool( LLDrawPool* poolp ); - - void allocDrawable(LLViewerObject *obj); - - void unlinkDrawable(LLDrawable*); - - static void removeMutedAVsLights(LLVOAvatar*); - - // Object related methods - void markVisible(LLDrawable *drawablep, LLCamera& camera); - void markOccluder(LLSpatialGroup* group); - - void doOcclusion(LLCamera& camera); - void markNotCulled(LLSpatialGroup* group, LLCamera &camera); - void markMoved(LLDrawable *drawablep, bool damped_motion = false); - void markShift(LLDrawable *drawablep); - void markTextured(LLDrawable *drawablep); - void markGLRebuild(LLGLUpdate* glu); - void markRebuild(LLSpatialGroup* group); - void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL); - void markPartitionMove(LLDrawable* drawablep); - void markMeshDirty(LLSpatialGroup* group); - - //get the object between start and end that's closest to start. - LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - bool pick_rigged, + void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr); + + void bindScreenToTexture(); + void renderFinalize(); + void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); + void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); + void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true); + void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); + void generateGlow(LLRenderTarget* src); + void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); + void renderDoF(LLRenderTarget* src, LLRenderTarget* dst); + void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst); + void combineGlow(LLRenderTarget* src, LLRenderTarget* dst); + void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex); + + void init(); + void cleanup(); + bool isInit() { return mInitialized; }; + + /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. + /// @return Draw pool, or NULL if not found. + LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); + + /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary. + /// @return Always returns a draw pool. + LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); + + /// @brief Figures out draw pool type from texture entry. Creates pool if necessary. + static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image); + static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep); + + void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools! + void removePool( LLDrawPool* poolp ); + + void allocDrawable(LLViewerObject *obj); + + void unlinkDrawable(LLDrawable*); + + static void removeMutedAVsLights(LLVOAvatar*); + + // Object related methods + void markVisible(LLDrawable *drawablep, LLCamera& camera); + void markOccluder(LLSpatialGroup* group); + + void doOcclusion(LLCamera& camera); + void markNotCulled(LLSpatialGroup* group, LLCamera &camera); + void markMoved(LLDrawable *drawablep, bool damped_motion = false); + void markShift(LLDrawable *drawablep); + void markTextured(LLDrawable *drawablep); + void markGLRebuild(LLGLUpdate* glu); + void markRebuild(LLSpatialGroup* group); + void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL); + void markPartitionMove(LLDrawable* drawablep); + void markMeshDirty(LLSpatialGroup* group); + + //get the object between start and end that's closest to start. + LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, + bool pick_transparent, + bool pick_rigged, bool pick_unselectable, bool pick_reflection_probe, - S32* face_hit, // return the face hit + S32* face_hit, // return the face hit S32* gltf_node_hit = nullptr, // return the gltf node hit S32* gltf_primitive_hit = nullptr, // return the gltf primitive hit - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ); + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ); - //get the closest particle to start between start and end, returns the LLVOPartGroup and particle index - LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection, - S32* face_hit); + //get the closest particle to start between start and end, returns the LLVOPartGroup and particle index + LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection, + S32* face_hit); - LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - S32* face_hit, // return the face hit - LLVector4a* intersection = NULL, // return the intersection point - LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector4a* normal = NULL, // return the surface normal at the intersection point - LLVector4a* tangent = NULL // return the surface tangent at the intersection point - ); + LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, + bool pick_transparent, + S32* face_hit, // return the face hit + LLVector4a* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point + ); - // Something about these textures has changed. Dirty them. - void dirtyPoolObjectTextures(const std::set& textures); + // Something about these textures has changed. Dirty them. + void dirtyPoolObjectTextures(const std::set& textures); - void resetDrawOrders(); + void resetDrawOrders(); - U32 addObject(LLViewerObject *obj); + U32 addObject(LLViewerObject *obj); - void enableShadows(const bool enable_shadows); + void enableShadows(const bool enable_shadows); void releaseSpotShadowTargets(); void releaseSunShadowTargets(); void releaseSunShadowTarget(U32 index); - bool shadersLoaded(); - bool canUseWindLightShaders() const; - bool canUseAntiAliasing() const; + bool shadersLoaded(); + bool canUseWindLightShaders() const; + bool canUseAntiAliasing() const; - // phases - void resetFrameStats(); + // phases + void resetFrameStats(); - void updateMoveDampedAsync(LLDrawable* drawablep); - void updateMoveNormalAsync(LLDrawable* drawablep); - void updateMovedList(LLDrawable::drawable_vector_t& move_list); - void updateMove(); - bool visibleObjectsInFrustum(LLCamera& camera); - bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); - bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); + void updateMoveDampedAsync(LLDrawable* drawablep); + void updateMoveNormalAsync(LLDrawable* drawablep); + void updateMovedList(LLDrawable::drawable_vector_t& move_list); + void updateMove(); + bool visibleObjectsInFrustum(LLCamera& camera); + bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); + bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); // Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera - void updateCull(LLCamera& camera, LLCullResult& result); - void createObjects(F32 max_dtime); - void createObject(LLViewerObject* vobj); - void processPartitionQ(); - void updateGeom(F32 max_dtime); - void updateGL(); - void rebuildPriorityGroups(); - void rebuildGroups(); - void clearRebuildGroups(); - void clearRebuildDrawables(); - - //calculate pixel area of given box from vantage point of given camera - static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); - static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera); - - void stateSort(LLCamera& camera, LLCullResult& result); - void stateSort(LLSpatialGroup* group, LLCamera& camera); - void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE); - void stateSort(LLDrawable* drawablep, LLCamera& camera); - void postSort(LLCamera& camera); - - void forAllVisibleDrawables(void (*func)(LLDrawable*)); + void updateCull(LLCamera& camera, LLCullResult& result); + void createObjects(F32 max_dtime); + void createObject(LLViewerObject* vobj); + void processPartitionQ(); + void updateGeom(F32 max_dtime); + void updateGL(); + void rebuildPriorityGroups(); + void rebuildGroups(); + void clearRebuildGroups(); + void clearRebuildDrawables(); + + //calculate pixel area of given box from vantage point of given camera + static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); + static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera); + + void stateSort(LLCamera& camera, LLCullResult& result); + void stateSort(LLSpatialGroup* group, LLCamera& camera); + void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE); + void stateSort(LLDrawable* drawablep, LLCamera& camera); + void postSort(LLCamera& camera); + + void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); void renderGLTFObjects(U32 type, bool texture = true, bool rigged = false); - + void renderAlphaObjects(bool rigged = false); - void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); - void renderGroups(LLRenderPass* pass, U32 type, bool texture); + void renderGroups(LLRenderPass* pass, U32 type, bool texture); void renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture); - void grabReferences(LLCullResult& result); - void clearReferences(); - - //check references will assert that there are no references in sCullResult to the provided data - void checkReferences(LLFace* face); - void checkReferences(LLDrawable* drawable); - void checkReferences(LLDrawInfo* draw_info); - void checkReferences(LLSpatialGroup* group); - - void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false); - void renderGeomPostDeferred(LLCamera& camera); - void renderGeomShadow(LLCamera& camera); + void grabReferences(LLCullResult& result); + void clearReferences(); + + //check references will assert that there are no references in sCullResult to the provided data + void checkReferences(LLFace* face); + void checkReferences(LLDrawable* drawable); + void checkReferences(LLDrawInfo* draw_info); + void checkReferences(LLSpatialGroup* group); + + void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false); + void renderGeomPostDeferred(LLCamera& camera); + void renderGeomShadow(LLCamera& camera); void bindLightFunc(LLGLSLShader& shader); // bind shadow maps // if setup is true, wil lset texture compare mode function and filtering options void bindShadowMaps(LLGLSLShader& shader); void bindDeferredShaderFast(LLGLSLShader& shader); - void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr); - void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); + void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr); + void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); - void unbindDeferredShader(LLGLSLShader& shader); + void unbindDeferredShader(LLGLSLShader& shader); // set env_mat parameter in given shader void setEnvMat(LLGLSLShader& shader); @@ -322,10 +322,10 @@ public: void bindReflectionProbes(LLGLSLShader& shader); void unbindReflectionProbes(LLGLSLShader& shader); - void renderDeferredLighting(); + void renderDeferredLighting(); // apply atmospheric haze based on contents of color and depth buffer - // should be called just before rendering water when camera is under water + // should be called just before rendering water when camera is under water // and just before rendering alpha when camera is above water void doAtmospherics(); @@ -333,367 +333,367 @@ public: // should be called just before rendering pre-water alpha objects void doWaterHaze(); - void postDeferredGammaCorrect(LLRenderTarget* screen_target); + void postDeferredGammaCorrect(LLRenderTarget* screen_target); - void generateSunShadow(LLCamera& camera); + void generateSunShadow(LLCamera& camera); LLRenderTarget* getSunShadowTarget(U32 i); LLRenderTarget* getSpotShadowTarget(U32 i); - void renderHighlight(const LLViewerObject* obj, F32 fade); - - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp); - void renderHighlights(); - void renderDebug(); - void renderPhysicsDisplay(); - - void rebuildPools(); // Rebuild pools - - void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object - bool verify(); // Verify that all data in the pipeline is "correct" - - S32 getLightCount() const { return mLights.size(); } - - void calcNearbyLights(LLCamera& camera); - void setupHWLights(); - void setupAvatarLights(bool for_edit = false); - void enableLights(U32 mask); - void enableLightsDynamic(); - void enableLightsAvatar(); - void enableLightsPreview(); - void enableLightsAvatarEdit(const LLColor4& color); - void enableLightsFullbright(); - void disableLights(); - - void shiftObjects(const LLVector3 &offset); - - void setLight(LLDrawable *drawablep, bool is_light); - - bool hasRenderBatches(const U32 type) const; - LLCullResult::drawinfo_iterator beginRenderMap(U32 type); - LLCullResult::drawinfo_iterator endRenderMap(U32 type); - LLCullResult::sg_iterator beginAlphaGroups(); - LLCullResult::sg_iterator endAlphaGroups(); + void renderHighlight(const LLViewerObject* obj, F32 fade); + + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp); + void renderHighlights(); + void renderDebug(); + void renderPhysicsDisplay(); + + void rebuildPools(); // Rebuild pools + + void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object + bool verify(); // Verify that all data in the pipeline is "correct" + + S32 getLightCount() const { return mLights.size(); } + + void calcNearbyLights(LLCamera& camera); + void setupHWLights(); + void setupAvatarLights(bool for_edit = false); + void enableLights(U32 mask); + void enableLightsDynamic(); + void enableLightsAvatar(); + void enableLightsPreview(); + void enableLightsAvatarEdit(const LLColor4& color); + void enableLightsFullbright(); + void disableLights(); + + void shiftObjects(const LLVector3 &offset); + + void setLight(LLDrawable *drawablep, bool is_light); + + bool hasRenderBatches(const U32 type) const; + LLCullResult::drawinfo_iterator beginRenderMap(U32 type); + LLCullResult::drawinfo_iterator endRenderMap(U32 type); + LLCullResult::sg_iterator beginAlphaGroups(); + LLCullResult::sg_iterator endAlphaGroups(); LLCullResult::sg_iterator beginRiggedAlphaGroups(); LLCullResult::sg_iterator endRiggedAlphaGroups(); - - void addTrianglesDrawn(S32 index_count); + + void addTrianglesDrawn(S32 index_count); void recordTrianglesDrawn(); - bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); } - bool hasRenderDebugMask(const U64 mask) const { return bool(mRenderDebugMask & mask); } - void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } - void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } - void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffffffffffff; } - void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; } - - bool hasRenderType(const U32 type) const; - bool hasAnyRenderType(const U32 type, ...) const; - - static bool isWaterClip(); - - void setRenderTypeMask(U32 type, ...); - // This is equivalent to 'setRenderTypeMask' - //void orRenderTypeMask(U32 type, ...); - void andRenderTypeMask(U32 type, ...); - void clearRenderTypeMask(U32 type, ...); - void setAllRenderTypes(); - void clearAllRenderTypes(); - - void pushRenderTypeMask(); - void popRenderTypeMask(); - - void pushRenderDebugFeatureMask(); - void popRenderDebugFeatureMask(); - - static void toggleRenderType(U32 type); - - // For UI control of render features - static bool hasRenderTypeControl(U32 data); - static void toggleRenderDebug(U64 data); - static void toggleRenderDebugFeature(U32 data); - static void toggleRenderTypeControl(U32 data); - static bool toggleRenderTypeControlNegated(S32 data); - static bool toggleRenderDebugControl(U64 data); - static bool toggleRenderDebugFeatureControl(U32 data); - static void setRenderDebugFeatureControl(U32 bit, bool value); - - static void setRenderParticleBeacons(bool val); - static void toggleRenderParticleBeacons(); - static bool getRenderParticleBeacons(); - - static void setRenderSoundBeacons(bool val); - static void toggleRenderSoundBeacons(); - static bool getRenderSoundBeacons(); - - static void setRenderMOAPBeacons(bool val); - static void toggleRenderMOAPBeacons(); - static bool getRenderMOAPBeacons(); - - static void setRenderPhysicalBeacons(bool val); - static void toggleRenderPhysicalBeacons(); - static bool getRenderPhysicalBeacons(); - - static void setRenderScriptedBeacons(bool val); - static void toggleRenderScriptedBeacons(); - static bool getRenderScriptedBeacons(); - - static void setRenderScriptedTouchBeacons(bool val); - static void toggleRenderScriptedTouchBeacons(); - static bool getRenderScriptedTouchBeacons(); - - static void setRenderBeacons(bool val); - static void toggleRenderBeacons(); - static bool getRenderBeacons(); - - static void setRenderHighlights(bool val); - static void toggleRenderHighlights(); - static bool getRenderHighlights(); - static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay - - static void updateRenderTransparentWater(); - static void refreshCachedSettings(); - - void addDebugBlip(const LLVector3& position, const LLColor4& color); - - void hidePermanentObjects( std::vector& restoreList ); - void restorePermanentObjects( const std::vector& restoreList ); - void skipRenderingOfTerrain( bool flag ); - void hideObject( const LLUUID& id ); - void restoreHiddenObject( const LLUUID& id ); + bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); } + bool hasRenderDebugMask(const U64 mask) const { return bool(mRenderDebugMask & mask); } + void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } + void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } + void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffffffffffff; } + void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; } + + bool hasRenderType(const U32 type) const; + bool hasAnyRenderType(const U32 type, ...) const; + + static bool isWaterClip(); + + void setRenderTypeMask(U32 type, ...); + // This is equivalent to 'setRenderTypeMask' + //void orRenderTypeMask(U32 type, ...); + void andRenderTypeMask(U32 type, ...); + void clearRenderTypeMask(U32 type, ...); + void setAllRenderTypes(); + void clearAllRenderTypes(); + + void pushRenderTypeMask(); + void popRenderTypeMask(); + + void pushRenderDebugFeatureMask(); + void popRenderDebugFeatureMask(); + + static void toggleRenderType(U32 type); + + // For UI control of render features + static bool hasRenderTypeControl(U32 data); + static void toggleRenderDebug(U64 data); + static void toggleRenderDebugFeature(U32 data); + static void toggleRenderTypeControl(U32 data); + static bool toggleRenderTypeControlNegated(S32 data); + static bool toggleRenderDebugControl(U64 data); + static bool toggleRenderDebugFeatureControl(U32 data); + static void setRenderDebugFeatureControl(U32 bit, bool value); + + static void setRenderParticleBeacons(bool val); + static void toggleRenderParticleBeacons(); + static bool getRenderParticleBeacons(); + + static void setRenderSoundBeacons(bool val); + static void toggleRenderSoundBeacons(); + static bool getRenderSoundBeacons(); + + static void setRenderMOAPBeacons(bool val); + static void toggleRenderMOAPBeacons(); + static bool getRenderMOAPBeacons(); + + static void setRenderPhysicalBeacons(bool val); + static void toggleRenderPhysicalBeacons(); + static bool getRenderPhysicalBeacons(); + + static void setRenderScriptedBeacons(bool val); + static void toggleRenderScriptedBeacons(); + static bool getRenderScriptedBeacons(); + + static void setRenderScriptedTouchBeacons(bool val); + static void toggleRenderScriptedTouchBeacons(); + static bool getRenderScriptedTouchBeacons(); + + static void setRenderBeacons(bool val); + static void toggleRenderBeacons(); + static bool getRenderBeacons(); + + static void setRenderHighlights(bool val); + static void toggleRenderHighlights(); + static bool getRenderHighlights(); + static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay + + static void updateRenderTransparentWater(); + static void refreshCachedSettings(); + + void addDebugBlip(const LLVector3& position, const LLColor4& color); + + void hidePermanentObjects( std::vector& restoreList ); + void restorePermanentObjects( const std::vector& restoreList ); + void skipRenderingOfTerrain( bool flag ); + void hideObject( const LLUUID& id ); + void restoreHiddenObject( const LLUUID& id ); void handleShadowDetailChanged(); LLReflectionMapManager mReflectionMapManager; LLHeroProbeManager mHeroProbeManager; private: - void unloadShaders(); - void addToQuickLookup( LLDrawPool* new_poolp ); - void removeFromQuickLookup( LLDrawPool* poolp ); - bool updateDrawableGeom(LLDrawable* drawable); - void assertInitializedDoError(); - bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; - void connectRefreshCachedSettingsSafe(const std::string name); - void hideDrawable( LLDrawable *pDrawable ); - void unhideDrawable( LLDrawable *pDrawable ); + void unloadShaders(); + void addToQuickLookup( LLDrawPool* new_poolp ); + void removeFromQuickLookup( LLDrawPool* poolp ); + bool updateDrawableGeom(LLDrawable* drawable); + void assertInitializedDoError(); + bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; + void connectRefreshCachedSettingsSafe(const std::string name); + void hideDrawable( LLDrawable *pDrawable ); + void unhideDrawable( LLDrawable *pDrawable ); void skipRenderingShadows(); public: - enum {GPU_CLASS_MAX = 3 }; - - enum LLRenderTypeMask - { - // Following are pool types (some are also object types) - RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, - RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, - RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, - RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, - RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, - RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK, - RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK, - RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, - RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, - RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS, - RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, - RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh - RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, - RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER, - RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, + enum {GPU_CLASS_MAX = 3 }; + + enum LLRenderTypeMask + { + // Following are pool types (some are also object types) + RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, + RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, + RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, + RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, + RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, + RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK, + RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK, + RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, + RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, + RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS, + RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, + RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh + RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, + RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER, + RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR, RENDER_TYPE_GLTF_PBR_ALPHA_MASK = LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK, - RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, + RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, RENDER_TYPE_ALPHA_PRE_WATER = LLDrawPool::POOL_ALPHA_PRE_WATER, RENDER_TYPE_ALPHA_POST_WATER = LLDrawPool::POOL_ALPHA_POST_WATER, - RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, - RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, + RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, + RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED, - RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, - RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, + RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED, - RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, + RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED, - RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, + RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, RENDER_TYPE_PASS_INVISI_SHINY_RIGGED = LLRenderPass::PASS_INVISI_SHINY_RIGGED, - RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, + RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED = LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, - RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, + RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, RENDER_TYPE_PASS_SHINY_RIGGED = LLRenderPass::PASS_SHINY_RIGGED, - RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, + RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, RENDER_TYPE_PASS_BUMP_RIGGED = LLRenderPass::PASS_BUMP_RIGGED, - RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP, + RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP, RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED, - RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, + RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED, RENDER_TYPE_PASS_GLTF_GLOW = LLRenderPass::PASS_GLTF_GLOW, RENDER_TYPE_PASS_GLTF_GLOW_RIGGED = LLRenderPass::PASS_GLTF_GLOW_RIGGED, - RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, - RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, + RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, + RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED, - RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, + RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, - RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL, + RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL, RENDER_TYPE_PASS_MATERIAL_RIGGED = LLRenderPass::PASS_MATERIAL_RIGGED, - RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA, + RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA, RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_RIGGED, - RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK, + RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK, RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, - RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, - RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP, + RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP, RENDER_TYPE_PASS_SPECMAP_RIGGED = LLRenderPass::PASS_SPECMAP_RIGGED, - RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND, + RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND, RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED = LLRenderPass::PASS_SPECMAP_BLEND_RIGGED, - RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK, + RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK, RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED = LLRenderPass::PASS_SPECMAP_MASK_RIGGED, - RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE, + RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE, RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, - RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP, + RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP, RENDER_TYPE_PASS_NORMMAP_RIGGED = LLRenderPass::PASS_NORMMAP_RIGGED, - RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND, + RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND, RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED = LLRenderPass::PASS_NORMMAP_BLEND_RIGGED, - RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK, + RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK, RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED = LLRenderPass::PASS_NORMMAP_MASK_RIGGED, - RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE, + RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE, RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, - RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC, + RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC, RENDER_TYPE_PASS_NORMSPEC_RIGGED = LLRenderPass::PASS_NORMSPEC_RIGGED, - RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND, + RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND, RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED = LLRenderPass::PASS_NORMSPEC_BLEND_RIGGED, - RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK, + RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK, RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, - RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE, + RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE, RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, RENDER_TYPE_PASS_GLTF_PBR = LLRenderPass::PASS_GLTF_PBR, RENDER_TYPE_PASS_GLTF_PBR_RIGGED = LLRenderPass::PASS_GLTF_PBR_RIGGED, RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK, RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED, - // Following are object types (only used in drawable mRenderType) - RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, - RENDER_TYPE_VOLUME, - RENDER_TYPE_PARTICLES, - RENDER_TYPE_CLOUDS, - RENDER_TYPE_HUD_PARTICLES, - NUM_RENDER_TYPES, - END_RENDER_TYPES = NUM_RENDER_TYPES - }; - - enum LLRenderDebugFeatureMask - { - RENDER_DEBUG_FEATURE_UI = 0x0001, - RENDER_DEBUG_FEATURE_SELECTED = 0x0002, - RENDER_DEBUG_FEATURE_HIGHLIGHTED = 0x0004, - RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES = 0x0008, -// RENDER_DEBUG_FEATURE_HW_LIGHTING = 0x0010, - RENDER_DEBUG_FEATURE_FLEXIBLE = 0x0010, - RENDER_DEBUG_FEATURE_FOG = 0x0020, - RENDER_DEBUG_FEATURE_FR_INFO = 0x0080, - RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100, - }; - - enum LLRenderDebugMask: U64 - { - RENDER_DEBUG_COMPOSITION = 0x00000001, - RENDER_DEBUG_VERIFY = 0x00000002, - RENDER_DEBUG_BBOXES = 0x00000004, - RENDER_DEBUG_OCTREE = 0x00000008, - RENDER_DEBUG_WIND_VECTORS = 0x00000010, - RENDER_DEBUG_OCCLUSION = 0x00000020, - RENDER_DEBUG_POINTS = 0x00000040, - RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080, - RENDER_DEBUG_TEXTURE_AREA = 0x00000100, - RENDER_DEBUG_FACE_AREA = 0x00000200, - RENDER_DEBUG_PARTICLES = 0x00000400, - RENDER_DEBUG_GLOW = 0x00000800, // not used - RENDER_DEBUG_TEXTURE_ANIM = 0x00001000, - RENDER_DEBUG_LIGHTS = 0x00002000, - RENDER_DEBUG_BATCH_SIZE = 0x00004000, - RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used - RENDER_DEBUG_RAYCAST = 0x00010000, - RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000, - RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000, - RENDER_DEBUG_SCULPTED = 0x00080000, - RENDER_DEBUG_AVATAR_VOLUME = 0x00100000, - RENDER_DEBUG_AVATAR_JOINTS = 0x00200000, - RENDER_DEBUG_AGENT_TARGET = 0x00800000, - RENDER_DEBUG_UPDATE_TYPE = 0x01000000, - RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000, - RENDER_DEBUG_NORMALS = 0x04000000, - RENDER_DEBUG_LOD_INFO = 0x08000000, + // Following are object types (only used in drawable mRenderType) + RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, + RENDER_TYPE_VOLUME, + RENDER_TYPE_PARTICLES, + RENDER_TYPE_CLOUDS, + RENDER_TYPE_HUD_PARTICLES, + NUM_RENDER_TYPES, + END_RENDER_TYPES = NUM_RENDER_TYPES + }; + + enum LLRenderDebugFeatureMask + { + RENDER_DEBUG_FEATURE_UI = 0x0001, + RENDER_DEBUG_FEATURE_SELECTED = 0x0002, + RENDER_DEBUG_FEATURE_HIGHLIGHTED = 0x0004, + RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES = 0x0008, +// RENDER_DEBUG_FEATURE_HW_LIGHTING = 0x0010, + RENDER_DEBUG_FEATURE_FLEXIBLE = 0x0010, + RENDER_DEBUG_FEATURE_FOG = 0x0020, + RENDER_DEBUG_FEATURE_FR_INFO = 0x0080, + RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100, + }; + + enum LLRenderDebugMask: U64 + { + RENDER_DEBUG_COMPOSITION = 0x00000001, + RENDER_DEBUG_VERIFY = 0x00000002, + RENDER_DEBUG_BBOXES = 0x00000004, + RENDER_DEBUG_OCTREE = 0x00000008, + RENDER_DEBUG_WIND_VECTORS = 0x00000010, + RENDER_DEBUG_OCCLUSION = 0x00000020, + RENDER_DEBUG_POINTS = 0x00000040, + RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080, + RENDER_DEBUG_TEXTURE_AREA = 0x00000100, + RENDER_DEBUG_FACE_AREA = 0x00000200, + RENDER_DEBUG_PARTICLES = 0x00000400, + RENDER_DEBUG_GLOW = 0x00000800, // not used + RENDER_DEBUG_TEXTURE_ANIM = 0x00001000, + RENDER_DEBUG_LIGHTS = 0x00002000, + RENDER_DEBUG_BATCH_SIZE = 0x00004000, + RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used + RENDER_DEBUG_RAYCAST = 0x00010000, + RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000, + RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000, + RENDER_DEBUG_SCULPTED = 0x00080000, + RENDER_DEBUG_AVATAR_VOLUME = 0x00100000, + RENDER_DEBUG_AVATAR_JOINTS = 0x00200000, + RENDER_DEBUG_AGENT_TARGET = 0x00800000, + RENDER_DEBUG_UPDATE_TYPE = 0x01000000, + RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000, + RENDER_DEBUG_NORMALS = 0x04000000, + RENDER_DEBUG_LOD_INFO = 0x08000000, RENDER_DEBUG_NODES = 0x20000000, - RENDER_DEBUG_TEXEL_DENSITY = 0x40000000, - RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000, - RENDER_DEBUG_IMPOSTORS = 0x100000000, + RENDER_DEBUG_TEXEL_DENSITY = 0x40000000, + RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000, + RENDER_DEBUG_IMPOSTORS = 0x100000000, RENDER_DEBUG_REFLECTION_PROBES = 0x200000000, RENDER_DEBUG_PROBE_UPDATES = 0x400000000, - }; + }; public: - - LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj); - - void updateCamera(bool reset = false); - - LLVector3 mFlyCamPosition; - LLQuaternion mFlyCamRotation; - - bool mBackfaceCull; - S32 mMatrixOpCount; - S32 mTextureMatrixOps; - S32 mNumVisibleNodes; - - S32 mDebugTextureUploadCost; - S32 mDebugSculptUploadCost; - S32 mDebugMeshUploadCost; - - S32 mNumVisibleFaces; - - S32 mPoissonOffset; - - static S32 sCompiles; - - static bool sShowHUDAttachments; - static bool sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. - static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write - static bool sAutoMaskAlphaDeferred; - static bool sAutoMaskAlphaNonDeferred; - static bool sRenderTransparentWater; - static bool sBakeSunlight; - static bool sNoAlpha; - static bool sUseFarClip; - static bool sShadowRender; - static bool sDynamicLOD; - static bool sPickAvatar; - static bool sReflectionRender; - static bool sDistortionRender; - static bool sImpostorRender; - static bool sImpostorRenderAlphaDepthPass; - static bool sUnderWaterRender; - static bool sRenderGlow; - static bool sTextureBindTest; - static bool sRenderAttachedLights; - static bool sRenderAttachedParticles; - static bool sRenderDeferred; - static bool sReflectionProbesEnabled; - static S32 sVisibleLightCount; - static bool sRenderingHUDs; + + LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj); + + void updateCamera(bool reset = false); + + LLVector3 mFlyCamPosition; + LLQuaternion mFlyCamRotation; + + bool mBackfaceCull; + S32 mMatrixOpCount; + S32 mTextureMatrixOps; + S32 mNumVisibleNodes; + + S32 mDebugTextureUploadCost; + S32 mDebugSculptUploadCost; + S32 mDebugMeshUploadCost; + + S32 mNumVisibleFaces; + + S32 mPoissonOffset; + + static S32 sCompiles; + + static bool sShowHUDAttachments; + static bool sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. + static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write + static bool sAutoMaskAlphaDeferred; + static bool sAutoMaskAlphaNonDeferred; + static bool sRenderTransparentWater; + static bool sBakeSunlight; + static bool sNoAlpha; + static bool sUseFarClip; + static bool sShadowRender; + static bool sDynamicLOD; + static bool sPickAvatar; + static bool sReflectionRender; + static bool sDistortionRender; + static bool sImpostorRender; + static bool sImpostorRenderAlphaDepthPass; + static bool sUnderWaterRender; + static bool sRenderGlow; + static bool sTextureBindTest; + static bool sRenderAttachedLights; + static bool sRenderAttachedParticles; + static bool sRenderDeferred; + static bool sReflectionProbesEnabled; + static S32 sVisibleLightCount; + static bool sRenderingHUDs; static F32 sDistortionWaterClipPlaneMargin; - static LLTrace::EventStatHandle sStatBatchSize; + static LLTrace::EventStatHandle sStatBatchSize; class RenderTargetPack { public: - U32 width = 0; - U32 height = 0; + U32 width = 0; + U32 height = 0; //screen texture - LLRenderTarget screen; - LLRenderTarget uiScreen; - LLRenderTarget deferredScreen; - LLRenderTarget fxaaBuffer; - LLRenderTarget edgeMap; - LLRenderTarget deferredLight; + LLRenderTarget screen; + LLRenderTarget uiScreen; + LLRenderTarget deferredScreen; + LLRenderTarget fxaaBuffer; + LLRenderTarget edgeMap; + LLRenderTarget deferredLight; //sun shadow map - LLRenderTarget shadow[4]; + LLRenderTarget shadow[4]; }; // main full resoltuion render target @@ -703,7 +703,7 @@ public: // used by reflection probes and dynamic texture bakes RenderTargetPack mAuxillaryRT; - // Auxillary render target pack scaled to the hero probe's per-face size. + // Auxillary render target pack scaled to the hero probe's per-face size. RenderTargetPack mHeroProbeRT; // currently used render target pack @@ -729,336 +729,336 @@ public: LLCullResult mReflectedObjects; LLCullResult mRefractedObjects; - //utility buffers for rendering post effects - LLPointer mDeferredVB; + //utility buffers for rendering post effects + LLPointer mDeferredVB; // a single triangle that covers the whole screen LLPointer mScreenTriangleVB; - //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1] - LLPointer mCubeVB; + //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1] + LLPointer mCubeVB; //list of currently bound reflection maps std::vector mReflectionMaps; - std::vector mShadowFrustPoints[4]; - LLVector4 mShadowError; - LLVector4 mShadowFOV; - LLVector3 mShadowFrustOrigin[4]; - LLCamera mShadowCamera[8]; - LLVector3 mShadowExtents[4][2]; + std::vector mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; + LLCamera mShadowCamera[8]; + LLVector3 mShadowExtents[4][2]; // TODO : separate Sun Shadow and Spot Shadow matrices - glh::matrix4f mSunShadowMatrix[6]; - glh::matrix4f mShadowModelview[6]; - glh::matrix4f mShadowProjection[6]; + glh::matrix4f mSunShadowMatrix[6]; + glh::matrix4f mShadowModelview[6]; + glh::matrix4f mShadowProjection[6]; glh::matrix4f mReflectionModelView; - LLPointer mShadowSpotLight[2]; - F32 mSpotLightFade[2]; - LLPointer mTargetShadowSpotLight[2]; + LLPointer mShadowSpotLight[2]; + F32 mSpotLightFade[2]; + LLPointer mTargetShadowSpotLight[2]; - LLVector4 mSunClipPlanes; - LLVector4 mSunOrthoClipPlanes; - LLVector2 mScreenScale; + LLVector4 mSunClipPlanes; + LLVector4 mSunOrthoClipPlanes; + LLVector2 mScreenScale; - //water distortion texture (refraction) - LLRenderTarget mWaterDis; + //water distortion texture (refraction) + LLRenderTarget mWaterDis; static const U32 MAX_BAKE_WIDTH; - //texture for making the glow - LLRenderTarget mGlow[3]; + //texture for making the glow + LLRenderTarget mGlow[3]; - //noise map - U32 mNoiseMap; - U32 mTrueNoiseMap; - U32 mLightFunc; + //noise map + U32 mNoiseMap; + U32 mTrueNoiseMap; + U32 mLightFunc; - LLColor4 mSunDiffuse; - LLColor4 mMoonDiffuse; - LLVector4 mSunDir; - LLVector4 mMoonDir; + LLColor4 mSunDiffuse; + LLColor4 mMoonDiffuse; + LLVector4 mSunDir; + LLVector4 mMoonDir; bool mNeedsShadowTargetClear; - LLVector4 mTransformedSunDir; - LLVector4 mTransformedMoonDir; + LLVector4 mTransformedSunDir; + LLVector4 mTransformedMoonDir; - bool mInitialized; - bool mShadersLoaded; + bool mInitialized; + bool mShadersLoaded; - U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback + U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback protected: - bool mRenderTypeEnabled[NUM_RENDER_TYPES]; - std::stack mRenderTypeEnableStack; - - U32 mRenderDebugFeatureMask; - U64 mRenderDebugMask; - U64 mOldRenderDebugMask; - std::stack mRenderDebugFeatureStack; - - ///////////////////////////////////////////// - // - // - LLDrawable::drawable_vector_t mMovedList; - LLDrawable::drawable_vector_t mMovedBridge; - LLDrawable::drawable_vector_t mShiftList; - - ///////////////////////////////////////////// - // - // - struct Light - { - Light(LLDrawable* ptr, F32 d, F32 f = 0.0f) - : drawable(ptr), - dist(d), - fade(f) - {} - LLPointer drawable; - F32 dist; - F32 fade; - struct compare - { - bool operator()(const Light& a, const Light& b) const - { - if ( a.dist < b.dist ) - return true; - else if ( a.dist > b.dist ) - return false; - else - return a.drawable < b.drawable; - } - }; - }; - typedef std::set< Light, Light::compare > light_set_t; - - LLDrawable::ordered_drawable_set_t mLights; - light_set_t mNearbyLights; // lights near camera - LLColor4 mHWLightColors[8]; - - ///////////////////////////////////////////// - // - // Different queues of drawables being processed. - // - LLDrawable::drawable_list_t mBuildQ1; // priority - LLSpatialGroup::sg_vector_t mGroupQ1; //priority - - LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref - - LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called - U32 mMeshDirtyQueryObject; - - LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius - - bool mGroupQ1Locked; - - bool mResetVertexBuffers; //if true, clear vertex buffers on next update - - LLViewerObject::vobj_list_t mCreateQ; - - LLDrawable::drawable_set_t mRetexturedList; - - class HighlightItem - { - public: - const LLPointer mItem; - mutable F32 mFade; - - HighlightItem(LLDrawable* item) - : mItem(item), mFade(0) - { - } - - bool operator<(const HighlightItem& rhs) const - { - return mItem < rhs.mItem; - } - - bool operator==(const HighlightItem& rhs) const - { - return mItem == rhs.mItem; - } - - void incrFade(F32 val) const - { - mFade = llclamp(mFade+val, 0.f, 1.f); - } - }; - - ////////////////////////////////////////////////// - // - // Draw pools are responsible for storing all rendered data, - // and performing the actual rendering of objects. - // - struct compare_pools - { - bool operator()(const LLDrawPool* a, const LLDrawPool* b) const - { - if (!a) - return true; - else if (!b) - return false; - else - { - S32 atype = a->getType(); - S32 btype = b->getType(); - if (atype < btype) - return true; - else if (atype > btype) - return false; - else - return a->getId() < b->getId(); - } - } - }; - typedef std::set pool_set_t; - pool_set_t mPools; - LLDrawPool* mLastRebuildPool; - - // For quick-lookups into mPools (mapped by texture pointer) - std::map mTerrainPools; - std::map mTreePools; - LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr; + bool mRenderTypeEnabled[NUM_RENDER_TYPES]; + std::stack mRenderTypeEnableStack; + + U32 mRenderDebugFeatureMask; + U64 mRenderDebugMask; + U64 mOldRenderDebugMask; + std::stack mRenderDebugFeatureStack; + + ///////////////////////////////////////////// + // + // + LLDrawable::drawable_vector_t mMovedList; + LLDrawable::drawable_vector_t mMovedBridge; + LLDrawable::drawable_vector_t mShiftList; + + ///////////////////////////////////////////// + // + // + struct Light + { + Light(LLDrawable* ptr, F32 d, F32 f = 0.0f) + : drawable(ptr), + dist(d), + fade(f) + {} + LLPointer drawable; + F32 dist; + F32 fade; + struct compare + { + bool operator()(const Light& a, const Light& b) const + { + if ( a.dist < b.dist ) + return true; + else if ( a.dist > b.dist ) + return false; + else + return a.drawable < b.drawable; + } + }; + }; + typedef std::set< Light, Light::compare > light_set_t; + + LLDrawable::ordered_drawable_set_t mLights; + light_set_t mNearbyLights; // lights near camera + LLColor4 mHWLightColors[8]; + + ///////////////////////////////////////////// + // + // Different queues of drawables being processed. + // + LLDrawable::drawable_list_t mBuildQ1; // priority + LLSpatialGroup::sg_vector_t mGroupQ1; //priority + + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called + U32 mMeshDirtyQueryObject; + + LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius + + bool mGroupQ1Locked; + + bool mResetVertexBuffers; //if true, clear vertex buffers on next update + + LLViewerObject::vobj_list_t mCreateQ; + + LLDrawable::drawable_set_t mRetexturedList; + + class HighlightItem + { + public: + const LLPointer mItem; + mutable F32 mFade; + + HighlightItem(LLDrawable* item) + : mItem(item), mFade(0) + { + } + + bool operator<(const HighlightItem& rhs) const + { + return mItem < rhs.mItem; + } + + bool operator==(const HighlightItem& rhs) const + { + return mItem == rhs.mItem; + } + + void incrFade(F32 val) const + { + mFade = llclamp(mFade+val, 0.f, 1.f); + } + }; + + ////////////////////////////////////////////////// + // + // Draw pools are responsible for storing all rendered data, + // and performing the actual rendering of objects. + // + struct compare_pools + { + bool operator()(const LLDrawPool* a, const LLDrawPool* b) const + { + if (!a) + return true; + else if (!b) + return false; + else + { + S32 atype = a->getType(); + S32 btype = b->getType(); + if (atype < btype) + return true; + else if (atype > btype) + return false; + else + return a->getId() < b->getId(); + } + } + }; + typedef std::set pool_set_t; + pool_set_t mPools; + LLDrawPool* mLastRebuildPool; + + // For quick-lookups into mPools (mapped by texture pointer) + std::map mTerrainPools; + std::map mTreePools; + LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr; LLDrawPoolAlpha* mAlphaPoolPostWater = nullptr; - LLDrawPool* mSkyPool = nullptr; - LLDrawPool* mTerrainPool = nullptr; - LLDrawPool* mWaterPool = nullptr; - LLRenderPass* mSimplePool = nullptr; - LLRenderPass* mGrassPool = nullptr; - LLRenderPass* mAlphaMaskPool = nullptr; - LLRenderPass* mFullbrightAlphaMaskPool = nullptr; - LLRenderPass* mFullbrightPool = nullptr; - LLDrawPool* mGlowPool = nullptr; - LLDrawPool* mBumpPool = nullptr; - LLDrawPool* mMaterialsPool = nullptr; - LLDrawPool* mWLSkyPool = nullptr; - LLDrawPool* mPBROpaquePool = nullptr; + LLDrawPool* mSkyPool = nullptr; + LLDrawPool* mTerrainPool = nullptr; + LLDrawPool* mWaterPool = nullptr; + LLRenderPass* mSimplePool = nullptr; + LLRenderPass* mGrassPool = nullptr; + LLRenderPass* mAlphaMaskPool = nullptr; + LLRenderPass* mFullbrightAlphaMaskPool = nullptr; + LLRenderPass* mFullbrightPool = nullptr; + LLDrawPool* mGlowPool = nullptr; + LLDrawPool* mBumpPool = nullptr; + LLDrawPool* mMaterialsPool = nullptr; + LLDrawPool* mWLSkyPool = nullptr; + LLDrawPool* mPBROpaquePool = nullptr; LLDrawPool* mPBRAlphaMaskPool = nullptr; - // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar - + // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar + public: - std::vector mHighlightFaces; // highlight faces on physical objects + std::vector mHighlightFaces; // highlight faces on physical objects protected: - std::vector mSelectedFaces; - - class DebugBlip - { - public: - LLColor4 mColor; - LLVector3 mPosition; - F32 mAge; - - DebugBlip(const LLVector3& position, const LLColor4& color) - : mColor(color), mPosition(position), mAge(0.f) - { } - }; - - std::list mDebugBlips; - - LLPointer mFaceSelectImagep; - - U32 mLightMask; - U32 mLightMovingMask; - - static bool sRenderPhysicalBeacons; - static bool sRenderMOAPBeacons; - static bool sRenderScriptedTouchBeacons; - static bool sRenderScriptedBeacons; - static bool sRenderParticleBeacons; - static bool sRenderSoundBeacons; + std::vector mSelectedFaces; + + class DebugBlip + { + public: + LLColor4 mColor; + LLVector3 mPosition; + F32 mAge; + + DebugBlip(const LLVector3& position, const LLColor4& color) + : mColor(color), mPosition(position), mAge(0.f) + { } + }; + + std::list mDebugBlips; + + LLPointer mFaceSelectImagep; + + U32 mLightMask; + U32 mLightMovingMask; + + static bool sRenderPhysicalBeacons; + static bool sRenderMOAPBeacons; + static bool sRenderScriptedTouchBeacons; + static bool sRenderScriptedBeacons; + static bool sRenderParticleBeacons; + static bool sRenderSoundBeacons; public: - static bool sRenderBeacons; - static bool sRenderHighlight; - - // Determines which set of UVs to use in highlight display - // - static LLRender::eTexIndex sRenderHighlightTextureChannel; - - //debug use - static U32 sCurRenderPoolType ; - - //cached settings - static bool WindLightUseAtmosShaders; - static bool RenderDeferred; - static F32 RenderDeferredSunWash; - static U32 RenderFSAASamples; - static U32 RenderResolutionDivisor; - static bool RenderUIBuffer; - static S32 RenderShadowDetail; + static bool sRenderBeacons; + static bool sRenderHighlight; + + // Determines which set of UVs to use in highlight display + // + static LLRender::eTexIndex sRenderHighlightTextureChannel; + + //debug use + static U32 sCurRenderPoolType ; + + //cached settings + static bool WindLightUseAtmosShaders; + static bool RenderDeferred; + static F32 RenderDeferredSunWash; + static U32 RenderFSAASamples; + static U32 RenderResolutionDivisor; + static bool RenderUIBuffer; + static S32 RenderShadowDetail; static S32 RenderShadowSplits; - static bool RenderDeferredSSAO; - static F32 RenderShadowResolutionScale; - static bool RenderDelayCreation; - static bool RenderAnimateRes; - static bool FreezeTime; - static S32 DebugBeaconLineWidth; - static F32 RenderHighlightBrightness; - static LLColor4 RenderHighlightColor; - static F32 RenderHighlightThickness; - static bool RenderSpotLightsInNondeferred; - static LLColor4 PreviewAmbientColor; - static LLColor4 PreviewDiffuse0; - static LLColor4 PreviewSpecular0; - static LLColor4 PreviewDiffuse1; - static LLColor4 PreviewSpecular1; - static LLColor4 PreviewDiffuse2; - static LLColor4 PreviewSpecular2; - static LLVector3 PreviewDirection0; - static LLVector3 PreviewDirection1; - static LLVector3 PreviewDirection2; - static F32 RenderGlowMinLuminance; - static F32 RenderGlowMaxExtractAlpha; - static F32 RenderGlowWarmthAmount; - static LLVector3 RenderGlowLumWeights; - static LLVector3 RenderGlowWarmthWeights; - static S32 RenderGlowResolutionPow; - static S32 RenderGlowIterations; - static F32 RenderGlowWidth; - static F32 RenderGlowStrength; - static bool RenderGlowNoise; - static bool RenderDepthOfField; - static bool RenderDepthOfFieldInEditMode; - static F32 CameraFocusTransitionTime; - static F32 CameraFNumber; - static F32 CameraFocalLength; - static F32 CameraFieldOfView; - static F32 RenderShadowNoise; - static F32 RenderShadowBlurSize; - static F32 RenderSSAOScale; - static U32 RenderSSAOMaxScale; - static F32 RenderSSAOFactor; - static LLVector3 RenderSSAOEffect; - static F32 RenderShadowOffsetError; - static F32 RenderShadowBiasError; - static F32 RenderShadowOffset; - static F32 RenderShadowBias; - static F32 RenderSpotShadowOffset; - static F32 RenderSpotShadowBias; + static bool RenderDeferredSSAO; + static F32 RenderShadowResolutionScale; + static bool RenderDelayCreation; + static bool RenderAnimateRes; + static bool FreezeTime; + static S32 DebugBeaconLineWidth; + static F32 RenderHighlightBrightness; + static LLColor4 RenderHighlightColor; + static F32 RenderHighlightThickness; + static bool RenderSpotLightsInNondeferred; + static LLColor4 PreviewAmbientColor; + static LLColor4 PreviewDiffuse0; + static LLColor4 PreviewSpecular0; + static LLColor4 PreviewDiffuse1; + static LLColor4 PreviewSpecular1; + static LLColor4 PreviewDiffuse2; + static LLColor4 PreviewSpecular2; + static LLVector3 PreviewDirection0; + static LLVector3 PreviewDirection1; + static LLVector3 PreviewDirection2; + static F32 RenderGlowMinLuminance; + static F32 RenderGlowMaxExtractAlpha; + static F32 RenderGlowWarmthAmount; + static LLVector3 RenderGlowLumWeights; + static LLVector3 RenderGlowWarmthWeights; + static S32 RenderGlowResolutionPow; + static S32 RenderGlowIterations; + static F32 RenderGlowWidth; + static F32 RenderGlowStrength; + static bool RenderGlowNoise; + static bool RenderDepthOfField; + static bool RenderDepthOfFieldInEditMode; + static F32 CameraFocusTransitionTime; + static F32 CameraFNumber; + static F32 CameraFocalLength; + static F32 CameraFieldOfView; + static F32 RenderShadowNoise; + static F32 RenderShadowBlurSize; + static F32 RenderSSAOScale; + static U32 RenderSSAOMaxScale; + static F32 RenderSSAOFactor; + static LLVector3 RenderSSAOEffect; + static F32 RenderShadowOffsetError; + static F32 RenderShadowBiasError; + static F32 RenderShadowOffset; + static F32 RenderShadowBias; + static F32 RenderSpotShadowOffset; + static F32 RenderSpotShadowBias; static LLDrawable* RenderSpotLight; - static F32 RenderEdgeDepthCutoff; - static F32 RenderEdgeNormCutoff; - static LLVector3 RenderShadowGaussian; - static F32 RenderShadowBlurDistFactor; - static bool RenderDeferredAtmospheric; - static F32 RenderHighlightFadeTime; - static F32 RenderFarClip; - static LLVector3 RenderShadowSplitExponent; - static F32 RenderShadowErrorCutoff; - static F32 RenderShadowFOVCutoff; - static bool CameraOffset; - static F32 CameraMaxCoF; - static F32 CameraDoFResScale; - static F32 RenderAutoHideSurfaceAreaLimit; - static bool RenderScreenSpaceReflections; + static F32 RenderEdgeDepthCutoff; + static F32 RenderEdgeNormCutoff; + static LLVector3 RenderShadowGaussian; + static F32 RenderShadowBlurDistFactor; + static bool RenderDeferredAtmospheric; + static F32 RenderHighlightFadeTime; + static F32 RenderFarClip; + static LLVector3 RenderShadowSplitExponent; + static F32 RenderShadowErrorCutoff; + static F32 RenderShadowFOVCutoff; + static bool CameraOffset; + static F32 CameraMaxCoF; + static F32 CameraDoFResScale; + static F32 RenderAutoHideSurfaceAreaLimit; + static bool RenderScreenSpaceReflections; static S32 RenderScreenSpaceReflectionIterations; - static F32 RenderScreenSpaceReflectionRayStep; - static F32 RenderScreenSpaceReflectionDistanceBias; - static F32 RenderScreenSpaceReflectionDepthRejectBias; - static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier; - static S32 RenderScreenSpaceReflectionGlossySamples; - static S32 RenderBufferVisualization; - static bool RenderMirrors; - static S32 RenderHeroProbeUpdateRate; + static F32 RenderScreenSpaceReflectionRayStep; + static F32 RenderScreenSpaceReflectionDistanceBias; + static F32 RenderScreenSpaceReflectionDepthRejectBias; + static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier; + static S32 RenderScreenSpaceReflectionGlossySamples; + static S32 RenderBufferVisualization; + static bool RenderMirrors; + static S32 RenderHeroProbeUpdateRate; static S32 RenderHeroProbeConservativeUpdateMultiplier; }; -- cgit v1.2.3 From 7ed053d9a257087b76937d750b9f2b0c96f6df38 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 May 2024 19:02:13 +0300 Subject: viewer#1520 Material upload floater displays wrong upload fee --- indra/llrender/llgltexture.cpp | 4 +++ indra/newview/llagentbenefits.cpp | 2 +- indra/newview/llmaterialeditor.cpp | 60 +++++++++++++++++++++++++------------- indra/newview/llmaterialeditor.h | 1 + 4 files changed, 45 insertions(+), 22 deletions(-) (limited to 'indra') diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index be4fc85985..104976fcc6 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -49,6 +49,10 @@ LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) mUseMipMaps = usemipmaps ; // Create an empty image of the specified size and width mGLTexturep = new LLImageGL(raw, usemipmaps) ; + mFullWidth = mGLTexturep->getCurrentWidth(); + mFullHeight = mGLTexturep->getCurrentHeight(); + mComponents = mGLTexturep->getComponents(); + setTexelsPerImage(); } LLGLTexture::~LLGLTexture() diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp index 4ac4d2136f..e9f00f6556 100644 --- a/indra/newview/llagentbenefits.cpp +++ b/indra/newview/llagentbenefits.cpp @@ -175,7 +175,7 @@ S32 LLAgentBenefits::getTextureUploadCost(const LLViewerTexture* tex) const return getTextureUploadCost(); } } - return getTextureUploadCost(); + return 0; } S32 LLAgentBenefits::getTextureUploadCost(const LLImageBase* tex) const diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 208b289ca9..36a0834845 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -489,10 +489,7 @@ BOOL LLMaterialEditor::postBuild() } else { - getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mBaseColorFetched))); - getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mMetallicRoughnessFetched))); - getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mEmissiveFetched))); - getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mNormalFetched))); + refreshUploadCost(); } boost::function changes_callback = [this](LLUICtrl * ctrl, void* userData) @@ -811,6 +808,37 @@ void LLMaterialEditor::resetUnsavedChanges() } } +void LLMaterialEditor::refreshUploadCost() +{ + mExpectedUploadCost = 0; + if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId() && mBaseColorFetched) + { + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(mBaseColorFetched); + mExpectedUploadCost += upload_cost; + getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + } + if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicRoughnessFetched) + { + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(mMetallicRoughnessFetched); + mExpectedUploadCost += upload_cost; + getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + } + if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId() && mEmissiveFetched) + { + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(mEmissiveFetched); + mExpectedUploadCost += upload_cost; + getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + } + if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId() && mNormalFetched) + { + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(mNormalFetched); + mExpectedUploadCost += upload_cost; + getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + } + + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); +} + void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) { mUnsavedChanges |= dirty_flag; @@ -841,25 +869,15 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) setCanSave(false); } - mExpectedUploadCost = 0; - if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId() && mBaseColorFetched) + if ((dirty_flag & MATERIAL_BASE_COLOR_TEX_DIRTY) + || (dirty_flag & MATERIAL_NORMAL_TEX_DIRTY) + || (dirty_flag & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + || (dirty_flag & MATERIAL_EMISIVE_TEX_DIRTY) + || (dirty_flag == 0) + || (dirty_flag == U32_MAX)) { - mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mBaseColorFetched); + refreshUploadCost(); } - if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicRoughnessFetched) - { - mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mMetallicRoughnessFetched); - } - if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId() && mEmissiveFetched) - { - mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mEmissiveFetched); - } - if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId() && mNormalFetched) - { - mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mNormalFetched); - } - - getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); } void LLMaterialEditor::setCanSaveAs(bool value) diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index dda65476af..11809d26be 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -288,6 +288,7 @@ private: // utility function for building a description of the imported material // based on what we know about it. const std::string buildMaterialDescription(); + void refreshUploadCost(); void resetUnsavedChanges(); void markChangesUnsaved(U32 dirty_flag); -- cgit v1.2.3 From 10fb2fc411d17f323c521c4182fe9b081201e62a Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 19:18:20 +0200 Subject: Adjust Copy3rdPartyLibs.cmake for Visual Studio 2022 17.10.0 and greater --- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 7938d4f54b..27b20ee3b1 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -107,7 +107,7 @@ if(WINDOWS) set(MSVC_VER 140) elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019 set(MSVC_VER 140) - elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1940) # Visual Studio 2022 + elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1950) # Visual Studio 2022 set(MSVC_VER 140) else (MSVC80) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") -- cgit v1.2.3 From 5f3a6bdd7f122688aff5c0e63f03928fa15bb0c9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 28 May 2024 13:25:02 -0700 Subject: secondlife/viewer#1531: Attempt to fix PBR terrain fragment shader. --- .../shaders/class1/deferred/pbrterrainF.glsl | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index de4745c1c4..0de2d348c3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -180,7 +180,7 @@ void main() rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w); #endif - PBRMix mix = init_pbr_mix(); + PBRMix pbr_mix = init_pbr_mix(); PBRMix mix2; switch (tm.type & MIX_X) { @@ -207,7 +207,7 @@ void main() , emissiveColors[0] #endif ); - mix = mix_pbr(mix, mix2, tm.weight.x); + pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.x); break; default: break; @@ -237,7 +237,7 @@ void main() , emissiveColors[1] #endif ); - mix = mix_pbr(mix, mix2, tm.weight.y); + pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.y); break; default: break; @@ -267,7 +267,7 @@ void main() , emissiveColors[2] #endif ); - mix = mix_pbr(mix, mix2, tm.weight.z); + pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.z); break; default: break; @@ -297,14 +297,14 @@ void main() , emissiveColors[3] #endif ); - mix = mix_pbr(mix, mix2, tm.weight.w); + pbr_mix = mix_pbr(pbr_mix, mix2, tm.weight.w); break; default: break; } float minimum_alpha = terrain_mix(tm, minimum_alphas); - if (mix.col.a < minimum_alpha) + if (pbr_mix.col.a < minimum_alpha) { discard; } @@ -312,7 +312,7 @@ void main() #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) // from mikktspace.com - vec3 vNt = mix.vNt; + vec3 vNt = pbr_mix.vNt; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -327,21 +327,21 @@ void main() #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) -#define emissive mix.emissive +#define mix_emissive pbr_mix.emissive #else -#define emissive vec3(0) +#define mix_emissive vec3(0) #endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) -#define orm mix.orm +#define mix_orm pbr_mix.orm #elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) -#define orm vec3(1.0, mix.rm) +#define mix_orm vec3(1.0, pbr_mix.rm) #else // Matte plastic potato terrain -#define orm vec3(1.0, 1.0, 0.0) +#define mix_orm vec3(1.0, 1.0, 0.0) #endif - frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse - frag_data[1] = max(vec4(orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[0] = max(vec4(pbr_mix.col.xyz, 0.0), vec4(0)); // Diffuse + frag_data[1] = max(vec4(mix_orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, flags - frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive + frag_data[3] = max(vec4(mix_emissive,0), vec4(0)); // PBR sRGB Emissive } -- cgit v1.2.3 From 33bb511ab4acd5867fbe5f11393a01e438b72293 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 28 May 2024 14:19:18 -0700 Subject: Improvements to mirror probe update rates (#1570) #1494 Fix for mirror updates getting "stuck" on some faces. --- indra/newview/llheroprobemanager.cpp | 36 +++++++++++++----------------------- indra/newview/llheroprobemanager.h | 3 +++ indra/newview/llviewerdisplay.cpp | 5 +++-- 3 files changed, 19 insertions(+), 25 deletions(-) (limited to 'indra') diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 208dfe45bd..1c08424868 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -112,7 +112,6 @@ void LLHeroProbeManager::update() LLVector4a probe_pos; LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; - F32 near_clip = 0.1f; bool probe_present = false; LLQuaternion cameraOrientation = LLViewerCamera::instance().getQuaternion(); LLVector3 cameraDirection = LLVector3::z_axis * cameraOrientation; @@ -192,20 +191,15 @@ void LLHeroProbeManager::update() // Iterate through each face of the cube for (int i = 0; i < 6; i++) { - float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])) * 0.6 + 0.4; + float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])); - float updateRate; - if (cube_facing < 0.1f) - { - updateRate = 0; - } - else - { - updateRate = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); - } + cube_facing = 1 - cube_facing; - mFaceUpdateList[i] = updateRate; + mFaceUpdateList[i] = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); } + + + mProbes[0]->mOrigin = probe_pos; } else { @@ -214,25 +208,23 @@ void LLHeroProbeManager::update() mHeroProbeStrength = 1; } - else - { - probe_pos.load3(camera_pos.mV); - } - +} +void LLHeroProbeManager::renderProbes() +{ static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); - if (mNearestHero != nullptr) + F32 near_clip = 0.01f; + if (mNearestHero != nullptr && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0) && + !gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent()) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); - // Probe 0 is always our mirror probe. - mProbes[0]->mOrigin = probe_pos; bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass(); gPipeline.mReflectionMapManager.mRadiancePass = true; - mRenderingMirror = true; + mRenderingMirror = true; doOcclusion(); @@ -585,8 +577,6 @@ void LLHeroProbeManager::cleanup() mDefaultProbe = nullptr; mUpdatingProbe = nullptr; - /* - */ } void LLHeroProbeManager::doOcclusion() diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 5df146f2f1..e45b0049b2 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -68,6 +68,8 @@ public: // maintain reflection probes void update(); + void renderProbes(); + // debug display, called from llspatialpartition if reflection // probe debug display is active void renderDebug(); @@ -152,5 +154,6 @@ private: std::vector> mHeroVOList; LLPointer mNearestHero; + }; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d65b44fd3a..bb3378f4fe 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -658,10 +658,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { // Render mirrors and associated hero probes before we render the rest of the scene. // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. - if (gPipeline.RenderMirrors && !gSnapshot && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0)) + if (gPipeline.RenderMirrors && !gSnapshot) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes"); gPipeline.mHeroProbeManager.update(); + gPipeline.mHeroProbeManager.renderProbes(); } LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); @@ -1072,7 +1073,7 @@ void display_cube_face() LLSpatialGroup::sNoDelete = TRUE; S32 occlusion = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 1; // occlusion data is from main camera point of view, don't read or write it during cube snapshots + LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data static LLCullResult result; -- cgit v1.2.3 From 12cd8589b4de85bc7f69c2cddc0d367cadb3b3f3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 28 May 2024 18:29:51 +0300 Subject: viewer#1568 Revert "SL-17597 AV height in Shape dialog IS WRONG" This reverts commit f5a7c22cea16b51db12360436ce64c2433a5aa5f to fix viewer#1568. --- indra/llappearance/llavatarappearance.cpp | 87 ++++++++++++++++++++----------- indra/llappearance/llavatarappearance.h | 2 - 2 files changed, 56 insertions(+), 33 deletions(-) (limited to 'indra') diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index d73be024cf..83e43b11b7 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -494,45 +494,70 @@ void LLAvatarAppearance::computeBodySize() mCurrBodySizeState["mAnkleLeft scale"] = mAnkleLeftp->getScale(); mCurrBodySizeState["mFootLeft pos"] = mFootLeftp->getPosition(); - F32 old_height = mBodySize.mV[VZ]; + LLVector3 pelvis_scale = mPelvisp->getScale(); + + // some of the joints have not been cached + LLVector3 skull = mSkullp->getPosition(); + //LLVector3 skull_scale = mSkullp->getScale(); + + LLVector3 neck = mNeckp->getPosition(); + LLVector3 neck_scale = mNeckp->getScale(); + + LLVector3 chest = mChestp->getPosition(); + LLVector3 chest_scale = mChestp->getScale(); + + // the rest of the joints have been cached + LLVector3 head = mHeadp->getPosition(); + LLVector3 head_scale = mHeadp->getScale(); + + LLVector3 torso = mTorsop->getPosition(); + LLVector3 torso_scale = mTorsop->getScale(); + + LLVector3 hip = mHipLeftp->getPosition(); + LLVector3 hip_scale = mHipLeftp->getScale(); + + LLVector3 knee = mKneeLeftp->getPosition(); + LLVector3 knee_scale = mKneeLeftp->getScale(); + + LLVector3 ankle = mAnkleLeftp->getPosition(); + LLVector3 ankle_scale = mAnkleLeftp->getScale(); + + LLVector3 foot = mFootLeftp->getPosition(); + F32 old_offset = mAvatarOffset.mV[VZ]; - // TODO: Measure the real depth and width - mPelvisToFoot = computePelvisToFoot(); - F32 new_height = computeBodyHeight(); - mBodySize.set(DEFAULT_AGENT_DEPTH, DEFAULT_AGENT_WIDTH, new_height); - F32 new_offset = getVisualParamWeight(AVATAR_HOVER); - mAvatarOffset.set(0, 0, new_offset); + mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER); + + mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] - + knee.mV[VZ] * hip_scale.mV[VZ] - + ankle.mV[VZ] * knee_scale.mV[VZ] - + foot.mV[VZ] * ankle_scale.mV[VZ]; - if (mBodySize.mV[VZ] != old_height || new_offset != old_offset) + LLVector3 new_body_size; + new_body_size.mV[VZ] = mPelvisToFoot + + // the sqrt(2) correction below is an approximate + // correction to get to the top of the head + F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + + head.mV[VZ] * neck_scale.mV[VZ] + + neck.mV[VZ] * chest_scale.mV[VZ] + + chest.mV[VZ] * torso_scale.mV[VZ] + + torso.mV[VZ] * pelvis_scale.mV[VZ]; + + // TODO -- measure the real depth and width + new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; + new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; + + mAvatarOffset.mV[VX] = 0.0f; + mAvatarOffset.mV[VY] = 0.0f; + + if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ]) { + mBodySize = new_body_size; + compareJointStateMaps(mLastBodySizeState, mCurrBodySizeState); } } -F32 LLAvatarAppearance::computeBodyHeight() -{ - F32 result = mPelvisToFoot + - // all these relative positions usually are positive - mPelvisp->getScale().mV[VZ] * mTorsop->getPosition().mV[VZ] + - mTorsop->getScale().mV[VZ] * mChestp->getPosition().mV[VZ] + - mChestp->getScale().mV[VZ] * mNeckp->getPosition().mV[VZ] + - mNeckp->getScale().mV[VZ] * mHeadp->getPosition().mV[VZ] + - mHeadp->getScale().mV[VZ] * mSkullp->getPosition().mV[VZ] * 2; - return result; -} - -F32 LLAvatarAppearance::computePelvisToFoot() -{ - F32 result = - // all these relative positions usually are negative - mPelvisp->getScale().mV[VZ] * mHipLeftp->getPosition().mV[VZ] + - mHipLeftp->getScale().mV[VZ] * mKneeLeftp->getPosition().mV[VZ] + - mKneeLeftp->getScale().mV[VZ] * mAnkleLeftp->getPosition().mV[VZ] + - mAnkleLeftp->getScale().mV[VZ] * mFootLeftp->getPosition().mV[VZ] / 2; - return -result; -} - //----------------------------------------------------------------------------- // parseSkeletonFile() //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 9dd1ddffad..dc2d48fb74 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -147,8 +147,6 @@ public: void compareJointStateMaps(joint_state_map_t& last_state, joint_state_map_t& curr_state); void computeBodySize(); - F32 computeBodyHeight(); - F32 computePelvisToFoot(); public: typedef std::vector avatar_joint_list_t; -- cgit v1.2.3 From 01c82642ac01342114f41f2428890042c3040c9b Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 29 May 2024 19:31:58 -0700 Subject: #1581 Only render mirrors when reflection probes are enabled. (#1592) --- indra/newview/llheroprobemanager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 1c08424868..ff47ca87ec 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -75,7 +75,7 @@ LLHeroProbeManager::~LLHeroProbeManager() // helper class to seed octree with probes void LLHeroProbeManager::update() { - if (!LLPipeline::RenderMirrors || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) + if (!LLPipeline::RenderMirrors || !LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) { return; } @@ -212,6 +212,12 @@ void LLHeroProbeManager::update() void LLHeroProbeManager::renderProbes() { + if (!LLPipeline::RenderMirrors || !LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || + LLStartUp::getStartupState() < STATE_PRECACHE) + { + return; + } + static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); -- cgit v1.2.3 From 83f9885d73a7ffb3c87ae29bcad6b01d0530eeb4 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 4 Jun 2024 10:26:34 -0500 Subject: #1614 Fix for moire pattern in specular highlights. Incidental cleanup. --- .../app_settings/shaders/class1/deferred/deferredUtil.glsl | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 385920f622..01543732d0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -142,18 +142,9 @@ vec2 getScreenCoordinate(vec2 screenpos) } vec4 getNorm(vec2 screenpos) -{ - return texture(normalMap, screenpos.xy); -} - -// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w -// See: C++: addDeferredAttachments(), GLSL: softenLightF -vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity) { vec4 norm = texture(normalMap, screenpos.xy); - n = norm.xyz; - envIntensity = texture(emissiveRect, screenpos.xy).r; - + norm.xyz = normalize(norm.xyz); return norm; } -- cgit v1.2.3 From c413458fd48ff209f7bd536924a2df2c4dfe8716 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 4 Jun 2024 15:22:38 -0700 Subject: #1628 Disable spherical mirror probes for the time being. (#1631) --- indra/newview/llheroprobemanager.cpp | 2 +- indra/newview/llpanelvolume.cpp | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ff47ca87ec..efe72128d4 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -123,7 +123,7 @@ void LLHeroProbeManager::update() float camera_center_distance = 99999.f; for (auto vo : mHeroVOList) { - if (vo && !vo->isDead() && vo->mDrawable.notNull()) + if (vo && !vo->isDead() && vo->mDrawable.notNull() && vo->isReflectionProbe() && vo->getReflectionProbeIsBox()) { float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec(); float center_distance = cameraDirection * (vo->getPositionAgent() - camera_pos); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 7f111d7619..701882ac57 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -387,6 +387,7 @@ void LLPanelVolume::getState( ) // Reflection Probe BOOL is_probe = volobjp && volobjp->isReflectionProbe(); + bool is_mirror = volobjp && volobjp->getReflectionProbeIsMirror(); getChild("Reflection Probe")->setValue(is_probe); getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh()); @@ -400,9 +401,9 @@ void LLPanelVolume::getState( ) getChildView("Probe Dynamic")->setEnabled(probe_enabled); getChildView("Probe Update Type")->setEnabled(probe_enabled); - getChildView("Probe Volume Type")->setEnabled(probe_enabled); - getChildView("Probe Ambiance")->setEnabled(probe_enabled); - getChildView("Probe Near Clip")->setEnabled(probe_enabled); + getChildView("Probe Volume Type")->setEnabled(probe_enabled && !is_mirror); + getChildView("Probe Ambiance")->setEnabled(probe_enabled && !is_mirror); + getChildView("Probe Near Clip")->setEnabled(probe_enabled && !is_mirror); getChildView("Probe Update Label")->setEnabled(probe_enabled); if (!probe_enabled) @@ -441,8 +442,8 @@ void LLPanelVolume::getState( ) update_type = "Dynamic Mirror"; } - getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); - getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror"); + getChildView("Probe Ambiance")->setEnabled(!is_mirror); + getChildView("Probe Near Clip")->setEnabled(!is_mirror); getChild("Probe Volume Type", true)->setValue(volume_type); getChild("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance()); @@ -1434,6 +1435,8 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) bool is_mirror = update_type.find("Mirror") != std::string::npos; + self->getChildView("Probe Volume Type")->setEnabled(!is_mirror); + volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos); volobjp->setReflectionProbeIsMirror(is_mirror); @@ -1442,7 +1445,7 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) std::string shape_type = self->getChild("Probe Volume Type")->getValue().asString(); - bool is_box = shape_type == "Box"; + bool is_box = shape_type == "Box" || is_mirror; if (volobjp->setReflectionProbeIsBox(is_box)) { -- cgit v1.2.3 From 9f97ff7286aceef5be4e7589ca4af911edf30f12 Mon Sep 17 00:00:00 2001 From: Brad Linden <46733234+brad-linden@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:09:03 -0700 Subject: #989 Fix for blurry terrain on Mac (#1633) Co-authored-by: Dave Parks --- indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index 8e1e4b54d5..b4ab7cd169 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -47,7 +47,9 @@ vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1) tcoord.x = dot(vpos, tp0); tcoord.y = dot(vpos, tp1); - + tcoord.z = 0; + tcoord.w = 1; + tcoord = mat * tcoord; return tcoord.xy; -- cgit v1.2.3